Subversion Repositories Applications.gtt

Compare Revisions

No changes between revisions

Ignore whitespace Rev 148 → Rev 149

/tags/v1.0-Homere/actions/GttCtrlActionPreferences.class.php
New file
0,0 → 1,76
<?php
class GttCtrlActionPreferences extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('Preferences', 'preferences');
}
 
public function executer()
{
$aso_preferences = array();
$this->getRegistre()->setTitre('Modifier mes préférences');
$Projet = new Projet();
$tab_projets = $Projet->consulter(Projet::GP_TOUS);
 
if (false == $tab_projets) {
$aso_preferences['messages'][] = "Veuillez commencer par ajouter des catégories de projet et des projets !";
$aso_preferences['preferences'] = false;
} else {
$aso_preferences['nbre_projets'] = count($tab_projets);
// Parcourt du tableau de projets
foreach ($tab_projets as $Projet) {
// Vérification de la présence du projet dans les préférences de l'utilisateur
$UtilisateurAProjet = new UtilisateurAProjet();
$cmd = UtilisateurAProjet::GUAP_ID;
$param = array($GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur(), $Projet->getIdProjet());
$coche = false;
if ($present = $UtilisateurAProjet->consulter($cmd, $param)) {
$coche = true;
}
// Récupération de la catégorie du projet
$ProjetCategorie = new ProjetCategorie();
$Categorie = current($ProjetCategorie->consulter(ProjetCategorie::GPC_ID, $Projet->getCeCategorie()));
// Récupération de toutes les infos
$aso_preferences['preferences'][$Categorie->getLibelle()][] = array(
'id' => $Projet->getIdProjet(),
'valeur' => $Projet->getIdProjet(),
'no' => $Projet->getNom(),
'de' => $Projet->getDescription(),
'dade' => $Projet->getDateDebut(),
'dafi' => $Projet->getDateFin(),
'dupr' => $Projet->getDureePrevue(),
'dufi' => $Projet->getDureeFinance(),
'av' => $Projet->getAvancement(),
'coche' => $coche);
}
ksort($aso_preferences['preferences']);
}
//echo '<pre>'.print_r($aso_preferences, true).'</pre>';
$this->getRegistre()->ajouterDonnee('preferences', $aso_preferences);
}
 
public function executerValider()
{
// Mise à jour des Préférences
$UtilisateurAProjet = new UtilisateurAProjet();
$UtilisateurAProjet->setIdUtilisateur($GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur());
$UtilisateurAProjet->supprimer();
//echo '<pre>'.print_r($_POST, true).'</pre>';
if (isset($_POST['pr'])) {
foreach ($_POST['pr'] as $pr_id) {
$UtilisateurAProjet = new UtilisateurAProjet();
$UtilisateurAProjet->setIdUtilisateur($GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur());
$UtilisateurAProjet->setIdProjet($pr_id);
$UtilisateurAProjet->ajouter();
}
}
// Action suivante
$this->setSuivant('__defaut__');
}
}
?>
/tags/v1.0-Homere/actions/GttCtrlActionAdminUtilisateur.class.php
New file
0,0 → 1,313
<?php
class GttCtrlActionAdminUtilisateur extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('AdminUtilisateur', 'admin_utilisateur');
$Registre->setTitre('Administrer les utilisateurs');
}
 
public function executer()
{
$aso_admin_utilisateur = array();
// Ajout du mode
$aso_admin_utilisateur['mode'] = 'A';// Ajout
 
// Récupération des utilisateur
$Utilisateur = new Utilisateur();
 
// Vérification si l'utilisateur est admin
$aso_admin_utilisateur['bool_mark_admin'] = false;
if ($Utilisateur->getMarkAdmin() == 1) {
$aso_admin_utilisateur['bool_mark_admin'] = true;
}
// Vérification si l'utilisateur doit apparaître dans le récapitulatif
$aso_admin_utilisateur['bool_mark_recapitulatif'] = false;
if ($Utilisateur->getMarkRecapitulatif() == 1) {
$aso_admin_utilisateur['bool_mark_recapitulatif'] = true;
}
 
// Utilisateur vide par défaut
$aso_admin_utilisateur['Utilisateur'] = clone $Utilisateur;
 
// Recherche des utilisateurs existant
$tab_u = $Utilisateur->consulter(Utilisateur::GU_TOUS);
foreach ($tab_u as $u) {
// Nous récupérons tous les statuts sauf le null (=0)
if ($u->getIdUtilisateur() != 0) {
$aso_utilisateur['id'] = $u->getIdUtilisateur();
$aso_utilisateur['libelle'] = $u->getNom().' '.$u->getPrenom();
$aso_admin_utilisateur['utilisateurs'][] = $aso_utilisateur;
}
}
 
// Recherche des statuts des utilisateurs
$UtilisateurStatut = new UtilisateurStatut();
$tab_us = $UtilisateurStatut->consulter(UtilisateurStatut::GUS_TOUS);
foreach ($tab_us as $us) {
// Nous récupérons tous les statuts sauf le null (=0)
if ($us->getIdUtilisateurStatut() != 0) {
$aso_us['id'] = $us->getIdUtilisateurStatut();
$aso_us['libelle'] = $us->getLibelle();
$aso_admin_utilisateur['utilisateur_statuts'][] = $aso_us;
}
}
 
// Modification des titres, légendes et bouton
$aso_admin_utilisateur['form_legend'] = 'Ajouter un utilisateur';
$aso_admin_utilisateur['form_bouton_value'] = 'Ajouter';
$aso_admin_utilisateur['form_bouton_id'] = 'btn_utilisateur_ajouter';
$aso_admin_utilisateur['form_url'] = 'index.php?action=admin-utilisateur_valider-ajouter';
 
//echo '<pre>'.print_r($aso_admin_utilisateur, true).'</pre>';
$this->getRegistre()->ajouterDonnee('admin_utilisateur', $aso_admin_utilisateur);
}
 
public function executerValiderAjouter()
{
if (isset($_POST['btn_utilisateur_annuler'])) {
// Action suivante
$this->setSuivant('__defaut__');
} else if (isset($_POST['btn_utilisateur_ajouter'])) {
// Vérification de l'utilisateur à ajouter
$bool_ajouter = true;
$Utilisateur = new Utilisateur();
$UtMail = $Utilisateur->consulter(Utilisateur::GU_MAIL, array($_POST['ut_email']));
if ((is_array($UtMail) && count($UtMail) > 1) || $UtMail instanceof Utilisateur) {
$aso_admin_utilisateur['messages'][] = 'Un utilisateur avec le même courriel existe déjà !';
$bool_ajouter = false;
}
$this->verifierChampsCommuns(&$aso_admin_utilisateur, &$bool_ajouter, 'A');
if ($bool_ajouter) {
// Action suivante
$this->setSuivant('ajouter');
} else {
// Action suivante
$this->setSuivant('__defaut__');
$this->getRegistre()->ajouterDonnee('admin_utilisateur', $aso_admin_utilisateur);
}
}
}
 
public function executerValiderModifier()
{
if (isset($_POST['btn_utilisateur_annuler'])) {
// Action suivante
$this->setSuivant('__defaut__');
} else if (isset($_POST['btn_utilisateur_modifier'])) {
// Vérification de l'utilisateur à modifier
$bool_modifier = true;
$Utilisateur = new Utilisateur();
$UtMail = $Utilisateur->consulter(Utilisateur::GU_MAIL, array($_POST['ut_email']));
if ((is_array($UtMail) && count($UtMail) > 1) || ($UtMail instanceof Utilisateur && $UtMail->getIdUtilisateur() != $_POST['ut_id_utilisateur'])) {
$aso_admin_utilisateur['messages'][] = 'Un utilisateur avec le même courriel existe déjà !';
$bool_modifier = false;
}
$this->verifierChampsCommuns(&$aso_admin_utilisateur, &$bool_modifier, 'M');
if ($bool_modifier) {
// Action suivante
$this->setSuivant('modifier');
} else {
// Action suivante
$_POST['btn_utilisateur_modifier'] = 'btn_utilisateur_modifier';
$_POST['utsu_id'] = $_POST['ut_id_utilisateur'];
$this->setSuivant('editer');
$this->getRegistre()->ajouterDonnee('admin_utilisateur', $aso_admin_utilisateur);
}
}
}
 
public function verifierChampsCommuns(&$aso_admin_utilisateur, &$bool, $mode)
{
// En modifcation, si le mot de passe est vide, on ne fait pas de changement dans la base de données
if ($mode == 'A' || ($mode == 'M' && (!empty($_POST['ut_mot_de_passe']) || !empty($_POST['ut_mot_de_passe_confirmation'])))) {
if (mb_strlen($_POST['ut_mot_de_passe']) < 6) {
$aso_admin_utilisateur['messages'][] = 'Le mot de passe doit contenir au moins 6 caractères !';
$bool = false;
}
if ($_POST['ut_mot_de_passe'] != $_POST['ut_mot_de_passe_confirmation']) {
$aso_admin_utilisateur['messages'][] = 'Les mots de passe saisies ne sont pas identique !';
$bool = false;
}
}
if ($_POST['ut_temps_de_travail_jour'] > 24) {
$aso_admin_utilisateur['messages'][] = 'Il est impossible que le temps de travail soit supérieur à 24h !';
$bool = false;
}
$aso_champs_tdt = array('ut_tdt_lundi' => 'Lundi', 'ut_tdt_mardi' => 'Mardi', 'ut_tdt_mercredi' => 'Mercredi',
'ut_tdt_jeudi' => 'Jeudi', 'ut_tdt_vendredi' => 'Vendredi', 'ut_tdt_samedi' => 'Samedi',
'ut_tdt_dimanche' => 'Dimanche');
foreach ($aso_champs_tdt as $champ_id => $libelle) {
if ($_POST[$champ_id] > $_POST['ut_temps_de_travail_jour']) {
$aso_admin_utilisateur['messages'][] = "Le champ temps de travail du $libelle ne doit pas être supérieur à la durée maximum du temps de travail journalier !";
$bool = false;
}
}
$aso_champs_obligatoires = array('ut_nom' => 'Nom', 'ut_prenom' => 'Prénom', 'ut_email' => 'Courriel');
// En modifcation, si le mot de passe est vide cela peut être normal
if ($mode == 'A' || ($mode == 'M' && (!empty($_POST['ut_mot_de_passe']) || !empty($_POST['ut_mot_de_passe_confirmation'])))) {
$aso_champs_obligatoires['ut_mot_de_passe'] = 'Mot de passe';
}
foreach ($aso_champs_obligatoires as $champ_id => $libelle) {
if (empty($_POST[$champ_id])) {
$aso_admin_utilisateur['messages'][] = "Le champ $libelle ne doit pas être vide !";
$bool = false;
}
}
}
 
public function executerEditer()
{
// Ajout du statut d'utilisateur
if (isset($_POST['btn_utilisateur_modifier'])) {
// Ajout du mode
$aso_admin_utilisateur['mode'] = 'M';// Modifier
 
// Récupération des données de l'utilisateur à modifier
$Utilisateur = new Utilisateur();
$Utilisateur->consulter(Utilisateur::GU_ID, $_POST['utsu_id'], true);
$aso_admin_utilisateur['Utilisateur'] = $Utilisateur;
// Vérification si l'utilisateur est admin
$aso_admin_utilisateur['bool_mark_admin'] = false;
if ($Utilisateur->getMarkAdmin() == 1) {
$aso_admin_utilisateur['bool_mark_admin'] = true;
}
// Vérification si l'utilisateur doit apparaître dans le récapitulatif
$aso_admin_utilisateur['bool_mark_recapitulatif'] = false;
if ($Utilisateur->getMarkRecapitulatif() == 1) {
$aso_admin_utilisateur['bool_mark_recapitulatif'] = true;
}
// Modification des titres, légendes et bouton
$aso_admin_utilisateur['form_legend'] = 'Modifier un utilisateur';
$aso_admin_utilisateur['form_bouton_value'] = 'Modifier';
$aso_admin_utilisateur['form_bouton_id'] = 'btn_utilisateur_modifier';
$aso_admin_utilisateur['form_url'] = 'index.php?action=admin-utilisateur_valider-modifier';
 
$this->getRegistre()->ajouterDonnee('admin_utilisateur', $aso_admin_utilisateur);
} else if (isset($_POST['btn_utilisateur_supprimer'])) {
// Action suivante
$this->setSuivant('supprimer');
}
}
 
public function executerAjouter()
{
$Utilisateur = new Utilisateur();
$Utilisateur->setNom($_POST['ut_nom']);
$Utilisateur->setPrenom($_POST['ut_prenom']);
$Utilisateur->setAdresse($_POST['ut_adresse']);
$Utilisateur->setVille($_POST['ut_ville']);
$Utilisateur->setCodePostal($_POST['ut_code_postal']);
$Utilisateur->setTelephone($_POST['ut_telephone']);
$Utilisateur->setEmail($_POST['ut_email']);
$Utilisateur->setPassword($_POST['ut_mot_de_passe']);
//$Utilisateur->setCeStatut($_POST['ut_statut']);
$Utilisateur->setCongesPayes($_POST['ut_conges_payes']);
$Utilisateur->setTempsDeTravailJour($_POST['ut_temps_de_travail_jour']);
$Utilisateur->setTempsDeTravailMois($_POST['ut_temps_de_travail_mois']);
$Utilisateur->setTdtLundi($_POST['ut_tdt_lundi']);
$Utilisateur->setTdtMardi($_POST['ut_tdt_mardi']);
$Utilisateur->setTdtMercredi($_POST['ut_tdt_mercredi']);
$Utilisateur->setTdtJeudi($_POST['ut_tdt_jeudi']);
$Utilisateur->setTdtVendredi($_POST['ut_tdt_vendredi']);
$Utilisateur->setTdtSamedi($_POST['ut_tdt_samedi']);
$Utilisateur->setTdtDimanche($_POST['ut_tdt_dimanche']);
$Utilisateur->setQuotaHeuresSupp($_POST['ut_quota_heures_supp']);
if (!isset($_POST['ut_mark_admin'])) {
$_POST['ut_mark_admin'] = 0;
}
$Utilisateur->setMarkAdmin($_POST['ut_mark_admin']);
if (!isset($_POST['ut_mark_recapitulatif'])) {
$_POST['ut_mark_recapitulatif'] = 0;
}
$Utilisateur->setMarkRecapitulatif($_POST['ut_mark_recapitulatif']);
$Utilisateur->ajouter();
// Action suivante
$this->setSuivant('__defaut__');
}
 
 
public function executerModifier()
{
$Utilisateur = new Utilisateur();
$Utilisateur->setIdUtilisateur($_POST['ut_id_utilisateur']);
$Utilisateur->setNom($_POST['ut_nom']);
$Utilisateur->setPrenom($_POST['ut_prenom']);
$Utilisateur->setAdresse($_POST['ut_adresse']);
$Utilisateur->setVille($_POST['ut_ville']);
$Utilisateur->setCodePostal($_POST['ut_code_postal']);
$Utilisateur->setTelephone($_POST['ut_telephone']);
$Utilisateur->setEmail($_POST['ut_email']);
if (isset($_POST['ut_mot_de_passe']) && !empty($_POST['ut_mot_de_passe'])) {
$Utilisateur->setPassword($_POST['ut_mot_de_passe']);
}
//$Utilisateur->setCeStatut($_POST['ut_statut']);
$Utilisateur->setCongesPayes($_POST['ut_conges_payes']);
$Utilisateur->setTempsDeTravailJour($_POST['ut_temps_de_travail_jour']);
$Utilisateur->setTempsDeTravailMois($_POST['ut_temps_de_travail_mois']);
$Utilisateur->setTdtLundi($_POST['ut_tdt_lundi']);
$Utilisateur->setTdtMardi($_POST['ut_tdt_mardi']);
$Utilisateur->setTdtMercredi($_POST['ut_tdt_mercredi']);
$Utilisateur->setTdtJeudi($_POST['ut_tdt_jeudi']);
$Utilisateur->setTdtVendredi($_POST['ut_tdt_vendredi']);
$Utilisateur->setTdtSamedi($_POST['ut_tdt_samedi']);
$Utilisateur->setTdtDimanche($_POST['ut_tdt_dimanche']);
$Utilisateur->setQuotaHeuresSupp($_POST['ut_quota_heures_supp']);
if (!isset($_POST['ut_mark_admin'])) {
$_POST['ut_mark_admin'] = 0;
}
$Utilisateur->setMarkAdmin($_POST['ut_mark_admin']);
if (!isset($_POST['ut_mark_recapitulatif'])) {
$_POST['ut_mark_recapitulatif'] = 0;
}
$Utilisateur->setMarkRecapitulatif($_POST['ut_mark_recapitulatif']);
$Utilisateur->modifier();
// Action suivante
$this->setSuivant('__defaut__');
}
 
public function executerSupprimer()
{
$aso_admin_utilisateur = array();
// Vérif du nombre d'utilisateur admin (doit être supérieur à 1)
$Utilisateur = new Utilisateur();
$nbre_admin = $Utilisateur->consulter(Utilisateur::GU_ADMIN);
if (count($nbre_admin) > 1) {
trigger_error('Utilisateur admin > 1 -> OK', E_USER_NOTICE);
// Vérif des travail_projets
$TravailProjet = new TravailProjet();
$bool_existe = $TravailProjet->consulter(TravailProjet::GTP_UTILISATEUR, array($_POST['utsu_id']));
if ($bool_existe == false) {
trigger_error('TravailProjet -> OK', E_USER_NOTICE);
// Vérif des absences
$Absence = new Absence();
$bool_existe = $Absence->consulter(Absence::GA_ID_UTILISATEUR, array($_POST['utsu_id']));
if ($bool_existe == false) {
trigger_error('Absence -> OK', E_USER_NOTICE);
// Suppression de l'utilisateur
$Utilisateur = new Utilisateur();
$Utilisateur->setIdUtilisateur($_POST['utsu_id']);
if ($Utilisateur->supprimer()) {
$aso_admin_utilisateur['messages'][] = "L'utilisateur a été supprimé.";
}
}
}
} else {
$aso_admin_utilisateur['messages'][] = "Il n'est pas possible de supprimer le seul administrateur!";
}
// Message d'erreur si l'utilisateur contient des données
if (isset($bool_existe) && $bool_existe != false) {
$aso_admin_utilisateur['messages'][] = "Il n'est pas possible de supprimer un utilisateur contenant des données!";
}
 
// Enregistrement du message
$this->getRegistre()->ajouterDonnee('admin_utilisateur', $aso_admin_utilisateur);
// Action suivante
$this->setSuivant('__defaut__');
}
}
?>
/tags/v1.0-Homere/actions/GttCtrlActionStatTableauCharge.class.php
New file
0,0 → 1,254
<?php
class GttCtrlActionStatTableauCharge extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('StatTableauCharge', 'stat_tableau_charge');
}
 
public function executer()
{
//+-------------------------------------------------------------------------------------------------+
// GESTION D'INFO GLOBALES
//+-------------------------------------------------------------------------------------------------+
$aso_stat = array('total_w' => 0,'total_a' => 0, 'total' => 0);
$this->getRegistre()->setTitre('Plan de charge');
 
//+-------------------------------------------------------------------------------------------------+
// GESTION DES PARAMÊTRE de l'URL
//+-------------------------------------------------------------------------------------------------+
// Initialisation des variables
if (!isset($_GET['annee'])) {
$_GET['annee'] = date('Y');
}
if (!isset($_GET['mois'])) {
$_GET['mois'] = date('m');
}
if (!isset($_GET['uid'])) {// ID de l'utilisateur à afficher
$_GET['uid'] = null;
}
//+-------------------------------------------------------------------------------------------------+
// GESTION DES UTILISATEURS
//+-------------------------------------------------------------------------------------------------+
$DaoUtilsateur = new Utilisateur();
$utilisateurs = $DaoUtilsateur->consulter(Utilisateur::GU_TOUS);
$UtilisateurCourant = null;
foreach ($utilisateurs as $Utilisateur) {
// Récupération des infos sur l'utilisateur
$aso_stat['utilisateurs'][$Utilisateur->getIdUtilisateur()]['courant'] = false;
$aso_stat['utilisateurs'][$Utilisateur->getIdUtilisateur()]['nom'] = $Utilisateur->getNom().' '.$Utilisateur->getPrenom();
if ( (!is_null($_GET['uid']) && $Utilisateur->getIdUtilisateur() == $_GET['uid'])
|| (is_null($_GET['uid']) && $Utilisateur->getIdUtilisateur() == $GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur()) ) {
$UtilisateurCourant = clone $Utilisateur;
$aso_stat['utilisateurs'][$Utilisateur->getIdUtilisateur()]['courant'] = true;
$aso_stat['utilisateur_courant'] = $Utilisateur->getNom().' '.$Utilisateur->getPrenom();
$_GET['uid'] = $Utilisateur->getIdUtilisateur();
}
}
$aso_stat['etre_admin'] = $GLOBALS['_GTT_']['Utilisateur']->getMarkAdmin();
$Utilisateur = $UtilisateurCourant;
//+-------------------------------------------------------------------------------------------------+
// GESTION DES CALENDRIERS
//+-------------------------------------------------------------------------------------------------+
// Construction du Calendrier
$Calendrier = new Calendrier();
$tab_jours_feries = $Calendrier->getListeFeries();
// Construction de l'objet mois
$Month = new Calendar_Month_Weeks($_GET['annee'], $_GET['mois']);
$Month->build();
// Récupération des jours du mois
while ($Week = $Month->fetch()) {
$Week->build();
//echo '<pre>'.print_r($Month, true).'</pre>';
$tab_semaine_jours = $Week->fetchAll();
foreach ($tab_semaine_jours as $num => $Day) {
// Nous prenons en compte uniquement les jours du mois courant
if ($Day->thisMonth() == $_GET['mois']) {
$element = array('travail' => 0, 'absence' => 0, 'w_et_a' => 0);
$element['jour'] = $Day->thisDay();
$element['jour_nom'] = $Calendrier->getNomJours($num);
$element['class'] = 'jour';
// Nous vérifions le type de jour
// Jour courrant
if ($Day->isSelected()) {
$element['class'] .= ' jour_courrant';
}
// Jour n'appartenant pas au moins courrant
if ($Day->isEmpty()) {
$element['class'] .= ' jour_vide';
}
// Jour férié
foreach ($tab_jours_feries as $jour_ferie) {
if ($Day->thisDay(true) == $jour_ferie) {
$element['class'] .= ' jour_ferie';
}
}
// Jour de week-end
if ($element['jour_nom'] == GESTION_DIM_L || $element['jour_nom'] == GESTION_SAM_L) {
$element['class'] .= ' jour_we';
}
$id = date('Y-m-d', mktime(0, 0, 0, $Day->thisMonth(), $Day->thisDay(), $Day->thisYear()));
$aso_stat['elements'][$id] = $element;
}
}
}
// Construction de l'url pour les mois précédent/suivant/courant et paramêtres pour le formulaire utilisateur
$aso_stat['form_url'] = 'index.php';
$aso_stat['form_param']['action'] = GTT_ACTION_STAT_TAB_CHARGE;
$aso_stat['form_param']['annee'] = $Month->thisYear();
$aso_stat['form_param']['mois'] = $Month->thisMonth();
$aso_stat['url_mois_courant'] = 'index.php?action='.GTT_ACTION_STAT_TAB_CHARGE.'&amp;annee='.$Month->thisYear().'&amp;mois='.$Month->thisMonth().'&amp;uid='.$_GET['uid'];
$PMonth = $Month->prevMonth('object');
$aso_stat['url_mois_precedent'] = 'index.php?action='.GTT_ACTION_STAT_TAB_CHARGE.'&amp;annee='.$PMonth->thisYear().'&amp;mois='.$PMonth->thisMonth().'&amp;uid='.$_GET['uid'];
$NMonth = $Month->nextMonth('object');
$aso_stat['url_mois_suivant'] = 'index.php?action='.GTT_ACTION_STAT_TAB_CHARGE.'&amp;annee='.$NMonth->thisYear().'&amp;mois='.$NMonth->thisMonth().'&amp;uid='.$_GET['uid'];
$aso_stat['mois']['mois'] = $Calendrier->getNomMois($Month->thisMonth());
$aso_stat['mois']['annee'] = $Month->thisYear();
$mois_courant_j1 = $Month->thisYear().'-'.sprintf("%02s", $Month->thisMonth()).'-'.sprintf("%02s", $Month->thisDay()).' 00:00:00';
$mois_courant_j36 = date('Y-m-d H:i:s', mktime(0, 0, 0, $NMonth->thisMonth(), 0, $NMonth->thisYear()));
//+-------------------------------------------------------------------------------------------------+
// GESTION DES PROJETS
//+-------------------------------------------------------------------------------------------------+
// Récupération du temps de travail pour un utilisateur pour le mois donné
$TravailProjet = new TravailProjet();
$cmd = TravailProjet::GTP_ID_UTILISATEUR_DATE_DEB_FIN;
$param = array($Utilisateur->getIdUtilisateur(), $mois_courant_j1, $mois_courant_j36);
$tab_tp = $TravailProjet->consulter($cmd, $param);
if ($tab_tp != false) {
$tab_projet_id = array();
foreach ($tab_tp as $utp) {
$tab_projet_id[] = $utp->getIdProjet();
}
// Nous vérifions qu'il y a des données pour l'utilisateur courant pour le mois donné
// Récupération des infos sur les projets de l'utilisateur
$Projet = new Projet();
$tab_p = $Projet->consulter(Projet::GP_ID_LIST, array(implode(',', $tab_projet_id)));
foreach ($tab_p as $Projet) {
// Récupération de la catégorie du projet
$ProjetCategorie = new ProjetCategorie();
$cmd = ProjetCategorie::GPC_ID;
$param = $Projet->getCeCategorie();
$Categorie = current($ProjetCategorie->consulter($cmd, $param));
// Nous vérifions le temps de travail pour ce projet
$aso_tps_w = 0;
if ($tab_tp) {
foreach ($tab_tp as $TP) {
$j = date('Y-m-d', strtotime($TP->getIdDateTravail()));
if ($TP->getIdProjet() == $Projet->getIdProjet()) {
// Récupération des infos sur les catégories
if (!isset($aso_stat['categories'][$Categorie->getLibelle()])) {
$aso_stat['categories'][$Categorie->getLibelle()] = array(
'total' => 0,
'abreviation' => $Categorie->getAbreviation());
}
if (!isset($aso_stat['categories'][$Categorie->getLibelle()][$j])) {
$aso_stat['categories'][$Categorie->getLibelle()][$j] = 0;
}
$aso_stat['categories'][$Categorie->getLibelle()][$j] += $TP->getDuree();
$aso_stat['categories'][$Categorie->getLibelle()]['total'] += $TP->getDuree();
// Récupération du total de travail
$aso_stat['total_w'] += $TP->getDuree();
// Récupération du total de temps global (travail+absence)
$aso_stat['total'] += $TP->getDuree();
// Récupération d'info sur le temps travaillé
$aso_stat['elements'][$j]['travail'] += $TP->getDuree();
 
// Récupération du total travail + absence par jour
$aso_stat['elements'][$j]['w_et_a'] += $TP->getDuree();
// Récupération des infos sur les projets
if (!isset($aso_stat['projets'][$Categorie->getLibelle()][$Projet->getIdProjet()])) {
$aso_stat['projets'][$Categorie->getLibelle()][$Projet->getIdProjet()] = array(
'id' => $Projet->getIdProjet(),
'nom' => $Projet->getNom(),
'desc' => $Projet->getDescription(),
'duree' => array(),
'total' => 0);
}
$aso_stat['projets'][$Categorie->getLibelle()][$Projet->getIdProjet()]['duree'][$j] = $TP->getDuree();
$aso_stat['projets'][$Categorie->getLibelle()][$Projet->getIdProjet()]['total'] += $TP->getDuree();
}
}
}
}
} else {
$aso_stat['messages'][] = 'Aucune information sur le travail en '.$aso_stat['mois']['mois'].' '.$aso_stat['mois']['annee'];
}
//+-------------------------------------------------------------------------------------------------+
// GESTION DES ABSENCES
//+-------------------------------------------------------------------------------------------------+
// Récupération des motifs d'absence
$AbsenceMotif = new AbsenceMotif();
$cmd = AbsenceMotif::GAM_TOUS;
$tab_am = $AbsenceMotif->consulter($cmd);
 
// Récupération des absences pour un utilisateur à une date donnée
$Absence = new Absence();
$cmd = Absence::GA_ID_UTILISATEUR_DATE_DEB_FIN;
$param = array($Utilisateur->getIdUtilisateur(), $mois_courant_j1, $mois_courant_j36);
$tab_a = $Absence->consulter($cmd, $param);
if ($tab_a != false) {
$aso_stat['ab_total'] = '';
if ($tab_am) {
foreach ($tab_am as $AM) {
// Initialisation du tableau des types d'absences
$aso_stat['absences'][$AM->getIdAbsenceMotif()]['nom'] = $AM->getLibelle();
if (!isset($aso_stat['absences'][$AM->getIdAbsenceMotif()]['total'])) {
$aso_stat['absences'][$AM->getIdAbsenceMotif()]['total'] = 0;
}
 
if ($tab_a) {
foreach ($tab_a as $A) {
if ($A->getIdAbsenceMotif() == $AM->getIdAbsenceMotif() && $A->getDuree() != 0) {
$j = date('Y-m-d', strtotime($A->getIdDateAbsence()));
 
// Récupération des infos sur les absences
$aso_stat['ab'][$AM->getIdAbsenceMotif()][$j] = $A->getDuree();
// Récupération du total des absences par jour
$aso_stat['elements'][$j]['absence'] += $A->getDuree();
// Récupération du total travail + absence par jour
$aso_stat['elements'][$j]['w_et_a'] += $A->getDuree();
 
// Récupération du total pour chaque type d'absence
$aso_stat['absences'][$AM->getIdAbsenceMotif()]['total'] += $A->getDuree();
 
// Récupération du total des absences
$aso_stat['total_a'] += $A->getDuree();
// Récupération du total de temps global (travail+absence)
$aso_stat['total'] += $A->getDuree();
}
}
}
}
}
} else {
$aso_stat['messages'][] = 'Aucune absence de mentionnée en '.$aso_stat['mois']['mois'].' '.$aso_stat['mois']['annee'];
}
// Post-traitement des nombre pour l'affichage
$formatage = array('ab', 'elements','absences', 'total_a', 'total_w', 'total', 'categories', 'projets');
foreach ($formatage as $cle) {
$aso_stat[$cle] = Nombre::formaterNbre($aso_stat[$cle], GTT_LANGUE);
}
// Sortie
//trigger_error(print_r($aso_stat, true), E_USER_NOTICE);
$this->getRegistre()->ajouterDonnee('stat_tableau_charge', $aso_stat);
}
}
?>
/tags/v1.0-Homere/actions/GttCtrlActionMenu.class.php
New file
0,0 → 1,24
<?php
class GttCtrlActionMenu extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('Menu', 'zone_menu');
$Registre->ajouterSquelette('zone_menu', 'menu');
}
 
public function executer()
{
$aso_menu = array();
 
// Nous vérifions les droits de l'utilisateur.
$aso_menu['bool_admin'] = false;
if ($GLOBALS['_GTT_']['Utilisateur']->getMarkAdmin()) {
$aso_menu['bool_admin'] = true;
}
 
//echo '<pre>'.print_r($aso_menu, true).'</pre>';
$this->getRegistre()->ajouterDonnee('zone_menu', $aso_menu);
}
}
?>
/tags/v1.0-Homere/actions/GttCtrlActionAdminAbsenceMotif.class.php
New file
0,0 → 1,214
<?php
class GttCtrlActionAdminAbsenceMotif extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('AdminAbsenceMotif', 'admin_absence_motif');
$Registre->setTitre("Administrer les motifs d'absence");
}
 
public function executer()
{
$aso_admin_absence_motif = array();
 
// Récupération des catégories
$AbsenceMotif = new AbsenceMotif();
 
// Utilisateur vide par défaut
$aso_admin_absence_motif['AbsenceMotif'] = clone $AbsenceMotif;
$tab_am = $AbsenceMotif->consulter(AbsenceMotif::GAM_TOUS);
if ($tab_am) {
if ($tab_am instanceof AbsenceMotif) {
$tab_am = array($tab_am);
}
foreach ($tab_am as $am) {
if ($am->getIdAbsenceMotif() != 0) {
$aso_motif['id'] = $am->getIdAbsenceMotif();
$aso_motif['libelle'] = $am->getLibelle();
$aso_admin_absence_motif['motifs'][] = $aso_motif;
}
}
}
// Modification des titres, légendes et bouton
$aso_admin_absence_motif['form_legend'] = "Ajouter un motif d'abscence";
$aso_admin_absence_motif['form_bouton_value'] = 'Ajouter';
$aso_admin_absence_motif['form_bouton_id'] = 'btn_absence_motif_ajouter';
$aso_admin_absence_motif['form_url'] = 'index.php?action=admin-absence-motif_valider-ajouter';
//echo '<pre>'.print_r($aso_admin_absence_motif, true).'</pre>';
$this->getRegistre()->ajouterDonnee('admin_absence_motif', $aso_admin_absence_motif);
}
public function executerEditer()
{
// Initialisation de variable
$aso_admin_absence_motif = array();
 
// Récupération d'info en fonction du bouton selectionné
if (isset($_POST['btn_absence_motif_modifier'])) {
// Récupération des données du motif à modifier
$AbsenceMotif = new AbsenceMotif();
$AbsenceMotif ->consulter(AbsenceMotif::GAM_ID, $_POST['amsu_id'], true);
$aso_admin_absence_motif['AbsenceMotif'] = $AbsenceMotif;
 
// Modification des titres, légendes et bouton
$aso_admin_absence_motif['form_legend'] = "Modifier un motif d'absence";
$aso_admin_absence_motif['form_bouton_value'] = 'Modifier';
$aso_admin_absence_motif['form_bouton_id'] = 'btn_absence_motif_modifier';
$aso_admin_absence_motif['form_url'] = 'index.php?action=admin-absence-motif_valider-modifier';
 
$this->getRegistre()->ajouterDonnee('admin_absence_motif', $aso_admin_absence_motif);
} else if (isset($_POST['btn_absence_motif_supprimer'])) {
// Action suivante
$this->setSuivant('ValiderSupprimer');
}
}
public function executerValiderAjouter()
{
if (isset($_POST['btn_absence_motif_annuler'])) {
// Action suivante
$this->setSuivant('__defaut__');
} else if (isset($_POST['btn_absence_motif_ajouter'])) {
// Vérification du motif à ajouter
$bool_modifier = true;
$AbsenceMotif = new AbsenceMotif();
$AmLibelle = $AbsenceMotif->consulter(AbsenceMotif::GAM_LIBELLE, array($_POST['amaj_libelle']));
if ((is_array($AmLibelle) && count($AmLibelle) > 1) || ($AmLibelle instanceof AbsenceMotif && $AmLibelle->getIdAbsenceMotif() != $_POST['amaj_id_absence_motif'])) {
$aso_admin_absence_motif['messages'][] = "Un motif d'absence avec le même libellé existe déjà !";
$bool_modifier = false;
}
//$this->verifierChampsCommuns(&$aso_admin_absence_motif, &$bool_modifier);
if ($bool_modifier) {
// Action suivante
$this->setSuivant('ajouter');
} else {
// Action suivante
$this->setSuivant('__defaut__');
$this->getRegistre()->ajouterDonnee('admin_absence_motif', $aso_admin_absence_motif);
}
}
}
 
public function executerAjouter()
{
// Initialisation de variable
$aso_admin_motif = array();
// Création de l'objet AbsenceMotif à ajouter
$AbsenceMotif = new AbsenceMotif();
$AbsenceMotif->setLibelle($_POST['amaj_libelle']);
if (!isset($_POST['amaj_mark_cp_diminuer'])) {
$_POST['amaj_mark_cp_diminuer'] = 0;
}
$AbsenceMotif->setMarkCpDiminuer($_POST['amaj_mark_cp_diminuer']);
if (!isset($_POST['amaj_mark_hs_diminuer'])) {
$_POST['amaj_mark_hs_diminuer'] = 0;
}
$AbsenceMotif->setMarkHsDiminuer($_POST['amaj_mark_hs_diminuer']);
if ($AbsenceMotif->ajouter()) {
$aso_admin_motif['messages'][] = "Le motif d'absence ${_POST['amaj_libelle']} a été ajouté.";
}
// Ajout du message d'information
$this->getRegistre()->ajouterDonnee('admin_absence_motif', $aso_admin_motif);
// Action suivante
$this->setSuivant('__defaut__');
}
 
public function executerValiderModifier()
{
if (isset($_POST['btn_absence_motif_annuler'])) {
// Action suivante
$this->setSuivant('__defaut__');
} else if (isset($_POST['btn_absence_motif_modifier'])) {
// Initialisation de variable
$aso_admin_motif = array();
// Vérification du motif à modifier
$bool_modifier = true;
$AbsenceMotif = new AbsenceMotif();
$AmLibelle = $AbsenceMotif->consulter(AbsenceMotif::GAM_LIBELLE, array($_POST['amaj_libelle']));
if ((is_array($AmLibelle) && count($AmLibelle) > 1) || ($AmLibelle instanceof AbsenceMotif && $AmLibelle->getIdAbsenceMotif() != $_POST['amaj_id_absence_motif'])) {
$aso_admin_motif['messages'][] = "Un motif d'absence avec le même libellé existe déjà !";
$bool_modifier = false;
}
//$this->verifierChampsCommuns(&$aso_admin_absence_motif, &$bool_modifier);
if ($bool_modifier) {
// Action suivante
$this->setSuivant('modifier');
} else {
// Action suivante
$_POST['btn_motif_absence_modifier'] = 'btn_absence_motif_modifier';
$_POST['amsu_id'] = $_POST['amaj_id_absence_motif'];
$this->setSuivant('editer');
$this->getRegistre()->ajouterDonnee('admin_absence_motif', $aso_admin_motif);
}
}
}
 
public function executerModifier()
{
// Initialisation de variable
$aso_admin_motif = array();
// Création de l'objet AbsenceMotif à modifier
$AbsenceMotif = new AbsenceMotif();
$AbsenceMotif->setIdAbsenceMotif($_POST['amaj_id_absence_motif']);
$AbsenceMotif->setLibelle($_POST['amaj_libelle']);
if (!isset($_POST['amaj_mark_cp_diminuer'])) {
$_POST['amaj_mark_cp_diminuer'] = 0;
}
$AbsenceMotif->setMarkCpDiminuer($_POST['amaj_mark_cp_diminuer']);
if (!isset($_POST['amaj_mark_hs_diminuer'])) {
$_POST['amaj_mark_hs_diminuer'] = 0;
}
$AbsenceMotif->setMarkHsDiminuer($_POST['amaj_mark_hs_diminuer']);
 
if ($AbsenceMotif->modifier()) {
$aso_admin_motif['messages'][] = "Le motif d'absence ${_POST['amaj_libelle']} a été modifié.";
}
// Ajout du message d'information
$this->getRegistre()->ajouterDonnee('admin_absence_motif', $aso_admin_motif);
// Action suivante
$this->setSuivant('__defaut__');
}
 
public function executerValiderSupprimer()
{
// Initialisation des variables
$aso_admin_motif = array();
 
// Vérif des absences
$Absence = new Absence();
$bool_existe = $Absence->consulter(Absence::GA_ID_ABSENCE_MOTIF, array($_POST['amsu_id']));
if ($bool_existe == false) {
trigger_error('Absence -> OK', E_USER_NOTICE);
// Suppression du motif d'absence
$AbsenceMotif = new AbsenceMotif();
$AbsenceMotif->setIdAbsenceMotif($_POST['amsu_id']);
if ($AbsenceMotif->supprimer()) {
$aso_admin_motif['messages'][] = "Le motif d'absence a été supprimé.";
}
}
// Message d'erreur si le motif d'absence est utilisé
if ($bool_existe != false) {
$aso_admin_motif['messages'][ ] = "Il n'est pas possible de supprimer un motif d'absence contenant des données!";
}
 
// Enregistrement du message
$this->getRegistre()->ajouterDonnee('admin_absence_motif', $aso_admin_motif);
// Action suivante
$this->setSuivant('__defaut__');
}
}
?>
/tags/v1.0-Homere/actions/GttCtrlActionAdminUtilisateurStatut.class.php
New file
0,0 → 1,69
<?php
class GttCtrlActionAdminUtilisateurStatut extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('AdminUtilisateurStatut', 'admin_utilisateur_statut');
$Registre->setTitre('Administrer les statuts des utilisateurs');
}
 
public function executer()
{
$aso_admin_us = array();
 
// Récupération des statuts d'utilisateur
$UtilisateurStatut = new UtilisateurStatut();
$tab_us = $UtilisateurStatut->consulter(UtilisateurStatut::GUS_TOUS);
foreach ($tab_us as $us) {
// Nous récupérons tous les statuts sauf le null (=0)
if ($us->getIdUtilisateurStatut() != 0) {
$aso_us['id'] = $us->getIdUtilisateurStatut();
$aso_us['libelle'] = $us->getLibelle();
$aso_admin_us['statuts'][] = $aso_us;
}
}
 
//echo '<pre>'.print_r($aso_admin_us, true).'</pre>';
$this->getRegistre()->ajouterDonnee('admin_utilisateur_statut', $aso_admin_us);
}
 
public function executerValiderAjouter()
{
// Ajout du statut d'utilisateur
$UtilisateurStatut = new UtilisateurStatut();
$bool_existe = $UtilisateurStatut->consulter(UtilisateurStatut::GUS_LIBELLE, array($_POST['usaj_libelle']));
if ($bool_existe == false) {
$UtilisateurStatut->setLibelle($_POST['usaj_libelle']);
$UtilisateurStatut->ajouter();
} else {
$aso_admin_us['message'] = 'Ce statut d\'utilisateur existe déjà !';
$this->getRegistre()->ajouterDonnee('admin_utilisateur_statut', $aso_admin_us);
}
 
// Action suivante
$this->setSuivant('__defaut__');
}
 
public function executerValiderSupprimer()
{
// Suppression du statut d'utilisateur
$UtilisateurStatut = new UtilisateurStatut();
$UtilisateurStatut->setIdUtilisateurStatut($_POST['ussu_id']);
$UtilisateurStatut->supprimer();
 
// Mise à jour des utilisateurs possédant ce statut
$Utilisateur = new Utilisateur();
$tab_u = $Utilisateur->consulter(Utilisateur::GU_CE_STATUT, $_POST['ussu_id']);
if ($tab_u != false) {
foreach ($tab_u as $u) {
$Ancien = clone $u;
$u->setCeStatut(0);
$u->modifier($Ancien);
}
}
 
// Action suivante
$this->setSuivant('__defaut__');
}
}
?>
/tags/v1.0-Homere/actions/GttCtrlActionGestion.class.php
New file
0,0 → 1,429
<?php
class GttCtrlActionGestion extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('Gestion', 'gestion');
$Registre->ajouterEspace('ZoneCalendrier', 'zone_calendrier');
$Registre->ajouterSquelette('zone_calendrier', 'calendrier_mini');
}
 
public function executer()
{
$aso_gestion = array();
$this->getRegistre()->setTitre('Gérer son temps');
 
//+-------------------------------------------------------------------------------------------------+
// GESTION DES CALENDRIERS
//+-------------------------------------------------------------------------------------------------+
// Initialisation des variables pour le calendrier
if (!isset($_GET['annee'])) {
$_GET['annee'] = date('Y');
}
if (!isset($_GET['mois'])) {
$_GET['mois'] = date('m');
}
if (!isset($_GET['semaine'])) {
$_GET['semaine'] = date('W');
}
if (!isset($_GET['jour'])) {
$_GET['jour'] = date('d');
}
// Instanciation de la classe Calendrier France
$Calendrier = new Calendrier($_GET['jour'], $_GET['semaine'], $_GET['mois'], $_GET['annee']);
$tab_jours_feries = $Calendrier->getListeFeries();
 
// Create an array of days which are "selected"
// Used for Week::build() below
$CalendrierJourCourrant = new Calendar_Week(date('Y'), date('m'), date('d'));
$aso_gestion['jc']['jour'] = $CalendrierJourCourrant->thisDay();
$aso_gestion['jc']['semaine'] = $CalendrierJourCourrant->thisWeek('n_in_year');
$aso_gestion['jc']['mois'] = $CalendrierJourCourrant->thisMonth();
$aso_gestion['jc']['mois_nom'] = $Calendrier->getNomMois($CalendrierJourCourrant->thisMonth());
$aso_gestion['jc']['annee'] = $CalendrierJourCourrant->thisYear();
$aso_gestion['jc_url'] = 'index.php?action='.GTT_ACTION_GESTION.'&amp;annee='.$aso_gestion['jc']['annee'].'&amp;mois='.$aso_gestion['jc']['mois'].'&amp;semaine='.$aso_gestion['jc']['semaine'].'&amp;jour='.$aso_gestion['jc']['jour'];
 
$CalendrierJourCourrant->build();
$CalendrierSemaineCourrante = $CalendrierJourCourrant->thisWeek('object');
$CalendrierSemaineCourrante->build();
$tab_jours = $CalendrierSemaineCourrante->fetchAll();
$aso_gestion['sjc_1']['jour'] = $tab_jours[1]->thisDay();
$aso_gestion['sjc_1']['mois'] = $Calendrier->getNomMois($tab_jours[1]->thisMonth());
$aso_gestion['sjc_1']['annee'] = $tab_jours[1]->thisYear();
$aso_gestion['sjc_7']['jour'] = $tab_jours[7]->thisDay();
$aso_gestion['sjc_7']['mois'] = $Calendrier->getNomMois($tab_jours[7]->thisMonth());
$aso_gestion['sjc_7']['annee'] = $tab_jours[7]->thisYear();
 
$aso_gestion['selectedDays'] = array ($CalendrierJourCourrant);
 
// Instruct month to build Week objects
// Construction de l'objet mois
$Month = new Calendar_Month_Weeks($_GET['annee'], $_GET['mois']);
$Month->build();
 
while ($Week = $Month->fetch()) {
$Week->build($aso_gestion['selectedDays']);
//echo '<pre>'.print_r($Month, true).'</pre>';
$tab_semaine_jours = $Week->fetchAll();
foreach ($tab_semaine_jours as $num => $Day) {
$element = array();
$element['annee'] = $Day->thisYear();
$element['mois'] = $Day->thisMonth();
$element['jour'] = $Day->thisDay();
$element['jour_nom'] = $Calendrier->getNomJours($num);
$element['url'] = 'index.php?action='.GTT_ACTION_GESTION.'&amp;annee='.$Day->thisYear().'&amp;mois='.$Day->thisMonth().'&amp;jour='.$Day->thisDay();
// Check to see if day is selected
if ($Day->isSelected()) {
$element['class'] = 'jour_courrant';
} else if ($Day->isEmpty()) {
$element['class'] = 'jour_vide';
} else {
$element['class'] = 'jour';
}
foreach ($tab_jours_feries as $jour_ferie) {
if ($Day->thisDay(true) == $jour_ferie) {
$element['class'] = 'jour_ferie';
}
}
$aso_gestion['elements'][$Week->thisWeek('n_in_year')][$num] = $element;
}
}
 
// Construction de l'url pour les mois précédent/suivant
$PMonth = $Month->prevMonth('object');
$aso_gestion['url_mois_precedent'] = 'index.php?action='.GTT_ACTION_GESTION.'&amp;annee='.$PMonth->thisYear().'&amp;mois='.$PMonth->thisMonth().'&amp;jour='.$PMonth->thisDay();
$NMonth = $Month->nextMonth('object');
$aso_gestion['url_mois_suivant'] = 'index.php?action='.GTT_ACTION_GESTION.'&amp;annee='.$NMonth->thisYear().'&amp;mois='.$NMonth->thisMonth().'&amp;jour='.$NMonth->thisDay();
$aso_gestion['mois']['mois'] = $Calendrier->getNomMois($Month->thisMonth());
$aso_gestion['mois']['annee'] = $Month->thisYear();
 
// Construction de l'url pour les semaines précédente/suivante
$Week = new Calendar_Week($_GET['annee'], $_GET['mois'], $_GET['jour']);
$aso_gestion['s'] = $Week->thisWeek('n_in_year');
 
$PWeek = $Week->prevWeek('object');
$aso_gestion['url_semaine_precedente'] = 'index.php?action='.GTT_ACTION_GESTION.'&amp;annee='.$PWeek->thisYear().'&amp;mois='.$PWeek->thisMonth().'&amp;jour='.$PWeek->thisDay();
 
$url_sc_param_date = '&amp;annee='.$Week->thisYear().'&amp;mois='.$Week->thisMonth().'&amp;jour='.$Week->thisDay();
$aso_gestion['url_semaine_courante'] = 'index.php?action='.GTT_ACTION_GESTION.$url_sc_param_date;
 
$NWeek = $Week->nextWeek('object');
$aso_gestion['url_semaine_suivante'] = 'index.php?action='.GTT_ACTION_GESTION.'&amp;annee='.$NWeek->thisYear().'&amp;mois='.$NWeek->thisMonth().'&amp;jour='.$NWeek->thisDay();
 
$Week->build();
$aso_jours = array();
foreach($Week->fetchAll() as $num => $j) {
$aso_gestion['sj_'.$num]['jour'] = $j->thisDay();
$aso_gestion['sj_'.$num]['mois'] = $Calendrier->getNomMois($j->thisMonth());
$aso_gestion['sj_'.$num]['annee'] = $j->thisYear();
$aso_gestion['sj_'.$num]['mysql'] = $aso_gestion['sj_'.$num]['annee'].'-'.sprintf("%02s", $j->thisMonth()).'-'.sprintf("%02s", $aso_gestion['sj_'.$num]['jour']);
$aso_jours[$aso_gestion['sj_'.$num]['mysql']] = $num;
$aso_tps_w_vide[$num] = '';
}
 
//+-------------------------------------------------------------------------------------------------+
// GESTION DES PROJETS
//+-------------------------------------------------------------------------------------------------+
// Récupération des projets sur lesquels l'utilisateur travaille
$UtilsateurAProjet = new UtilisateurAProjet();
$tab_uap = $UtilsateurAProjet->consulter(UtilisateurAProjet::GUAP_UTILISATEUR, $GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur());
// Si nous avons des données...
$aso_gestion['bool_projets'] = false;
if ($tab_uap && count($tab_uap) >= 1) {
$aso_gestion['bool_projets'] = true;
$tab_projet_id = array();
foreach ($tab_uap as $uap) {
$tab_projet_id[] = $uap->getIdProjet();
}
 
// Récupération du temps de travail pour un utilisateur à une date donnée
$TravailProjet = new TravailProjet();
$cmd = TravailProjet::GTP_ID_UTILISATEUR_DATE_DEB_FIN;
$param = array($GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur(), $aso_gestion['sj_1']['mysql'], $aso_gestion['sj_7']['mysql']);
$tab_tp = $TravailProjet->consulter($cmd, $param);
 
// Récupération des infos sur les projets de l'utilisateur
$aso_gestion['totaux'] = $aso_tps_w_vide;
$Projet = new Projet();
$tab_p = $Projet->consulter(Projet::GP_ID_LIST, array(implode(',', $tab_projet_id)));
foreach ($tab_p as $Projet) {
// Récupération de la catégorie du projet
$ProjetCategorie = new ProjetCategorie();
$Categorie = current($ProjetCategorie->consulter(ProjetCategorie::GPC_ID, $Projet->getCeCategorie()));
// Nous vérifions le temps de travail pour ce projet pour la semaine courrante
$aso_tps_w = $aso_tps_w_vide;
if (!isset($aso_gestion['categorie_totaux'][$Categorie->getLibelle()])) {
$aso_gestion['categorie_totaux'][$Categorie->getLibelle()] = $aso_tps_w_vide;
}
if ($tab_tp) {
foreach ($tab_tp as $TP) {
if ($TP->getIdProjet() == $Projet->getIdProjet()) {
$num = $aso_jours[$TP->getIdDateTravail()];
$aso_tps_w[$num] = $TP->getDuree();
$aso_gestion['categorie_totaux'][$Categorie->getLibelle()][$num] += $TP->getDuree();
$aso_gestion['totaux'][$num] += $TP->getDuree();
}
}
}
// Stockage des infos nécessaire pour l'affichage
$aso_gestion['preferences'][$Categorie->getLibelle()][] = array(
'id' => $Projet->getIdProjet(),
'valeur' => $Projet->getIdProjet(),
'nom' => $Projet->getNom(),
'desc' => $Projet->getDescription(),
'date' => $aso_tps_w);
}
}
// Trie par odre alphabétique des catégories...
ksort($aso_gestion['preferences']);
//+-------------------------------------------------------------------------------------------------+
// GESTION DES ABSENCES
//+-------------------------------------------------------------------------------------------------+
// Récupération des motifs d'absence
$AbsenceMotif = new AbsenceMotif();
$cmd = AbsenceMotif::GAM_TOUS;
$tab_am = $AbsenceMotif->consulter($cmd);
 
// Récupération des absences pour un utilisateur à une date donnée
$Absence = new Absence();
$cmd = Absence::GA_ID_UTILISATEUR_DATE_DEB_FIN;
$param = array($GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur(), $aso_gestion['sj_1']['mysql'], $aso_gestion['sj_7']['mysql']);
$tab_a = $Absence->consulter($cmd, $param);
// Si nous avons des absences...
 
$aso_gestion['ab_total'] = $aso_tps_w_vide;
if ($tab_am) {
foreach ($tab_am as $AM) {
$aso_gestion['ab_libelle'][$AM->getIdAbsenceMotif()] = $AM->getLibelle();
$aso_gestion['ab'][$AM->getIdAbsenceMotif()] = $aso_tps_w_vide;
if ($tab_a) {
foreach ($tab_a as $A) {
if ($A->getIdAbsenceMotif() == $AM->getIdAbsenceMotif()) {
$num = $aso_jours[$A->getIdDateAbsence()];
if ($A->getDuree() < 0) {
$A->setDuree(0);
}
$aso_gestion['ab'][$AM->getIdAbsenceMotif()][$num] = $A->getDuree();
$aso_gestion['ab_total'][$num] += $A->getDuree();
$aso_gestion['totaux'][$num] += $A->getDuree();
}
}
}
}
}
// Création de l'url de réponse du formulaire
$aso_gestion['url_gestion_valider'] = 'index.php?action='.GTT_ACTION_GESTION_VALIDER.$url_sc_param_date;
 
//echo '<pre>ici '.print_r($aso_gestion['ab'], true).'la</pre>';
$this->getRegistre()->ajouterDonnee('gestion', $aso_gestion);
$this->getRegistre()->ajouterDonnee('zone_calendrier', $aso_gestion);
}
 
public function verifierValider()
{
 
}
 
public function executerValider()
{
// Création du Calendrier
$Calendrier = new Calendrier($_GET['jour'], null, $_GET['mois'], $_GET['annee']);
 
// Récupération des info sur la semaine courrante
$Week = new Calendar_Week($_GET['annee'], $_GET['mois'], $_GET['jour']);
$Week->build();
$aso_jours = array();
$aso_semaine = array();
$jours_w_semaine = array();
foreach($Week->fetchAll() as $num => $j) {
$aso_semaine[$num]['mysql'] = $j->thisYear().'-'.sprintf("%02s", $j->thisMonth()).'-'.sprintf("%02s", $j->thisDay());
$aso_jours[$aso_semaine[$num]['mysql']] = $num;
// Initialisation de la variable pour la gestion des heures sup
$methode = 'getTdt'.$Calendrier->getNomJoursLong($num);
$jours_w_semaine[$num] = array( 'act' => 0,
'pre' => 0,
'act_a' => 0,
'pre_a' => 0,
'mod' => false,
'tdt' => $GLOBALS['_GTT_']['Utilisateur']->$methode());
// Vérification des jours fériés pour modification du temps de travail automatique
if ($Calendrier->etreFerie($j->getTimestamp())) {
// Nous passons automatiquement le temps de travail à 0
$jours_w_semaine[$num]['tdt'] = 0;
}
}
 
// Récupération du temps de travail pour un utilisateur à une date donnée
$TravailProjet = new TravailProjet();
$cmd = TravailProjet::GTP_ID_UTILISATEUR_DATE_DEB_FIN;
$param = array($GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur(), $aso_semaine[1]['mysql'], $aso_semaine[7]['mysql']);
$tab_tp = $TravailProjet->consulter($cmd, $param);
 
// Création d'un utilisateur pour les mises à jour des CP et RTT
$Utilisateur = new Utilisateur();
$Utilisateur->initialiser();
$Utilisateur->setIdUtilisateur($GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur());
$Utilisateur->setQuotaHeuresSupp($GLOBALS['_GTT_']['Utilisateur']->getQuotaHeuresSupp());
$Utilisateur->setCongesPayes($GLOBALS['_GTT_']['Utilisateur']->getCongesPayes());
 
// Ajout ou Mise à jour des durées de travail
if (isset($_POST['pr'])) {
foreach($_POST['pr'] as $projet_id => $jours) {
foreach($jours as $jour_num => $nbr_heure) {
if (isset($jours_w_semaine[$jour_num])) {
$jours_w_semaine[$jour_num]['act'] += $nbr_heure;
}
$bool_ajouter = true;
if (!empty($tab_tp)) {
foreach ($tab_tp as $TP) {
if ($TP->getIdDateTravail() == $aso_semaine[$jour_num]['mysql']) {
if ($TP->getIdProjet() == $projet_id) {
$bool_ajouter = false;
$jours_w_semaine[$jour_num]['pre'] += $TP->getDuree();
$jours_w_semaine[$jour_num]['mod'] = true;
if ($TP->getDuree() != $nbr_heure) {
if (empty($nbr_heure)) {
// Une fois des données saisie dans un jour, on ne supprime pas la ligne mais
// on met la durée 0
$TP->setDuree(0);
$TP->modifier();
} else {
$TP->setDuree($nbr_heure);
$TP->modifier();
}
}
}
}
}
}
if ($bool_ajouter && !empty($nbr_heure)) {
$TP = new TravailProjet();
$TP->setDuree((float)$nbr_heure);
$TP->setIdUtilisateur($GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur());
$TP->setIdProjet($projet_id);
$TP->setIdDateTravail((string)$aso_semaine[$jour_num]['mysql']);
$TP->ajouter();
}
}
}
}
 
// Récupération des absences pour un utilisateur à une date donnée
$Absence = new Absence();
$cmd = Absence::GA_ID_UTILISATEUR_DATE_DEB_FIN;
$param = array($GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur(), $aso_semaine[1]['mysql'], $aso_semaine[7]['mysql']);
$tab_a = $Absence->consulter($cmd, $param);
 
// Ajout ou Mise à jour des durées d'absences pour congés payés
$cp_h_modif = 0;
$hs_h_modif = 0;
if (isset($_POST['ab'])) {
//echo '<pre>'.print_r($_POST['ab'], true).'</pre>';
foreach($_POST['ab'] as $ab_id => $tab_num_j) {
// Création du motif d'absence pour voir si on doit diminuer les congés payés
$AbsenceMotif = new AbsenceMotif();
$AbsenceMotif->consulter(AbsenceMotif::GAM_ID, $ab_id, true);
 
foreach($tab_num_j as $num_j => $ab_duree) {
// Gestion des heures sup en fonction du type d'absence
if (isset($jours_w_semaine[$num_j])) {
if ($AbsenceMotif->getMarkHsDiminuer()) {
$jours_w_semaine[$num_j]['act_a'] += $ab_duree;
} else {
$jours_w_semaine[$num_j]['act'] += $ab_duree;
}
}
$bool_ajouter = true;
if (!empty($tab_a)) {
foreach ($tab_a as $A) {
if ($A->getIdDateAbsence() == $aso_semaine[$num_j]['mysql']) {
if ($A->getIdAbsenceMotif() == $ab_id) {
$bool_ajouter = false;
$jours_w_semaine[$num_j]['mod'] = true;
// Gestion des heures sup en fonction du type d'absence
if ($AbsenceMotif->getMarkHsDiminuer()) {
$jours_w_semaine[$num_j]['pre_a'] += $A->getDuree();
} else {
$jours_w_semaine[$num_j]['pre'] += $A->getDuree();
}
if ($A->getDuree() != $ab_duree) {
if (empty($ab_duree)) {
if ($AbsenceMotif->getMarkCpDiminuer()) {
$Utilisateur->augmenterCongesPayes($A->getDuree());
}
// Une fois des données saisie dans un jour, on ne supprime pas la ligne mais
// on met la durée 0
$A->setDuree(0);
$A->modifier();
} else {
$ab_duree_tmp = $A->getDuree();
$A->setDuree($ab_duree);
$A->modifier();
if ($AbsenceMotif->getMarkCpDiminuer()) {
$Utilisateur->augmenterCongesPayes(($ab_duree_tmp - $ab_duree));
}
}
}
}
}
}
}
if ($bool_ajouter && !empty($ab_duree)) {
$A = new Absence();
$A->setDuree((float)$ab_duree);
$A->setIdUtilisateur($GLOBALS['_GTT_']['Utilisateur']->getIdUtilisateur());
$A->setIdAbsenceMotif($ab_id);
$A->setIdDateAbsence((string)$aso_semaine[$num_j]['mysql']);
$A->ajouter();
if ($AbsenceMotif->getMarkCpDiminuer()) {
$Utilisateur->diminuerCongesPayes($ab_duree);
}
}
}
}
}
 
// Gestion de la mise à jour des heures sup
foreach ($jours_w_semaine as $c => $j) {
// Modifications existantes pour le jour courant
if (($j['pre'] != 0 || $j['act'] != 0) || ($j['act_a'] != 0 || $j['pre_a'] != 0)) {
$heure_sup_pre = ($j['tdt'] - ($j['pre_a'] + $j['pre'])) + $j['pre_a'];
$heure_sup_act = ($j['tdt'] - ($j['act_a'] + $j['act'])) + $j['act_a'];
$heure_sup_dif = $heure_sup_act - $heure_sup_pre ;
if ($j['mod'] == false) {// Première fois que l'on modifie le jour
if ($heure_sup_act > 0) {
$Utilisateur->diminuerQuotaHeuresSup($heure_sup_act);
}
if ($heure_sup_act < 0) {
$Utilisateur->augmenterQuotaHeuresSup($heure_sup_act);
}
} else {// Les heures sup ont déjà été comptabilisées
if ($heure_sup_dif > 0) {
$Utilisateur->diminuerQuotaHeuresSup($heure_sup_dif);
}
if ($heure_sup_dif < 0) {
$Utilisateur->augmenterQuotaHeuresSup($heure_sup_dif);
}
}
}
}
$Utilisateur->modifier();
 
// Mise à jour de la vue Identité pour les congés payés et RTT
$GttCtrlActionIdentification = new GttCtrlActionIdentification($this->getRegistre());
$GttCtrlActionIdentification->setSuivant('__defaut__');
$this->setSuivant($GttCtrlActionIdentification);
 
// Action suivante
$this->setSuivant('__defaut__');
}
}
?>
/tags/v1.0-Homere/actions/GttCtrlActionIdentification.class.php
New file
0,0 → 1,61
<?php
 
class GttCtrlActionIdentification extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('Identification', 'identification');
}
 
public function executer()
{
$aso_identification = array();
$params = array('dsn' => GTT_BDD_DSN,
'table' => 'gestion_utilisateur',
'usernamecol' => 'gu_email',
'passwordcol' => 'gu_password',
'cryptype' => 'md5',
'db_fields' => '*');
// Création de l'objet auth
$GLOBALS['_GTT_']['identification'] = new Auth('DB', $params, null, false);
$GLOBALS['_GTT_']['identification']->setSessionname(GTT_AUTH_SESSION_NOM);
$GLOBALS['_GTT_']['identification']->setExpire(time()+(int)GTT_AUTH_SESSION_DUREE);
$GLOBALS['_GTT_']['identification']->start();
setcookie(session_name(),session_id(), time()+(int)GTT_AUTH_SESSION_DUREE, "/");
if ($GLOBALS['_GTT_']['identification']->getAuth()) {
require_once GTT_CHEMIN_METIER.'Utilisateur.class.php';
$GLOBALS['_GTT_']['Utilisateur'] = new Utilisateur(Utilisateur::GU_MAIL, array($GLOBALS['_GTT_']['identification']->getUserName()));
$aso_identification['nom'] = $GLOBALS['_GTT_']['Utilisateur']->getNom();
$aso_identification['prenom'] = $GLOBALS['_GTT_']['Utilisateur']->getPrenom();
// Récupération des infos sur l'utilisateur
$aso_identification['cp'] = $GLOBALS['_GTT_']['Utilisateur']->getCongesPayes();
$cp = $aso_identification['cp'] / $GLOBALS['_GTT_']['Utilisateur']->getTempsDeTravailJour();
$aso_identification['cp_j'] = round($cp, 1);
$aso_identification['rtt'] = $GLOBALS['_GTT_']['Utilisateur']->getQuotaHeuresSupp();
$rtt = $aso_identification['rtt'] / $GLOBALS['_GTT_']['Utilisateur']->getTempsDeTravailJour();
$aso_identification['rtt_j'] = round($rtt, 1);
$aso_identification['tps_w'] = $GLOBALS['_GTT_']['Utilisateur']->getTempsDeTravailJour();
 
$this->getRegistre()->ajouterSquelette('identification', 'identite');
//echo '<pre>'.print_r($aso_identification, true).'</pre>';
$this->getRegistre()->ajouterDonnee('identification', $aso_identification);
} else {
$this->setSuivant('Deconnexion', 1);
}
}
 
public function executerDeconnexion()
{
$aso_connexion = array();
$this->getRegistre()->setTitre('Bienvenue sur GTT!');
$this->getRegistre()->ajouterSquelette('identification', 'connexion');
// Création de l'url de réponse du formulaire
$aso_connexion['url'] = 'index.php?action='.GTT_ACTION_CONNEXION;
$GLOBALS['_GTT_']['identification']->logout();
 
//echo '<pre>'.print_r($aso_connexion, true).'</pre>';
$this->getRegistre()->ajouterDonnee('identification', $aso_connexion);
$this->getRegistre()->set('action_finale', true);
}
}
?>
/tags/v1.0-Homere/actions/GttCtrlActionStatTableauGlobal.class.php
New file
0,0 → 1,199
<?php
class GttCtrlActionStatTableauGlobal extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('StatTableauGlobal', 'stat_tableau_global');
}
 
public function executer()
{
$aso_stat = array();
$this->getRegistre()->setTitre('Tableau récapitulatif');
 
//+-------------------------------------------------------------------------------------------------+
// GESTION DES CALENDRIERS
//+-------------------------------------------------------------------------------------------------+
// Initialisation des variables pour le calendrier
if (!isset($_GET['annee'])) {
$_GET['annee'] = date('Y');
}
if (!isset($_GET['mois'])) {
$_GET['mois'] = date('m');
}
 
// Construction de l'objet mois
$Month = new Calendar_Month_Weeks($_GET['annee'], $_GET['mois']);
$Month->build();
 
// Construction du Calendrier
$Calendrier = new Calendrier();
// Construction de l'url pour les mois précédent/suivant
$aso_stat['url_mois_courant'] = 'index.php?action='.GTT_ACTION_STAT_TAB_GLOB.'&amp;annee='.$Month->thisYear().'&amp;mois='.$Month->thisMonth();
$PMonth = $Month->prevMonth('object');
$aso_stat['url_mois_precedent'] = 'index.php?action='.GTT_ACTION_STAT_TAB_GLOB.'&amp;annee='.$PMonth->thisYear().'&amp;mois='.$PMonth->thisMonth();
$NMonth = $Month->nextMonth('object');
$aso_stat['url_mois_suivant'] = 'index.php?action='.GTT_ACTION_STAT_TAB_GLOB.'&amp;annee='.$NMonth->thisYear().'&amp;mois='.$NMonth->thisMonth();
$aso_stat['mois']['mois'] = $Calendrier->getNomMois($Month->thisMonth());
$aso_stat['mois']['annee'] = $Month->thisYear();
$mois_courant_j1 = $Month->thisYear().'-'.sprintf("%02s", $Month->thisMonth()).'-'.sprintf("%02s", $Month->thisDay()).' 00:00:00';
$mois_courant_j36 = date('Y-m-d H:i:s', mktime(0, 0, 0, $NMonth->thisMonth(), 0, $NMonth->thisYear()));
 
//+-------------------------------------------------------------------------------------------------+
// GESTION D'INFO GLOBALES
//+-------------------------------------------------------------------------------------------------+
// Initialisation de variables
$aso_stat['absences'] = false;
$aso_stat['categories'] = false;
// Récupération des infos sur les utilisateurs
$DaoUtilsateur = new Utilisateur();
$utilisateurs = $DaoUtilsateur->consulter(Utilisateur::GU_TOUS_AFFICHABLE);
if (false == $utilisateurs) {
$aso_stat['messages'][] = "Aucun utilisateur affichable de disponible...";
} else {
// Initialisation de variables communes à la gestion des projets et des absences
$aso_stat['total_absences_projets'] = 0;
// Initialisation de variables propre aux absences
$aso_stat['total_absences'] = 0;
// Initialisation de variables propre aux absences
$aso_stat['total_projets'] = 0;
 
// Récupération des motifs d'absence
$AbsenceMotif = new AbsenceMotif();
$cmd = AbsenceMotif::GAM_TOUS;
$tab_am = $AbsenceMotif->consulter($cmd);
if (false == $tab_am) {
$aso_stat['messages'][] = "Aucun motif d'absence de renseigné";
}
// Pour chaque utilisateur nous récupérons les infos
foreach ($utilisateurs as $Utilisateur) {
// Initialisation du talbeau des infos sur l'utilisateur
$aso_gestion = array( 'prenom_nom' => $Utilisateur->getPrenom().' '.$Utilisateur->getNom(),
'total_w' => 0,
'total_a' => 0,
'total' => 0);
//+-------------------------------------------------------------------------------------------------+
// GESTION DES PROJETS
//+-------------------------------------------------------------------------------------------------+
// Récupération du temps de travail pour un utilisateur à une date donnée
$TravailProjet = new TravailProjet();
$cmd = TravailProjet::GTP_ID_UTILISATEUR_DATE_DEB_FIN;
$param = array($Utilisateur->getIdUtilisateur(), $mois_courant_j1, $mois_courant_j36);
$tab_tp = $TravailProjet->consulter($cmd, $param);
if (false == $tab_tp) {
$aso_stat['messages'][] = "Aucune information sur le travail de ${aso_gestion['prenom_nom']}";
} else {
// Récupération des identifiants des projets
$tab_projet_id = array('');
foreach ($tab_tp as $tp) {
$tab_projet_id[0] .= $tp->getIdProjet().',';
}
$tab_projet_id[0] = rtrim($tab_projet_id[0], ',');
// Récupération des infos sur les projets de l'utilisateur
$Projet = new Projet();
$tab_p = $Projet->consulter(Projet::GP_ID_LIST, $tab_projet_id);
foreach ($tab_p as $Projet) {
// Récupération de la catégorie du projet
$ProjetCategorie = new ProjetCategorie();
$cmd = ProjetCategorie::GPC_ID;
$param = $Projet->getCeCategorie();
$Categorie = current($ProjetCategorie->consulter($cmd, $param));
// Info trans utilisateur sur les catégories
if (!isset($aso_stat['categories'][$Categorie->getIdCategorie()])) {
$aso_stat['categories'][$Categorie->getIdCategorie()] = array( 'projets' => array(),
'nom' => $Categorie->getLibelle(),
'abreviation' => $Categorie->getAbreviation(),
'total' => 0);
}
foreach ($tab_tp as $TP) {
if ($TP->getIdProjet() == $Projet->getIdProjet()) {
// Info trans utilisateur sur les catégories
if (!isset($aso_stat['categories'][$Categorie->getIdCategorie()]['projets'][$Projet->getIdProjet()])) {
$aso_stat['categories'][$Categorie->getIdCategorie()]['projets'][$Projet->getIdProjet()] =
array( 'nom' => $Projet->getNom(),
'desc' => $Projet->getDescription(),
'total' => 0);
}
$aso_stat['categories'][$Categorie->getIdCategorie()]['projets'][$Projet->getIdProjet()]['total'] += $TP->getDuree();
$aso_stat['categories'][$Categorie->getIdCategorie()]['total'] += $TP->getDuree();
// Stockage des infos nécessaire pour l'affichage d'un utilisateur
if (!isset($aso_gestion['projets'][$Categorie->getIdCategorie()][$Projet->getIdProjet()])) {
$aso_gestion['projets'][$Categorie->getIdCategorie()][$Projet->getIdProjet()] = array(
'id' => $Projet->getIdProjet(),
'nom' => $Projet->getNom(),
'duree' => 0);
}
$aso_gestion['projets'][$Categorie->getIdCategorie()][$Projet->getIdProjet()]['duree'] += $TP->getDuree();
if (!isset($aso_gestion['projets'][$Categorie->getIdCategorie()]['total'])) {
$aso_gestion['projets'][$Categorie->getIdCategorie()]['total'] = 0;
}
$aso_gestion['projets'][$Categorie->getIdCategorie()]['total'] += $TP->getDuree();
$aso_gestion['total_w'] += $TP->getDuree();
}
}
}
}
$aso_gestion['total'] = $aso_gestion['total_w'];
$aso_stat['total_projets'] += $aso_gestion['total_w'];
//+-------------------------------------------------------------------------------------------------+
// GESTION DES ABSENCES
//+-------------------------------------------------------------------------------------------------+
// Récupération des absences pour un utilisateur à une date donnée
$Absence = new Absence();
$cmd = Absence::GA_ID_UTILISATEUR_DATE_DEB_FIN;
$param = array($Utilisateur->getIdUtilisateur(), $mois_courant_j1, $mois_courant_j36);
$tab_a = $Absence->consulter($cmd, $param);
 
if (false == $tab_a) {
$aso_stat['messages'][] = "Aucune information sur les absences de ${aso_gestion['prenom_nom']}";
} else {
if (false != $tab_am) {
foreach ($tab_am as $AM) {
if (!isset($aso_stat['absences'][$AM->getIdAbsenceMotif()])) {
$aso_stat['absences'][$AM->getIdAbsenceMotif()] =
array( 'nom' => $AM->getLibelle(),
'total' => 0);
}
foreach ($tab_a as $A) {
if ($A->getIdAbsenceMotif() == $AM->getIdAbsenceMotif() && $A->getDuree() != 0) {
$aso_stat['absences'][$AM->getIdAbsenceMotif()]['total'] += $A->getDuree();
$aso_stat['total_absences'] += $A->getDuree();
if (!isset($aso_gestion['ab'][$AM->getIdAbsenceMotif()])) {
$aso_gestion['ab'][$AM->getIdAbsenceMotif()] = 0;
}
$aso_gestion['ab'][$AM->getIdAbsenceMotif()] += $A->getDuree();
$aso_gestion['total_a'] += $A->getDuree();
$aso_gestion['total'] += $A->getDuree();
}
}
}
}
}
$aso_stat['total_absences_projets'] += $aso_gestion['total'];
$aso_stat['utilisateurs'][] = $aso_gestion;
}
}
// Post-traitement des nombre pour l'affichage
$formatage = array('total_projets', 'total_absences','total_absences_projets', 'utilisateurs', 'categories', 'projets', 'absences');
foreach ($formatage as $cle) {
$aso_stat[$cle] = Nombre::formaterNbre($aso_stat[$cle], GTT_LANGUE);
}
// Sortie
//trigger_error(print_r($aso_stat, true), E_USER_NOTICE);
$this->getRegistre()->ajouterDonnee('stat_tableau_global', $aso_stat);
}
}
?>
/tags/v1.0-Homere/actions/GttCtrlActionAdminCategorie.class.php
New file
0,0 → 1,119
<?php
class GttCtrlActionAdminCategorie extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('AdminCategorie', 'admin_categorie');
$Registre->setTitre('Administrer les catégories des projets');
}
 
public function executer()
{
$aso_admin_categ = array();
 
// Récupération des catégories
$ProjetCategorie = new ProjetCategorie();
 
// Ajout de la catégorie par défaut
$aso_admin_categ['ProjetCategorie'] = $ProjetCategorie;
// Récupération des infos sur les categories existantes
$tab_pc = $ProjetCategorie->consulter(ProjetCategorie::GPC_TOUS);
if (false == $tab_pc) {
$aso_admin_categ['categories'] = false;
} else {
foreach ($tab_pc as $pc) {
if ($pc->getIdCategorie() != 0) {
$aso_categ['id'] = $pc->getIdCategorie();
$aso_categ['libelle'] = $pc->getLibelle();
$aso_admin_categ['categories'][] = $aso_categ;
}
}
}
// Modification des titres, légendes et bouton
$aso_admin_categ['form_legend'] = 'Ajouter une categorie';
$aso_admin_categ['form_bouton_value'] = 'Ajouter';
$aso_admin_categ['form_bouton_id'] = 'btn_categorie_ajouter';
$aso_admin_categ['form_url'] = 'index.php?action=admin-categorie_valider-ajouter';
//echo '<pre>'.print_r($aso_admin_categ, true).'</pre>';
$this->getRegistre()->ajouterDonnee('admin_categorie', $aso_admin_categ);
}
 
public function executerEditer()
{
// Ajout du statut d'utilisateur
if (isset($_POST['btn_categorie_modifier'])) {
// Récupération des données de la categorie à modifier
$ProjetCategorie = new ProjetCategorie();
$ProjetCategorie->consulter(ProjetCategorie::GPC_ID, $_POST['casu_id'], true);
$aso_admin_categ['ProjetCategorie'] = $ProjetCategorie;
 
// Modification des titres, légendes et bouton
$aso_admin_categ['form_legend'] = 'Modifier une categorie';
$aso_admin_categ['form_bouton_value'] = 'Modifier';
$aso_admin_categ['form_bouton_id'] = 'btn_categorie_modifier';
$aso_admin_categ['form_url'] = 'index.php?action=admin-categorie_valider-modifier';
 
$this->getRegistre()->ajouterDonnee('admin_categorie', $aso_admin_categ);
} else if (isset($_POST['btn_categorie_supprimer'])) {
// Action suivante
$this->setSuivant('ValiderSupprimer');
}
}
 
public function executerValiderModifier()
{
if (isset($_POST['btn_categorie_annuler'])) {
// Action suivante
$this->setSuivant('__defaut__');
} else if (isset($_POST['btn_categorie_modifier'])) {
$ProjetCategorie = new ProjetCategorie();
$ProjetCategorie->setIdCategorie($_POST['caaj_id_categorie']);
$ProjetCategorie->setLibelle($_POST['caaj_libelle']);
$ProjetCategorie->setAbreviation($_POST['caaj_abreviation']);
$ProjetCategorie->modifier();
}
}
public function executerValiderAjouter()
{
// Ajout de la catégorie
$ProjetCategorie = new ProjetCategorie();
$bool_existe = $ProjetCategorie->consulter(ProjetCategorie::GPC_LIBELLE, array($_POST['caaj_libelle']));
if ($bool_existe == false) {
$ProjetCategorie->setLibelle($_POST['caaj_libelle']);
$ProjetCategorie->setAbreviation($_POST['caaj_abreviation']);
$ProjetCategorie->ajouter();
} else {
$aso_admin_categ['message'] = 'Cette catégorie existe déjà !';
$this->getRegistre()->ajouterDonnee('admin_categorie', $aso_admin_categ);
}
 
// Action suivante
$this->setSuivant('__defaut__');
}
 
public function executerValiderSupprimer()
{
// Suppression de la catégorie
$ProjetCategorie = new ProjetCategorie();
$ProjetCategorie->setIdCategorie($_POST['casu_id']);
$ProjetCategorie->supprimer();
 
// Mise à jour des projets appartenant à la catégorie
$Projet = new Projet();
$tab_p = $Projet->consulter(Projet::GP_CE_CATEGORIE, $_POST['casu_id']);
if ($tab_p != false) {
foreach ($tab_p as $p) {
$Ancien = clone $p;
$p->setCeCategorie(0);
$p->modifier($Ancien);
}
}
 
// Action suivante
$this->setSuivant('__defaut__');
}
}
?>
/tags/v1.0-Homere/actions/GttCtrlActionAdminProjet.class.php
New file
0,0 → 1,208
<?php
class GttCtrlActionAdminProjet extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('AdminProjet', 'admin_projet');
$Registre->setTitre('Administrer les projets');
}
 
public function executer()
{
$aso_admin_projet = array();
// Récupération des projet
$Projet = new Projet();
// Ajout du projet par défaut
$aso_admin_projet['Projet'] = $Projet;
 
// Récupération des catégories
$ProjetCategorie = new ProjetCategorie();
$aso_admin_projet['categories'] = $ProjetCategorie->consulter(ProjetCategorie::GPC_TOUS);
// Récupération des projets
$tab_p = $Projet->consulter(Projet::GP_TOUS);
if (false == $tab_p) {
$aso_admin_projet['projets'] = false;
} else {
foreach ($tab_p as $Pr) {
$aso_projet['id'] = $Pr->getIdProjet();
$aso_projet['nom'] = $Pr->getNom();
$aso_admin_projet['projets'][] = $aso_projet;
}
}
// Modification des titres, légendes et bouton
$aso_admin_projet['form_legend'] = 'Ajouter un projet';
$aso_admin_projet['form_bouton_value'] = 'Ajouter';
$aso_admin_projet['form_bouton_id'] = 'btn_projet_ajouter';
$aso_admin_projet['form_url'] = 'index.php?action=admin-projet_valider-ajouter';
//echo '<pre>'.print_r($aso_admin_projet, true).'</pre>';
$this->getRegistre()->ajouterDonnee('admin_projet', $aso_admin_projet);
}
 
public function executerEditer()
{
if (isset($_POST['btn_projet_modifier'])) {
// Récupération des données du projet à modifier
$Projet = new Projet();
$Projet->consulter(Projet::GP_ID, $_POST['prsu_id'], true);
$aso_admin_projet['Projet'] = $Projet;
// Récupération des catégories
$ProjetCategorie = new ProjetCategorie();
$aso_admin_projet['categories'] = $ProjetCategorie->consulter(ProjetCategorie::GPC_TOUS);
 
// Ajout de la catégorie par défaut
$ProjetCategorie->consulter(ProjetCategorie::GPC_ID, $Projet->getCeCategorie(), true);
$aso_admin_projet['CategorieDefaut'] = $ProjetCategorie;
//echo '<hr>'.print_r($aso_admin_projet['CategorieDefaut'],true);
// Modification des titres, légendes et bouton
$aso_admin_projet['form_legend'] = 'Modifier une projet';
$aso_admin_projet['form_bouton_value'] = 'Modifier';
$aso_admin_projet['form_bouton_id'] = 'btn_projet_modifier';
$aso_admin_projet['form_url'] = 'index.php?action=admin-projet_valider-modifier';
 
$this->getRegistre()->ajouterDonnee('admin_projet', $aso_admin_projet);
} else if (isset($_POST['btn_projet_supprimer'])) {
// Action suivante
$this->setSuivant('ValiderSupprimer');
}
}
 
public function executerValiderModifier()
{
if (isset($_POST['btn_utilisateur_annuler'])) {
// Action suivante
$this->setSuivant('__defaut__');
} else if (isset($_POST['btn_projet_modifier'])) {
$aso_admin_projet = array();
$bool_modifier = true;
$this->verifierChampsCommuns($aso_admin_projet, $bool_modifier);
if ($bool_modifier) {
// Action suivante
$this->setSuivant('modifier');
} else {
$this->getRegistre()->ajouterDonnee('admin_projet', $aso_admin_projet);
// Action suivante
$this->setSuivant('__defaut__');
}
}
}
public function executerModifier()
{
$Projet = new Projet();
//$Projet->setIdCategorie($_POST['caaj_id_categorie']);
$Projet->setIdProjet($_POST['praj_id_projet']);
$Projet->setCeCategorie($_POST['praj_ce_categorie']);
$Projet->setNom($_POST['praj_nom']);
$Projet->setDescription($_POST['praj_description']);
$Projet->setDateDebut($_POST['praj_date_debut']);
$Projet->setDateFin($_POST['praj_date_fin']);
$Projet->setDureePrevue($_POST['praj_duree_prevue']);
$Projet->setDureeFinance($_POST['praj_duree_finance']);
$Projet->setAvancement($_POST['praj_avancement']);
if ($Projet->modifier()) {
$aso_admin_projet['messages'][] = "Le projet ${_POST['praj_nom']} a été modifié.";
}
// Ajout du message d'information
$this->getRegistre()->ajouterDonnee('admin_projet', $aso_admin_projet);
// Action suivante
$this->setSuivant('__defaut__');
}
public function executerValiderAjouter()
{
$aso_admin_projet = array();
if (isset($_POST['btn_projet_annuler'])) {
// Action suivante
$this->setSuivant('__defaut__');
} else if (isset($_POST['btn_projet_ajouter'])) {
$bool_ajouter = true;
// Vérification de l'existance d'un projet avec le même nom
$Projet = new Projet();
$bool_existe = $Projet->consulter(Projet::GP_NOM, array($_POST['praj_nom']));
if (true == $bool_existe) {
$aso_admin_projet['messages'][] = "Un projet avec un nom identique existe déjà !";
$bool_ajouter = false;
}
$this->verifierChampsCommuns($aso_admin_projet, $bool_ajouter);
$this->getRegistre()->ajouterDonnee('admin_projet', $aso_admin_projet);
if ($bool_ajouter) {
// Action suivante
$this->setSuivant('ajouter');
} else {
// Action suivante
$this->setSuivant('__defaut__');
}
}
}
public function executerAjouter()
{
$aso_admin_projet = array();
$Projet = new Projet();
$Projet->setCeCategorie($_POST['praj_ce_categorie']);
$Projet->setNom($_POST['praj_nom']);
$Projet->setDescription($_POST['praj_description']);
$Projet->setDateDebut($_POST['praj_date_debut']);
$Projet->setDateFin($_POST['praj_date_fin']);
$Projet->setDureePrevue($_POST['praj_duree_prevue']);
$Projet->setDureeFinance($_POST['praj_duree_finance']);
$Projet->setAvancement($_POST['praj_avancement']);
if ($Projet->ajouter()) {
$aso_admin_projet['messages'][] = "Le projet ${_POST['praj_nom']} a été ajouté.";
}
// Ajout du message d'information
$this->getRegistre()->ajouterDonnee('admin_projet', $aso_admin_projet);
// Action suivante
$this->setSuivant('__defaut__');
}
public function verifierChampsCommuns(&$aso_admin_projet, &$bool)
{
if (empty($_POST['praj_nom'])) {
$aso_admin_projet['messages'][] = 'Le nom du projet ne doit pas être vide !';
$bool = false;
}
}
 
public function executerValiderSupprimer()
{
$aso_admin_projet = array();
// Vérif des utilisateur_a_projets
$UtilisateurAProjet = new UtilisateurAProjet();
$bool_existe = $UtilisateurAProjet->consulter(UtilisateurAProjet::GUAP_PROJET, array($_POST['prsu_id']));
if ($bool_existe == false) {
trigger_error('UtilisateurAProjet -> OK', E_USER_NOTICE);
// Vérif des travail_projets
$TravailProjet = new TravailProjet();
$bool_existe = $TravailProjet->consulter(TravailProjet::GTP_PROJET, array($_POST['prsu_id']));
if ($bool_existe == false) {
trigger_error('TravailProjet -> OK', E_USER_NOTICE);
// Suppression du projet
$Projet = new Projet();
$Projet->setIdProjet($_POST['prsu_id']);
if ($Projet->supprimer()) {
$aso_admin_projet['messages'][] = "Le projet a été supprimé.";
}
}
}
// Message d'erreur si le projet contient des données
if ($bool_existe != false) {
$aso_admin_projet['messages'][] = "Il n'est pas possible de supprimer un projet contenant des données!";
}
 
// Enregistrement du message
$this->getRegistre()->ajouterDonnee('admin_projet', $aso_admin_projet);
// Action suivante
$this->setSuivant('__defaut__');
}
}
?>
/tags/v1.0-Homere/gtt_config.inc.php
New file
0,0 → 1,76
<?php
//==================================== GTT v4 ==================================
// +------------------------------------------------------------------------------------------------------+
// Gestion des dates
/** Définition du fuseau horaire à utiliser pour eFlore. */
date_default_timezone_set('Europe/Paris');
 
// +------------------------------------------------------------------------------------------------------+
// Définition de la langue
/** Paramêtres indiquant que l'on est en français pourpermettre la mise en majuscule des caractères accentués. */
setlocale(LC_CTYPE, 'fr_FR');
/** Langue à utiliser par défaut. */
define('GTT_LANGUE', 'fr');
 
// +------------------------------------------------------------------------------------------------------+
// La session
// Identification
define('GTT_AUTH_SESSION_NOM', 'gtt_v4');
$tps = 3600*24*30;
define('GTT_AUTH_SESSION_DUREE', (int)$tps);
 
// +------------------------------------------------------------------------------------------------------+
// Les constantes d'action
define ('GTT_ACTION_CONNEXION', 'gestion');
define ('GTT_ACTION_DECONNEXION', 'identification_deconnexion');
define ('GTT_ACTION_IDENTIFICATION', 'identification');
define ('GTT_ACTION_PREFERENCE', 'preferences');
define ('GTT_ACTION_PREFERENCE_VALIDER', 'preferences_valider');
define ('GTT_ACTION_GESTION', 'gestion');
define ('GTT_ACTION_GESTION_VALIDER', 'gestion_valider');
define ('GTT_ACTION_UTILISATEUR', 'utilisateur');
define ('GTT_ACTION_STAT_TAB_GLOB', 'stat-tableau-global');
define ('GTT_ACTION_STAT_TAB_CHARGE', 'stat-tableau-charge');
 
// +------------------------------------------------------------------------------------------------------+
// Les chemins d'accès
define('GTT_CHEMIN_APPLI', '');
define('GTT_CHEMIN_BIBLIO', GTT_CHEMIN_APPLI.'bibliotheque'.DIRECTORY_SEPARATOR);
define('GTT_CHEMIN_ARTICHOW', GTT_CHEMIN_BIBLIO.'artichow'.DIRECTORY_SEPARATOR);
define('GTT_CHEMIN_PEAR', GTT_CHEMIN_BIBLIO.'pear'.DIRECTORY_SEPARATOR);
define('GTT_CHEMIN_METIER', GTT_CHEMIN_BIBLIO.'metier'.DIRECTORY_SEPARATOR);
define('GTT_CHEMIN_NOYAU', GTT_CHEMIN_BIBLIO.'noyau'.DIRECTORY_SEPARATOR);
define('GTT_CHEMIN_ACTION', GTT_CHEMIN_APPLI.'actions'.DIRECTORY_SEPARATOR);
define('GTT_CHEMIN_PRESENTATION', GTT_CHEMIN_APPLI.'presentation'.DIRECTORY_SEPARATOR);
define('GTT_CHEMIN_LANGUE', GTT_CHEMIN_APPLI.'langues'.DIRECTORY_SEPARATOR);
 
// Inclusion des chemins des bibliothèques
// Nous incluons la bibliothèque PEAR de l'appli en premier
ini_set('include_path', GTT_CHEMIN_PEAR.PATH_SEPARATOR.ini_get('include_path'));
 
// Tableau des chemins pour la fonction autoload
$GLOBALS['_GTT_']['tab_chemin_autoload'] = array(GTT_CHEMIN_NOYAU, GTT_CHEMIN_METIER, GTT_CHEMIN_ACTION);
 
// +------------------------------------------------------------------------------------------------------+
// Les valeur de la bdd
define('GTT_ABSCENCE_ID_CP', 1);
define('GTT_ABSCENCE_ID_RTT', 2);
define('GTT_ABSCENCE_ID_MALADIE', 3);
define('GTT_ABSCENCE_ID_GREVE', 4);
 
// +------------------------------------------------------------------------------------------------------+
// Débogage
/** Constante stockant si oui ou non on veut afficher le débogage des fichiers PEAR.*/
define('GTT_DEBOGAGE_PEAR', false);
/** Constante stockant la chaine permettant de repérer en se basant sur le chemin, les fichiers provenant de la bibliothèque PEAR.*/
define('GTT_DEBOGAGE_PEAR_REGEXP_CHAINE', '/(?:\/lib\/php\/|pear)/i');
/** Constante stockant une expression régulière permettant de repérer en se basant sur le message, les fichiers provenant de la bibliothèque PEAR.*/
define('GTT_DEBOGAGE_PEAR_REGEXP_MESSAGE', '/Non-static method (?:DB|PEAR|Calendar_Engine_Factory|Calendar_Factory)/i');
/** Constante stockant si oui ou non on veut afficher le contexte de débogage.*/
define('GTT_DEBOGAGE_CONTEXTE', false);
/** Constante stockant une valeur correspondant au niveau d'erreur à employer pour le code PHP.*/
define('GTT_DEBOGAGE_NIVEAU', 2048);// Voir le manuel de PHP pour les différents niveaux disponibles.
/** Constante stockant si oui ou nom on veut afficher le tableau de chronométrage de l'application.*/
define('GTT_DEBOGAGE_CHRONO', false);
 
?>
Property changes:
Added: svn:executable
/tags/v1.0-Homere/LICENCES
New file
0,0 → 1,5
L'application Gestion du Temps de Travail (GTT) est sous double licence GPL v2 (http://www.opensource.org/licenses/gpl-2.0.php) et CECILL (http://www.cecill.info/) sauf mention contraire dans les fichiers.
La feuille de style Emeraude est à l'origine de Free CSS Templates (http://www.freecsstemplates.org) sous licence Creative Commons Attribution 2.5.
L'icone help_view_16x16.gif (http://www.iconlet.com/info/19266_help_view_16x16) du style Emeraude provient de Eclipse Project sous licence EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html).
L'icone lien_externe.png (http://www.iconlet.com/info/6616_link_16x16) sous licence GNU Lesser General Public License (http://www.gnu.org/copyleft/lgpl.html).
Les favicones sont à l'origine le fichier stock_form-time-field_16x16.png (http://www.iconlet.com/info/75430_stock_form-time-field_16x16) provenant de Titan Creations sous licence Creative Commons Attribution-ShareAlike 2.5.
/tags/v1.0-Homere/AUTEURS
New file
0,0 → 1,3
Jean-Pascal MILCENT <jpm@tela-botanica.org> pour les versions 3 et 4.
Shaheen Raheem <shaheenar50@hotmail.com> pour la version 2.
Dorian Bannier <dbannier@aol.com> pour la version 1.
/tags/v1.0-Homere/documentation/gtt_installation.sql
New file
0,0 → 1,190
-- phpMyAdmin SQL Dump
-- version 2.11.4
-- http://www.phpmyadmin.net
--
-- Serveur: localhost
-- Généré le : Mar 17 Juin 2008 à 18:14
-- Version du serveur: 5.0.51
-- Version de PHP: 5.2.5
 
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
 
--
-- Base de données: `gtt_v4`
--
 
-- --------------------------------------------------------
 
--
-- Structure de la table `gestion_absence`
--
 
CREATE TABLE IF NOT EXISTS `gestion_absence` (
`ga_id_utilisateur` int(11) unsigned NOT NULL,
`ga_id_absence_motif` tinyint(3) unsigned NOT NULL,
`ga_id_date_absence` date NOT NULL default '0000-00-00',
`ga_duree` float NOT NULL default '0',
PRIMARY KEY (`ga_id_utilisateur`,`ga_id_absence_motif`,`ga_id_date_absence`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
 
--
-- Contenu de la table `gestion_absence`
--
 
 
-- --------------------------------------------------------
 
--
-- Structure de la table `gestion_absence_motif`
--
 
CREATE TABLE IF NOT EXISTS `gestion_absence_motif` (
`gam_id_absence_motif` tinyint(3) unsigned NOT NULL auto_increment,
`gam_libelle` varchar(255) collate utf8_unicode_ci NOT NULL,
`gam_mark_cp_diminuer` tinyint(1) NOT NULL,
`gam_mark_hs_diminuer` tinyint(1) NOT NULL,
PRIMARY KEY (`gam_id_absence_motif`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=5 ;
 
--
-- Contenu de la table `gestion_absence_motif`
--
 
INSERT INTO `gestion_absence_motif` (`gam_id_absence_motif`, `gam_libelle`, `gam_mark_cp_diminuer`, `gam_mark_hs_diminuer`) VALUES
(1, 'Congés payés', 1, 0),
(2, 'Récupération', 0, 1),
(3, 'Maladie', 0, 0);
 
-- --------------------------------------------------------
 
--
-- Structure de la table `gestion_projet`
--
 
CREATE TABLE IF NOT EXISTS `gestion_projet` (
`gp_id_projet` int(11) unsigned NOT NULL auto_increment,
`gp_ce_projet_parent` int(11) NOT NULL default '0',
`gp_ce_categorie` int(11) unsigned NOT NULL default '0',
`gp_nom` varchar(255) collate utf8_unicode_ci NOT NULL,
`gp_description` text collate utf8_unicode_ci,
`gp_date_debut` date default '0000-00-00',
`gp_date_fin` date NOT NULL default '0000-00-00',
`gp_duree_prevue` float default '0',
`gp_avancement` int(11) default '0',
PRIMARY KEY (`gp_id_projet`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ;
 
--
-- Contenu de la table `gestion_projet`
--
 
 
-- --------------------------------------------------------
 
--
-- Structure de la table `gestion_projet_categorie`
--
 
CREATE TABLE IF NOT EXISTS `gestion_projet_categorie` (
`gpc_id_categorie` int(11) unsigned NOT NULL auto_increment,
`gpc_libelle` varchar(255) collate utf8_unicode_ci NOT NULL,
`gpc_abreviation` varchar(25) collate utf8_unicode_ci default NULL,
PRIMARY KEY (`gpc_id_categorie`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;
 
--
-- Contenu de la table `gestion_projet_categorie`
--
 
 
-- --------------------------------------------------------
 
--
-- Structure de la table `gestion_travail_projet`
--
 
CREATE TABLE IF NOT EXISTS `gestion_travail_projet` (
`gtp_id_utilisateur` int(11) unsigned NOT NULL,
`gtp_id_projet` int(11) unsigned NOT NULL,
`gtp_id_date_travail` date NOT NULL default '0000-00-00',
`gtp_duree` float NOT NULL default '0',
PRIMARY KEY (`gtp_id_utilisateur`,`gtp_id_projet`,`gtp_id_date_travail`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
 
--
-- Contenu de la table `gestion_travail_projet`
--
 
 
-- --------------------------------------------------------
 
--
-- Structure de la table `gestion_utilisateur`
--
 
CREATE TABLE IF NOT EXISTS `gestion_utilisateur` (
`gu_id_utilisateur` int(11) unsigned NOT NULL auto_increment,
`gu_ce_statut` tinyint(3) unsigned NOT NULL,
`gu_nom` varchar(100) collate utf8_unicode_ci NOT NULL,
`gu_prenom` varchar(100) collate utf8_unicode_ci NOT NULL,
`gu_password` varchar(32) collate utf8_unicode_ci NOT NULL,
`gu_email` varchar(255) collate utf8_unicode_ci NOT NULL,
`gu_telephone` varchar(25) collate utf8_unicode_ci default NULL,
`gu_adresse` varchar(255) collate utf8_unicode_ci default NULL,
`gu_code_postal` varchar(6) collate utf8_unicode_ci default NULL,
`gu_ville` varchar(50) collate utf8_unicode_ci default NULL,
`gu_quota_heures_supp` float default NULL,
`gu_conges_payes` float default NULL,
`gu_temps_de_travail_jour` float default NULL,
`gu_temps_de_travail_mois` float default NULL,
`gu_mark_admin` tinyint(1) default NULL,
`gu_mark_recapitulatif` tinyint(1) default NULL,
`gu_notes` text collate utf8_unicode_ci,
PRIMARY KEY (`gu_id_utilisateur`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ;
 
--
-- Contenu de la table `gestion_utilisateur`
--
 
INSERT INTO `gestion_utilisateur` (`gu_id_utilisateur`, `gu_ce_statut`, `gu_nom`, `gu_prenom`, `gu_password`, `gu_email`, `gu_telephone`, `gu_adresse`, `gu_code_postal`, `gu_ville`, `gu_quota_heures_supp`, `gu_conges_payes`, `gu_temps_de_travail_jour`, `gu_temps_de_travail_mois`, `gu_mark_admin`, `gu_mark_recapitulatif`, `gu_notes`) VALUES
(1, 0, 'DÉMONSTRATION', 'Démo', 'c94a22169d9050aa369648f7bdbe144a', 'demo', '', '', '', '', 0, 0, 7, 0, 1, 0, NULL);
 
-- --------------------------------------------------------
 
--
-- Structure de la table `gestion_utilisateur_a_projet`
--
 
CREATE TABLE IF NOT EXISTS `gestion_utilisateur_a_projet` (
`guap_id_utilisateur` int(11) unsigned NOT NULL,
`guap_id_projet` int(11) unsigned NOT NULL,
PRIMARY KEY (`guap_id_utilisateur`,`guap_id_projet`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
 
--
-- Contenu de la table `gestion_utilisateur_a_projet`
--
 
 
-- --------------------------------------------------------
 
--
-- Structure de la table `gestion_utilisateur_statut`
--
 
CREATE TABLE IF NOT EXISTS `gestion_utilisateur_statut` (
`gus_id_utilisateur_statut` tinyint(3) unsigned NOT NULL auto_increment,
`gus_libelle` varchar(255) collate utf8_unicode_ci NOT NULL,
`gus_mark_recapitulatif` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`gus_id_utilisateur_statut`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=4 ;
 
--
-- Contenu de la table `gestion_utilisateur_statut`
--
 
INSERT INTO `gestion_utilisateur_statut` (`gus_id_utilisateur_statut`, `gus_libelle`, `gus_mark_recapitulatif`) VALUES
(1, 'Salarié', 1),
(2, 'Président', 0),
(3, 'Stagiaire', 0);
/tags/v1.0-Homere/documentation/gtt_maj_001.sql
New file
0,0 → 1,9
ALTER TABLE `gestion_projet` ADD `gp_duree_finance` FLOAT NOT NULL AFTER `gp_duree_prevue` ;
 
ALTER TABLE `gestion_utilisateur` ADD `gu_tdt_lundi` FLOAT NOT NULL DEFAULT '0' AFTER `gu_temps_de_travail_mois` ,
ADD `gu_tdt_mardi` FLOAT NOT NULL DEFAULT '0' AFTER `gu_tdt_lundi` ,
ADD `gu_tdt_mercredi` FLOAT NOT NULL DEFAULT '0' AFTER `gu_tdt_mardi` ,
ADD `gu_tdt_jeudi` FLOAT NOT NULL DEFAULT '0' AFTER `gu_tdt_mercredi` ,
ADD `gu_tdt_vendredi` FLOAT NOT NULL DEFAULT '0' AFTER `gu_tdt_jeudi` ,
ADD `gu_tdt_samedi` FLOAT NOT NULL DEFAULT '0' AFTER `gu_tdt_vendredi` ,
ADD `gu_tdt_dimanche` FLOAT NOT NULL DEFAULT '0' AFTER `gu_tdt_samedi` ;
/tags/v1.0-Homere/documentation/gtt_v4.xml
New file
0,0 → 1,860
<?xml version="1.0" standalone="yes" ?>
<DBMODEL Version="4.0">
<SETTINGS>
<GLOBALSETTINGS ModelName="model_reverse_engineered" IDModel="0" IDVersion="0" VersionStr="1.0.0.0" Comments="" UseVersionHistroy="1" AutoIncVersion="1" DatabaseType="MySQL" ZoomFac="100.00" XPos="0" YPos="0" DefaultDataType="5" DefaultTablePrefix="0" DefSaveDBConn="" DefSyncDBConn="Gestion v4" DefQueryDBConn="" Printer="" HPageCount="4.0" PageAspectRatio="1.440892512336408" PageOrientation="1" PageFormat="A4 (210x297 mm, 8.26x11.7 inches)" SelectedPages="" UsePositionGrid="0" PositionGridX="20" PositionGridY="20" TableNameInRefs="0" DefaultTableType="0" ActivateRefDefForNewRelations="1" FKPrefix="" FKPostfix="" CreateFKRefDefIndex="0" DBQuoteCharacter="`" CreateSQLforLinkedObjects="0" DefModelFont="Nimbus Sans L" CanvasWidth="4096" CanvasHeight="2842" />
<DATATYPEGROUPS>
<DATATYPEGROUP Name="Numeric Types" Icon="1" />
<DATATYPEGROUP Name="Date and Time Types" Icon="2" />
<DATATYPEGROUP Name="String Types" Icon="3" />
<DATATYPEGROUP Name="Blob and Text Types" Icon="4" />
<DATATYPEGROUP Name="User defined Types" Icon="5" />
<DATATYPEGROUP Name="Geographic Types" Icon="6" />
</DATATYPEGROUPS>
<DATATYPES>
<DATATYPE ID="1" IDGroup="0" TypeName="TINYINT" Description="A very small integer. The signed range is -128 to 127. The unsigned range is 0 to 255." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
</PARAMS>
<OPTIONS>
<OPTION Name="UNSIGNED" Default="1" />
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="2" IDGroup="0" TypeName="SMALLINT" Description="A small integer. The signed range is -32768 to 32767. The unsigned range is 0 to 65535." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
</PARAMS>
<OPTIONS>
<OPTION Name="UNSIGNED" Default="1" />
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="3" IDGroup="0" TypeName="MEDIUMINT" Description="A medium-size integer. The signed range is -8388608 to 8388607. The unsigned range is 0 to 16777215." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
</PARAMS>
<OPTIONS>
<OPTION Name="UNSIGNED" Default="1" />
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="4" IDGroup="0" TypeName="INT" Description="A normal-size integer. The signed range is -2147483648 to 2147483647. The unsigned range is 0 to 4294967295." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="1" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
</PARAMS>
<OPTIONS>
<OPTION Name="UNSIGNED" Default="0" />
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="5" IDGroup="0" TypeName="INTEGER" Description="A normal-size integer. The signed range is -2147483648 to 2147483647. The unsigned range is 0 to 4294967295." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="1" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
</PARAMS>
<OPTIONS>
<OPTION Name="UNSIGNED" Default="1" />
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="6" IDGroup="0" TypeName="BIGINT" Description="A large integer. The signed range is -9223372036854775808 to 9223372036854775807. The unsigned range is 0 to 18446744073709551615." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
</PARAMS>
<OPTIONS>
<OPTION Name="UNSIGNED" Default="0" />
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="7" IDGroup="0" TypeName="FLOAT" Description="A small (single-precision) floating-point number. Cannot be unsigned. Allowable values are -3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to 3.402823466E+38." ParamCount="1" OptionCount="1" ParamRequired="1" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="precision" />
</PARAMS>
<OPTIONS>
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="8" IDGroup="0" TypeName="FLOAT" Description="A small (single-precision) floating-point number. Cannot be unsigned. Allowable values are -3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to 3.402823466E+38." ParamCount="2" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
<PARAM Name="decimals" />
</PARAMS>
<OPTIONS>
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="9" IDGroup="0" TypeName="DOUBLE" Description="A normal-size (double-precision) floating-point number. Cannot be unsigned. Allowable values are -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and 2.2250738585072014E-308 to 1.7976931348623157E+308." ParamCount="2" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="2" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
<PARAM Name="decimals" />
</PARAMS>
<OPTIONS>
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="10" IDGroup="0" TypeName="DOUBLE PRECISION" Description="This is a synonym for DOUBLE." ParamCount="2" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="2" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
<PARAM Name="decimals" />
</PARAMS>
<OPTIONS>
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="11" IDGroup="0" TypeName="REAL" Description="This is a synonym for DOUBLE." ParamCount="2" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="2" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
<PARAM Name="decimals" />
</PARAMS>
<OPTIONS>
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="12" IDGroup="0" TypeName="DECIMAL" Description="An unpacked floating-point number. Cannot be unsigned. Behaves like a CHAR column." ParamCount="2" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="3" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
<PARAM Name="decimals" />
</PARAMS>
<OPTIONS>
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="13" IDGroup="0" TypeName="NUMERIC" Description="This is a synonym for DECIMAL." ParamCount="2" OptionCount="1" ParamRequired="1" EditParamsAsString="0" SynonymGroup="3" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
<PARAM Name="decimals" />
</PARAMS>
<OPTIONS>
<OPTION Name="ZEROFILL" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="14" IDGroup="1" TypeName="DATE" Description="A date. The supported range is \a1000-01-01\a to \a9999-12-31\a." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="15" IDGroup="1" TypeName="DATETIME" Description="A date and time combination. The supported range is \a1000-01-01 00:00:00\a to \a9999-12-31 23:59:59\a." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="16" IDGroup="1" TypeName="TIMESTAMP" Description="A timestamp. The range is \a1970-01-01 00:00:00\a to sometime in the year 2037. The length can be 14 (or missing), 12, 10, 8, 6, 4, or 2 representing YYYYMMDDHHMMSS, ... , YYYYMMDD, ... , YY formats." ParamCount="1" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
</PARAMS>
</DATATYPE>
<DATATYPE ID="17" IDGroup="1" TypeName="TIME" Description="A time. The range is \a-838:59:59\a to \a838:59:59\a." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="18" IDGroup="1" TypeName="YEAR" Description="A year in 2- or 4-digit format (default is 4-digit)." ParamCount="1" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
</PARAMS>
</DATATYPE>
<DATATYPE ID="19" IDGroup="2" TypeName="CHAR" Description="A fixed-length string (1 to 255 characters) that is always right-padded with spaces to the specified length when stored. values are sorted and compared in case-insensitive fashion according to the default character set unless the BINARY keyword is given." ParamCount="1" OptionCount="1" ParamRequired="1" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
</PARAMS>
<OPTIONS>
<OPTION Name="BINARY" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="20" IDGroup="2" TypeName="VARCHAR" Description="A variable-length string (1 to 255 characters). Values are sorted and compared in case-sensitive fashion unless the BINARY keyword is given." ParamCount="1" OptionCount="1" ParamRequired="1" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="length" />
</PARAMS>
<OPTIONS>
<OPTION Name="BINARY" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="21" IDGroup="2" TypeName="BIT" Description="This is a synonym for CHAR(1)." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="22" IDGroup="2" TypeName="BOOL" Description="This is a synonym for CHAR(1)." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="23" IDGroup="3" TypeName="TINYBLOB" Description="A column maximum length of 255 (2^8 - 1) characters. Values are sorted and compared in case-sensitive fashion." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="24" IDGroup="3" TypeName="BLOB" Description="A column maximum length of 65535 (2^16 - 1) characters. Values are sorted and compared in case-sensitive fashion." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="25" IDGroup="3" TypeName="MEDIUMBLOB" Description="A column maximum length of 16777215 (2^24 - 1) characters. Values are sorted and compared in case-sensitive fashion." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="26" IDGroup="3" TypeName="LONGBLOB" Description="A column maximum length of 4294967295 (2^32 - 1) characters. Values are sorted and compared in case-sensitive fashion." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="27" IDGroup="3" TypeName="TINYTEXT" Description="A column maximum length of 255 (2^8 - 1) characters." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="28" IDGroup="3" TypeName="TEXT" Description="A column maximum length of 65535 (2^16 - 1) characters." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="29" IDGroup="3" TypeName="MEDIUMTEXT" Description="A column maximum length of 16777215 (2^24 - 1) characters." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="30" IDGroup="3" TypeName="LONGTEXT" Description="A column maximum length of 4294967295 (2^32 - 1) characters." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="31" IDGroup="3" TypeName="ENUM" Description="An enumeration. A string object that can have only one value, chosen from the list of values." ParamCount="1" OptionCount="0" ParamRequired="1" EditParamsAsString="1" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="values" />
</PARAMS>
</DATATYPE>
<DATATYPE ID="32" IDGroup="3" TypeName="SET" Description="A set. A string object that can have zero or more values, each of which must be chosen from the list of values." ParamCount="1" OptionCount="0" ParamRequired="1" EditParamsAsString="1" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<PARAMS>
<PARAM Name="values" />
</PARAMS>
</DATATYPE>
<DATATYPE ID="33" IDGroup="4" TypeName="Varchar(20)" Description="" ParamCount="0" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<OPTIONS>
<OPTION Name="BINARY" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="34" IDGroup="4" TypeName="Varchar(45)" Description="" ParamCount="0" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<OPTIONS>
<OPTION Name="BINARY" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="35" IDGroup="4" TypeName="Varchar(255)" Description="" ParamCount="0" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
<OPTIONS>
<OPTION Name="BINARY" Default="0" />
</OPTIONS>
</DATATYPE>
<DATATYPE ID="36" IDGroup="5" TypeName="GEOMETRY" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="38" IDGroup="5" TypeName="LINESTRING" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="39" IDGroup="5" TypeName="POLYGON" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="40" IDGroup="5" TypeName="MULTIPOINT" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="41" IDGroup="5" TypeName="MULTILINESTRING" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="42" IDGroup="5" TypeName="MULTIPOLYGON" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
<DATATYPE ID="43" IDGroup="5" TypeName="GEOMETRYCOLLECTION" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
</DATATYPE>
</DATATYPES>
<COMMON_DATATYPES>
<COMMON_DATATYPE ID="5" />
<COMMON_DATATYPE ID="8" />
<COMMON_DATATYPE ID="20" />
<COMMON_DATATYPE ID="15" />
<COMMON_DATATYPE ID="22" />
<COMMON_DATATYPE ID="28" />
<COMMON_DATATYPE ID="26" />
<COMMON_DATATYPE ID="33" />
<COMMON_DATATYPE ID="34" />
<COMMON_DATATYPE ID="35" />
</COMMON_DATATYPES>
<TABLEPREFIXES>
<TABLEPREFIX Name="Default (no prefix)" />
</TABLEPREFIXES>
<REGIONCOLORS>
<REGIONCOLOR Color="Red=#FFEEEC" />
<REGIONCOLOR Color="Yellow=#FEFDED" />
<REGIONCOLOR Color="Green=#EAFFE5" />
<REGIONCOLOR Color="Cyan=#ECFDFF" />
<REGIONCOLOR Color="Blue=#F0F1FE" />
<REGIONCOLOR Color="Magenta=#FFEBFA" />
</REGIONCOLORS>
<POSITIONMARKERS>
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
</POSITIONMARKERS>
</SETTINGS>
<METADATA>
<REGIONS>
<REGION ID="1777" RegionName="A impl\195\169menter" XPos="969" YPos="148" Width="340" Height="670" RegionColor="0" TablePrefix="0" TableType="0" OverwriteTablePrefix="0" OverwriteTableType="0" Comments="" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="27" />
</REGIONS>
<TABLES>
<TABLE ID="1394" Tablename="gestion_absence" PrevTableName="" XPos="386" YPos="643" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="2" >
<COLUMNS>
<COLUMN ID="1761" ColName="ga_id_utilisateur" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1762" ColName="ga_id_absence_motif" PrevColName="" Pos="1" idDatatype="1" DatatypeParams="(3)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1411" ColName="ga_id_date_absence" PrevColName="" Pos="3" idDatatype="14" DatatypeParams="" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="0000-00-00" Comments="">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1413" ColName="ga_duree" PrevColName="" Pos="5" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_END>
<RELATION_END ID="1583" />
<RELATION_END ID="1585" />
</RELATIONS_END>
<INDICES>
<INDEX ID="1414" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1761" LengthParam="0" />
<INDEXCOLUMN idColumn="1762" LengthParam="0" />
<INDEXCOLUMN idColumn="1411" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1395" Tablename="gestion_projet_categorie" PrevTableName="gestion_categorie" XPos="43" YPos="71" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="3" >
<COLUMNS>
<COLUMN ID="1415" ColName="gpc_id_categorie" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="1" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1416" ColName="gpc_libelle" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_START>
<RELATION_START ID="1564" />
</RELATIONS_START>
<INDICES>
<INDEX ID="1417" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1415" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1396" Tablename="gestion_frais_km" PrevTableName="gestion_composer_utilisateur_frais_kilometrique" XPos="1027" YPos="349" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="4" >
<COLUMNS>
<COLUMN ID="1605" ColName="gfk_id_frais_km" PrevColName="gcufk_id_frais_km" Pos="7" idDatatype="5" DatatypeParams="(11)" Width="-1" Prec="-1" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1737" ColName="gfkt_id_frais_km_taux" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1639" ColName="gfk_ce_utilisateur" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1420" ColName="gfk_date" PrevColName="gcufk_date_frais" Pos="3" idDatatype="14" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="0000-00-00" Comments="">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1421" ColName="gfk_nbre_km" PrevColName="gcufk_nb_kilometre" Pos="4" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1422" ColName="gfk_objet" PrevColName="gcufk_objet" Pos="5" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1423" ColName="gfk_trajet" PrevColName="gcufk_trajet" Pos="6" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1424" ColName="gfk_montant_total" PrevColName="gcufk_montant_total" Pos="7" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_END>
<RELATION_END ID="1503" />
<RELATION_END ID="1505" />
</RELATIONS_END>
<INDICES>
<INDEX ID="1425" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1605" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1397" Tablename="gestion_note_frais_ligne" PrevTableName="gestion_depense" XPos="1025" YPos="651" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="5" >
<COLUMNS>
<COLUMN ID="1617" ColName="gnfl_id_note_frais_ligne" PrevColName="gld_id_ligne_depense" Pos="3" idDatatype="5" DatatypeParams="(11)" Width="-1" Prec="-1" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1634" ColName="gnfl_ce_note_frais" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1428" ColName="gnfl_date" PrevColName="gd_date_depense" Pos="3" idDatatype="14" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="0000-00-00" Comments="">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1429" ColName="gnfl_montant_ht" PrevColName="gd_montant_ht" Pos="4" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1620" ColName="gnfl_taux_tva" PrevColName="gld_taux_tva" Pos="5" idDatatype="7" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1430" ColName="gnfl_montant_ttc" PrevColName="gd_montant_ttc" Pos="5" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_END>
<RELATION_END ID="1500" />
</RELATIONS_END>
<INDICES>
<INDEX ID="1431" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1617" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1398" Tablename="gestion_frais_km_taux" PrevTableName="gestion_frais_kilometrique" XPos="1027" YPos="245" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="6" >
<COLUMNS>
<COLUMN ID="1432" ColName="gfkt_id_frais_km_taux" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1433" ColName="gfkt_taux" PrevColName="" Pos="2" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_START>
<RELATION_START ID="1505" />
</RELATIONS_START>
<INDICES>
<INDEX ID="1434" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1432" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1399" Tablename="gestion_absence_motif" PrevTableName="gestion_motif_absence" XPos="44" YPos="521" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="7" >
<COLUMNS>
<COLUMN ID="1435" ColName="gam_id_absence_motif" PrevColName="" Pos="1" idDatatype="1" DatatypeParams="(3)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="1" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1436" ColName="gam_libelle" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="Libell\195\169 du motif d\aabscence.">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1770" ColName="gam_mark_cp_diminuer" PrevColName="gam_cp_diminuer" Pos="2" idDatatype="22" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="Indique si ce motif diminue le nombre d\aheur de cong\195\169s pay\195\169s.">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1772" ColName="gam_mark_hs_diminuer" PrevColName="gam_hs_diminuer" Pos="4" idDatatype="22" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="Indique si ce motif diminue le nombre d\aheures supl\195\169mentaires.">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_START>
<RELATION_START ID="1583" />
</RELATIONS_START>
<INDICES>
<INDEX ID="1438" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1435" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1402" Tablename="gestion_utilisateur_a_projet" PrevTableName="gestion_preferences" XPos="384" YPos="357" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="10" >
<COLUMNS>
<COLUMN ID="1631" ColName="guap_id_utilisateur" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1632" ColName="guap_id_projet" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="-1" Prec="-1" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_END>
<RELATION_END ID="1494" />
<RELATION_END ID="1498" />
</RELATIONS_END>
<INDICES>
<INDEX ID="1447" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1631" LengthParam="0" />
<INDEXCOLUMN idColumn="1632" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1404" Tablename="gestion_projet" PrevTableName="" XPos="44" YPos="195" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="12" >
<COLUMNS>
<COLUMN ID="1522" ColName="gp_id_projet" PrevColName="" Pos="6" idDatatype="5" DatatypeParams="(11)" Width="-1" Prec="-1" PrimaryKey="1" NotNull="1" AutoInc="1" IsForeignKey="0" DefaultValue="" Comments="Identifiant du projet.">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1766" ColName="gp_ce_projet_parent" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="-1" Prec="-1" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1629" ColName="gp_ce_categorie" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="Identifiant de la cat\195\169gorie du projet.">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1455" ColName="gp_nom" PrevColName="gp_nom_projet" Pos="3" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="Nom du projet.">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1456" ColName="gp_description" PrevColName="" Pos="4" idDatatype="28" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="Description d\195\169taill\195\169e du projet.">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1457" ColName="gp_date_debut" PrevColName="" Pos="5" idDatatype="14" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0000-00-00" Comments="Date de d\195\169but du projet">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1768" ColName="gp_date_fin" PrevColName="" Pos="8" idDatatype="14" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0000-00-00" Comments="Date de fin du projet estim\195\169e.">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1458" ColName="gp_duree_prevue" PrevColName="" Pos="6" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="Dur\195\169e pr\195\169vue du projet en jour.">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1787" ColName="gp_duree_finance" PrevColName="" Pos="9" idDatatype="7" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="Dur\195\169e en jour financ\195\169 pour le projet.">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1459" ColName="gp_avancement" PrevColName="" Pos="7" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="Pourcentage d\aavancement du projet.">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_START>
<RELATION_START ID="1498" />
<RELATION_START ID="1511" />
<RELATION_START ID="1764" />
</RELATIONS_START>
<RELATIONS_END>
<RELATION_END ID="1564" />
<RELATION_END ID="1764" />
</RELATIONS_END>
<INDICES>
<INDEX ID="1625" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1522" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1405" Tablename="gestion_utilisateur_statut" PrevTableName="gestion_statut" XPos="673" YPos="234" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="13" >
<COLUMNS>
<COLUMN ID="1461" ColName="gus_id_utilisateur_statut" PrevColName="" Pos="1" idDatatype="1" DatatypeParams="(3)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="1" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1462" ColName="gus_libelle" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1776" ColName="gus_mark_recapitulatif" PrevColName="" Pos="2" idDatatype="22" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="1" Comments="Indique si ce type d\autilisateur doit appara\195\174tre dans le r\195\169capitulatif ou pas.">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_START>
<RELATION_START ID="1592" />
</RELATIONS_START>
<INDICES>
<INDEX ID="1463" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1461" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1407" Tablename="gestion_travail_projet" PrevTableName="gestion_travail" XPos="394" YPos="473" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="15" >
<COLUMNS>
<COLUMN ID="1742" ColName="gtp_id_utilisateur" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1743" ColName="gtp_id_projet" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="-1" Prec="-1" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1474" ColName="gtp_id_date_travail" PrevColName="" Pos="3" idDatatype="14" DatatypeParams="" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="0000-00-00" Comments="">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1475" ColName="gtp_duree" PrevColName="" Pos="4" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_END>
<RELATION_END ID="1510" />
<RELATION_END ID="1511" />
</RELATIONS_END>
<INDICES>
<INDEX ID="1476" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1742" LengthParam="0" />
<INDEXCOLUMN idColumn="1743" LengthParam="0" />
<INDEXCOLUMN idColumn="1474" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1408" Tablename="gestion_utilisateur" PrevTableName="" XPos="686" YPos="365" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="16" >
<COLUMNS>
<COLUMN ID="1477" ColName="gu_id_utilisateur" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="1" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1763" ColName="gu_ce_statut" PrevColName="" Pos="1" idDatatype="1" DatatypeParams="(3)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1479" ColName="gu_nom" PrevColName="" Pos="3" idDatatype="20" DatatypeParams="(100)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1480" ColName="gu_prenom" PrevColName="" Pos="4" idDatatype="20" DatatypeParams="(100)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1481" ColName="gu_password" PrevColName="" Pos="5" idDatatype="20" DatatypeParams="(32)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1482" ColName="gu_email" PrevColName="" Pos="6" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1483" ColName="gu_telephone" PrevColName="" Pos="7" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1484" ColName="gu_adresse" PrevColName="" Pos="8" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1485" ColName="gu_code_postal" PrevColName="" Pos="9" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1486" ColName="gu_ville" PrevColName="" Pos="10" idDatatype="20" DatatypeParams="(50)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1487" ColName="gu_quota_heures_supp" PrevColName="" Pos="11" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1488" ColName="gu_conges_payes" PrevColName="" Pos="12" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1489" ColName="gu_temps_de_travail_jour" PrevColName="gu_temps_de_travail" Pos="13" idDatatype="7" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1789" ColName="gu_temps_de_travail_mois" PrevColName="" Pos="23" idDatatype="7" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1779" ColName="gu_tdt_lundi" PrevColName="" Pos="16" idDatatype="7" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1780" ColName="gu_tdt_mardi" PrevColName="" Pos="17" idDatatype="7" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1781" ColName="gu_tdt_mercredi" PrevColName="" Pos="18" idDatatype="7" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1782" ColName="gu_tdt_jeudi" PrevColName="" Pos="19" idDatatype="7" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1783" ColName="gu_tdt_vendredi" PrevColName="" Pos="20" idDatatype="7" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1784" ColName="gu_tdt_samedi" PrevColName="" Pos="21" idDatatype="7" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1785" ColName="gu_tdt_dimanche" PrevColName="" Pos="22" idDatatype="7" DatatypeParams="" Width="-1" Prec="-1" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="0" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1490" ColName="gu_mark_admin" PrevColName="" Pos="14" idDatatype="22" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1491" ColName="gu_mark_recapitulatif" PrevColName="" Pos="15" idDatatype="22" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1492" ColName="gu_notes" PrevColName="" Pos="16" idDatatype="28" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_START>
<RELATION_START ID="1494" />
<RELATION_START ID="1503" />
<RELATION_START ID="1510" />
<RELATION_START ID="1585" />
<RELATION_START ID="1612" />
</RELATIONS_START>
<RELATIONS_END>
<RELATION_END ID="1592" />
</RELATIONS_END>
<INDICES>
<INDEX ID="1493" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1477" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
<TABLE ID="1400" Tablename="gestion_note_frais" PrevTableName="" XPos="1030" YPos="525" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="8" >
<COLUMNS>
<COLUMN ID="1439" ColName="gnf_id_note_frais" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1614" ColName="gnf_ce_utilisateur" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="1" />
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
<COLUMN ID="1440" ColName="gnf_libelle" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
<OPTIONSELECTED>
<OPTIONSELECT Value="0" />
</OPTIONSELECTED>
</COLUMN>
</COLUMNS>
<RELATIONS_START>
<RELATION_START ID="1500" />
</RELATIONS_START>
<RELATIONS_END>
<RELATION_END ID="1612" />
</RELATIONS_END>
<INDICES>
<INDEX ID="1441" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
<INDEXCOLUMNS>
<INDEXCOLUMN idColumn="1439" LengthParam="0" />
</INDEXCOLUMNS>
</INDEX>
</INDICES>
</TABLE>
</TABLES>
<RELATIONS>
<RELATION ID="1494" RelationName="fk_gu_guap" Kind="1" SrcTable="1408" DestTable="1402" FKFields="gu_id_utilisateur=guap_id_utilisateur\n" FKFieldsComments="\n" relDirection="4" MidOffset="-13" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="48" CaptionOffsetY="-33" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="17" />
<RELATION ID="1498" RelationName="fk_gp_guap" Kind="1" SrcTable="1404" DestTable="1402" FKFields="gp_id_projet=guap_id_projet\n" FKFieldsComments="\n" relDirection="2" MidOffset="19" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="-53" CaptionOffsetY="-24" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="18" />
<RELATION ID="1503" RelationName="fk_gu_gfk" Kind="2" SrcTable="1408" DestTable="1396" FKFields="gu_id_utilisateur=gfk_ce_utilisateur\n" FKFieldsComments="\n" relDirection="2" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="0" CaptionOffsetY="0" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="22" />
<RELATION ID="1505" RelationName="fk_gfkt_gfk" Kind="2" SrcTable="1398" DestTable="1396" FKFields="gfkt_id_frais_km_taux=gfkt_id_frais_km_taux\n" FKFieldsComments="\n" relDirection="3" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="-59" CaptionOffsetY="-22" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="23" />
<RELATION ID="1510" RelationName="fk_gu_gtp" Kind="1" SrcTable="1408" DestTable="1407" FKFields="gu_id_utilisateur=gtp_id_utilisateur\n" FKFieldsComments="\n" relDirection="4" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="-1" CaptionOffsetY="-46" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="26" />
<RELATION ID="1511" RelationName="fk_gp_gtp" Kind="1" SrcTable="1404" DestTable="1407" FKFields="gp_id_projet=gtp_id_projet\n" FKFieldsComments="\n" relDirection="2" MidOffset="-12" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="48" CaptionOffsetY="-23" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="27" />
<RELATION ID="1564" RelationName="fk_gpc_gp" Kind="5" SrcTable="1395" DestTable="1404" FKFields="gpc_id_categorie=gp_ce_categorie\n" FKFieldsComments="\n" relDirection="3" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="-47" CaptionOffsetY="-22" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="32" />
<RELATION ID="1583" RelationName="fk_gam_ga" Kind="1" SrcTable="1399" DestTable="1394" FKFields="gam_id_absence_motif=ga_id_absence_motif\n" FKFieldsComments="\n" relDirection="2" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="-47" CaptionOffsetY="-22" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="31" />
<RELATION ID="1585" RelationName="fk_gu_ga" Kind="1" SrcTable="1408" DestTable="1394" FKFields="gu_id_utilisateur=ga_id_utilisateur\n" FKFieldsComments="\n" relDirection="4" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="-45" CaptionOffsetY="-22" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="32" />
<RELATION ID="1592" RelationName="fk_gs_gu" Kind="2" SrcTable="1405" DestTable="1408" FKFields="gus_id_utilisateur_statut=gu_ce_statut\n" FKFieldsComments="\n" relDirection="3" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="-41" CaptionOffsetY="-24" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="32" />
<RELATION ID="1500" RelationName="fk_gnf_gnfl" Kind="5" SrcTable="1400" DestTable="1397" FKFields="gnf_id_note_frais=gnfl_ce_note_frais\n" FKFieldsComments="\n" relDirection="3" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="-48" CaptionOffsetY="-25" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="20" />
<RELATION ID="1612" RelationName="fk_gu_gnf" Kind="2" SrcTable="1408" DestTable="1400" FKFields="gu_id_utilisateur=gnf_ce_utilisateur\n" FKFieldsComments="\n" relDirection="2" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="0" CaptionOffsetY="0" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="32" />
<RELATION ID="1764" RelationName="fk_gp_gp_parent" Kind="2" SrcTable="1404" DestTable="1404" FKFields="gp_id_projet=gp_ce_projet_parent\n" FKFieldsComments="\n" relDirection="2" MidOffset="23" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="-71" CaptionOffsetY="-23" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="26" />
</RELATIONS>
<NOTES>
</NOTES>
<IMAGES>
</IMAGES>
</METADATA>
<PLUGINDATA>
<PLUGINDATARECORDS>
</PLUGINDATARECORDS>
</PLUGINDATA>
<QUERYDATA>
<QUERYRECORDS>
</QUERYRECORDS>
</QUERYDATA>
<LINKEDMODELS>
</LINKEDMODELS>
</DBMODEL>
/tags/v1.0-Homere/config.inc.defaut.php
New file
0,0 → 1,10
<?php
// Base de données
define('GTT_BDD_NOM', 'gtt_v4');
define('GTT_BDD_DSN', 'mysql://utilsiateur:mot_de_passe@localhost/'.GTT_BDD_NOM);
// Débogage
/** Constante stockant si oui ou non on veut afficher le débogage.*/
define('GTT_DEBOGAGE', false);
/** Constante stockant si oui ou non on veut afficher les requêtes SQL.*/
define('GTT_DEBOGAGE_SQL', false);
?>
/tags/v1.0-Homere/presentation/calendrier_mini.tpl.html
New file
0,0 → 1,30
<div id="calendrier_mini" class="calendrier">
<h2>Calendrier</h2>
<table>
<caption><a href="<?=$url_mois_precedent;?>">&lt;&lt;</a> <?=$mois['mois'];?>
<?=$mois['annee'];?> <a href="<?=$url_mois_suivant;?>">&gt;&gt;</a></caption>
<thead>
<tr>
<th>Lun</th>
<th>Mar</th>
<th>Mer</th>
<th>Jeu</th>
<th>Ven</th>
<th>Sam</th>
<th>Dim</th>
</tr>
</thead>
<tbody>
<?php foreach ($elements as $semaine) : ?>
<tr>
<?php foreach ($semaine as $jour) : ?>
<td class="<?=$jour['class'];?>"> <? if ($jour['class'] == 'jour_vide') :?>
<?=$jour['jour'];?> <? else :?> <a href="<?=$jour['url'];?>"><?=$jour['jour'];?></a>
<? endif;?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<hr/>
</div>
/tags/v1.0-Homere/presentation/admin_utilisateur_statut.tpl.html
New file
0,0 → 1,34
<?php if (isset($message)) : ?>
<p class="information"><?=$message;?></p>
<?php endif; ?>
<form id="admin_us_supprimer" class="editer" name="admin_us_supprimer" action="http://localhost/gestion/index.php?action=admin-utilisateur-statut_valider-supprimer" method="post">
<fieldset>
<legend>Supprimer un statut d'utilisateur</legend>
<ul>
<li>
<label for="ussu_id">Statut d'utilisateur :</label>
<select id="ussu_id" name="ussu_id">
<?php foreach ($statuts as $statut) : ?>
<option value="<?=$statut['id'];?>"><?=$statut['libelle'];?></option>
<?php endforeach; ?>
</select>
</li>
<li><input id="btn_us_supprimer" name="btn_us_supprimer" value="Supprimer" type="submit" onclick="javascript:return confirm('Êtes vous sûr de vouloir supprimer cet statut d\'utilisateur ?');" /></li>
</ul>
</fieldset>
</form>
<form id="admin_us_ajouter" name="admin_us_ajouter" action="http://localhost/gestion/index.php?action=admin-utilisateur-statut_valider-ajouter" method="post">
<fieldset>
<legend>Ajouter un statut d'utilisateur</legend>
<ul>
<li>
<label for="usaj_libelle">Libelle :</label>
<input size="30" id="usaj_libelle" name="usaj_libelle" type="text" />
<span class="symbole_obligatoire">*</span>
</li>
<li>
<input size="5" id="btn_us_ajouter" name="btn_us_ajouter" value="Ajouter" type="submit" /></li>
<li><span class="symbole_obligatoire">*</span> =champs obligatoires</li>
</ul>
</fieldset>
</form>
/tags/v1.0-Homere/presentation/scripts/commun.js
New file
0,0 → 1,27
// Fonction déclanchant l'ouverture d'une fenêtre externe pour les liens possédant la classe "ext"
function ouvrirLienExterne()
{
var liens = document.getElementsByTagName('a');
// On récupère tous les liens (<a>) du document dans une variable (un array), ici liens.
// Une boucle qui parcourt le tableau (array) liens du début à la fin.
for (var i = 0 ; i < liens.length ; ++i) {
// Si les liens ont un nom de class égal à  lien_ext, alors on agit.
if (liens[i].className == 'ext') {
liens[i].title = liens[i].title + 'S\'ouvre dans une nouvelle fenêtre';
// Au clique de la souris.
liens[i].onclick = function() {
window.open(this.href);
return false; // On ouvre une nouvelle page ayant pour URL le href du lien cliqué et on inhibe le lien réel.
};
}
}
}
// Fonction initialisant d'autres fonctions
function initialiser()
{
ouvrirLienExterne();
}
 
// Au chargement de la page, on appelle la fonction d'initialisation :
window.onload = initialiser;
/tags/v1.0-Homere/presentation/stat_tableau_global.tpl.html
New file
0,0 → 1,81
<div id="navigation">
<p>Navigation : <a href="<?=$url_mois_precedent;?>">&lt;&lt;</a> <?=$mois['mois'];?> <?=$mois['annee'];?> <a href="<?=$url_mois_suivant;?>">&gt;&gt;</a></p>
</div>
<div id="export">
<p><a href="<?=$url_mois_courant;?>&amp;format=csv">Affichage au format CSV</a> - <a href="<?=$url_mois_courant;?>&amp;format=csv&amp;sortie=csvt">Export au format CSV</a></p>
</div>
<?php if ($categories || $absences) : ?>
<table id="tab_tps_w_mensuel_salarie" summary="Tableau du temps de travail mensuel par salarié.">
<caption>Tableaux global - <?=$mois['mois'];?> <?=$mois['annee'];?></caption>
<thead>
<tr>
<th>Projets</th>
<?php foreach ($utilisateurs as $utilisateur) : ?>
<th><?=$utilisateur['prenom_nom']?></th>
<?php endforeach; ?>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php $ligne = "impair"; ?>
<?php if ($categories) : ?>
<tr class="total">
<th>Travail</th>
<?php foreach ($utilisateurs as $utilisateur) : ?>
<td><?=(isset($utilisateur['total_w'])) ? $utilisateur['total_w'] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?=$total_projets;?></td>
</tr>
<?foreach ($categories as $idc => $categorie):?>
<tr class="categories">
<th class="categories_titre"><?=$categorie['nom'];?> [<?=$categorie['abreviation'];?>]</th>
<?php foreach ($utilisateurs as $utilisateur) : ?>
<td class="categories_total"><?=(isset($utilisateur['projets'][$idc]['total'])) ? $utilisateur['projets'][$idc]['total'] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?=$categorie['total'];?></td>
</tr>
<?foreach ($categorie['projets'] as $idp => $projet):?>
<tr class="utilisateur <?=$ligne ; $ligne = ($ligne == "impair") ? "pair" : "impair" ;?>">
<th id="pr:<?=$idp;?>" title="<?=$projet['desc'];?>"><?=$projet['nom'];?></th>
<?php foreach ($utilisateurs as $utilisateur) : ?>
<td class="projet"><?=(isset($utilisateur['projets'][$idc][$idp])) ? $utilisateur['projets'][$idc][$idp]['duree'] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?=$projet['total'];?></td>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($absences) : ?>
<tr class="total">
<th class="absences_titre">Absences</th>
<?php foreach ($utilisateurs as $utilisateur) : ?>
<td><?=$utilisateur['total_a'];?></td>
<?php endforeach; ?>
<td class="total"><?=$total_absences;?></td>
</tr>
<?php foreach ($absences as $ida => $absence) : ?>
<tr class="utilisateur <?=$ligne ; $ligne = ($ligne == "impair") ? "pair" : "impair" ;?>">
<th id="ab:<?=$ida;?>" class="absence_nom"><?=$absence['nom'];?></th>
<?php foreach ($utilisateurs as $utilisateur) : ?>
<td class="absence"><?= (isset($utilisateur['ab'][$ida])) ? $utilisateur['ab'][$ida] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?= (isset($absence['total'])) ? $absence['total'] : "&nbsp;";?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<tr class="total">
<th>Total</th>
<?php foreach ($utilisateurs as $utilisateur) : ?>
<td><?=(isset($utilisateur['total'])) ? $utilisateur['total'] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?=$total_absences_projets;?></td>
</tr>
</tbody>
</table>
<?php endif; ?>
 
<?php if (isset($messages)) : ?>
<?php foreach ($messages as $message) : ?>
<p class="information"><?=$message;?></p>
<?php endforeach; ?>
<?php endif; ?>
/tags/v1.0-Homere/presentation/connexion.tpl.html
New file
0,0 → 1,19
<form action="<?=$url;?>" method="post" name="login" id="login">
<fieldset>
<legend>Identifiez vous</legend>
<table id="connexion">
<caption>Identification</caption>
<tr>
<th>Courriel</th>
<td><input name="username" type="text" /></td>
</tr>
<tr>
<th>Mot de passe</th>
<td><input name="password" type="password" /></td>
</tr>
<tr>
<td colspan="2"><input name="btn_submit" value="OK" type="submit" /></td>
</tr>
</table>
</fieldset>
</form>
/tags/v1.0-Homere/presentation/preferences.tpl.html
New file
0,0 → 1,61
<?php if (isset($messages)) : ?>
<?php foreach ($messages as $message) : ?>
<p class="information"><?=$message;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($preferences) : ?>
<div id="preferences">
<form class="centre" id="gestion_admin_pref" action="index.php?action=<?=GTT_ACTION_PREFERENCE_VALIDER;?>" name="gestion_admin_pref" method="post">
<input name="champ_nb_total_proj" value="<?=$nbre_projets;?>" type="hidden"/>
<table id="preference">
<thead>
<tr>
<th>&nbsp;</th>
<th>Nom</th>
<th>Description</th>
<th>Date début</th>
<th>Date fin</th>
<th>Durée prévue</th>
<th>Durée financée</th>
<th>Avancement (%)</th>
</tr>
</thead>
<tbody>
<?foreach ($preferences as $categorie => $projets):?>
<tr class="categories"><th colspan="8"><?=$categorie;?></th></tr>
<?php $ligne = "impair"; ?>
<?foreach ($projets as $projet):?>
<tr class="<?=$ligne ; $ligne = ($ligne == "impair") ? "pair" : "impair" ;?>">
<td class="check"><input id="pr:<?=$projet['id'];?>" name="pr:<?=$projet['id'];?>" value="<?=$projet['valeur'];?>" type="checkbox" <?=$projet['coche']?'checked="checked"':'';?>/></td>
<td class="pr_no"><?=$projet['no'];?></td>
<td class="pr_de"><?=$projet['de'];?></td>
<td class="pr_dade"><?=($projet['dade'] != '0000-00-00') ? $projet['dade'] : '&nbsp;' ;?></td>
<td class="pr_dafi"><?=($projet['dafi'] != '0000-00-00') ? $projet['dafi'] : '&nbsp;' ;?></td>
<td class="pr_dupr"><?=(!empty($projet['dupr'])) ? $projet['dupr'] : '&nbsp;' ;?></td>
<td class="pr_dufi"><?=(!empty($projet['dufi'])) ? $projet['dufi'] : '&nbsp;' ;?></td>
<td class="pr_av">
<?php if (!empty($projet['av'])) : ?>
<img height="10"
width="<?=$projet['av'];?>"
title="<?=$projet['av'];?> %"
src="presentation/images/pixels/avancement.png"
style="cursor:crosshair;padding-right:<?=(100 - $projet['av']);?>px;border:1px solid #DDD;"
alt="<?=$projet['av'];?> %" />
<?php else : ?>
<img height="10"
width="100"
style="cursor:crosshair;border:1px solid #DDD;"
src="presentation/images/pixels/vide.png"
title="<?=$projet['av'];?> %"
alt="0 %" />
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
</tbody>
</table>
<input class="btn_large" id="btn_valider_editer" name="btn_valider_editer" value="<?=$i18n_general_valider;?>" type="submit" />
</form>
</div>
<?php endif; ?>
/tags/v1.0-Homere/presentation/images/icones/lien_externe.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/presentation/images/icones/lien_externe.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/presentation/images/pixels/vide.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/presentation/images/pixels/vide.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/presentation/images/pixels/avancement.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/presentation/images/pixels/avancement.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/presentation/images/favicones/gtt.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/presentation/images/favicones/gtt.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/presentation/images/favicones/gtt.ico
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/presentation/images/favicones/gtt.ico
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/presentation/menu.tpl.html
New file
0,0 → 1,21
<h2>Menu</h2>
<h3>Général</h3>
<ul>
<li><a href="index.php?action=gestion">Gestion de mon temps</a></li>
<li><a href="index.php?action=preferences">Gestion de mes projets</a></li>
</ul>
<h3>Statistiques</h3>
<ul>
<li><a href="index.php?action=stat-tableau-global">Tableau général</a></li>
<li><a href="index.php?action=stat-tableau-charge">Plan de charge</a></li>
</ul>
<?php if ($bool_admin) : ?>
<h3>Administration</h3>
<ul>
<li><a href="index.php?action=admin-projet">Projets</a></li>
<li><a href="index.php?action=admin-categorie" title="Modifier, supprimer et ajouter des catégories pour les projets">Categories des projets</a></li>
<li><a href="index.php?action=admin-absence-motif">Motifs des absences</a></li>
<li><a href="index.php?action=admin-utilisateur-statut">Statuts des utilisateurs</a></li>
<li><a href="index.php?action=admin-utilisateur">Utilisateurs</a></li>
</ul>
<?php endif; ?>
/tags/v1.0-Homere/presentation/identite.tpl.html
New file
0,0 → 1,17
<div id="identite">
<h2>Votre identité</h2>
<dl class="ajout_2_points">
<dt>Prénom</dt>
<dd><?=$prenom;?></dd>
<dt>Nom</dt>
<dd><?=$nom;?></dd>
<dt title="Vous devez travailler le nombre d'heure indiqué chaque jour">Temps travail</dt>
<dd><?=$tps_w;?> h. par j.</dd>
<dt title="Nombre de congés payés vous restant à prendre">CP restants</dt>
<dd><?=$cp;?> h. (&asymp; <?=$cp_j;?> j.)</dd>
<dt title="Nombre d'heures supplémentaires accumulées">Heures sup.</dt>
<dd><?=$rtt;?> h. (&asymp; <?=$rtt_j;?> j.)</dd>
</dl>
<p><a href="index.php?action=identification_deconnexion">Déconnexion</a></p>
<hr/>
</div>
/tags/v1.0-Homere/presentation/admin_absence_motif.tpl.html
New file
0,0 → 1,50
<?php if (isset($messages)) : ?>
<?php foreach ($messages as $message) : ?>
<p class="information"><?=$message;?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php if (isset($motifs)) : ?>
<form id="admin_absence_motif_editer" class="editer" name="admin_absence_motif_editer" action="index.php?action=admin-absence-motif_editer" method="post">
<fieldset>
<legend>Éditer un motif d'absence</legend>
<ul>
<li>
<label for="amsu_id">Motif d'absence :</label>
<select id="amsu_id" name="amsu_id">
<?php foreach ($motifs as $motif) : ?>
<option value="<?=$motif['id'];?>"><?=$motif['libelle'];?></option>
<?php endforeach; ?>
</select>
</li>
<li><input id="btn_absence_motif_supprimer" name="btn_absence_motif_supprimer" value="Supprimer" type="submit" onclick="javascript:return confirm('Êtes vous sûr de vouloir supprimer ce motif d\'abscence ?');"/></li>
<li><input id="btn_absence_motif_modifier" name="btn_absence_motif_modifier" value="Modifier" type="submit" /></li>
</ul>
</fieldset>
</form>
<?php endif; ?>
<form id="admin_absence_motif_ajouter" name="admin_absence_motif_ajouter" action="<?=$form_url;?>" method="post">
<fieldset>
<legend><?=$form_legend;?></legend>
<ul>
<li>
<label for="amaj_libelle">Libellé :</label>
<input size="30" id="amaj_libelle" name="amaj_libelle" type="text" value="<?=$AbsenceMotif->getLibelle();?>"/>
<span class="symbole_obligatoire">*</span>
</li>
<li>
<label for="amaj_mark_cp_diminuer">Diminue le nombre de congés payés :</label>
<input id="amaj_mark_cp_diminuer" name="amaj_mark_cp_diminuer" type="checkbox" value="1" <?=($AbsenceMotif->getMarkCpDiminuer())?'checked="checked"':'';?>/>
</li>
<li>
<label for="amaj_mark_hs_diminuer">Diminue le nombre d'heures suplémentaires :</label>
<input id="amaj_mark_hs_diminuer" name="amaj_mark_hs_diminuer" type="checkbox" value="1" <?=($AbsenceMotif->getMarkHsDiminuer())?'checked="checked"':'';?>/>
</li>
<li>
<input name="amaj_id_absence_motif" type="hidden" value="<?=$AbsenceMotif->getIdAbsenceMotif();?>"/>
<input id="<?=$form_bouton_id;?>" name="<?=$form_bouton_id;?>" value="<?=$form_bouton_value;?>" type="submit" />
<input id="btn_utilisateur_annuler" name="btn_utilisateur_annuler" value="Annuler" type="submit" />
</li>
<li><span class="symbole_obligatoire">*</span> =champs obligatoires</li>
</ul>
</fieldset>
</form>
/tags/v1.0-Homere/presentation/gestion.tpl.html
New file
0,0 → 1,71
<div id="info">
<p id="info_aujourdhui">Aujourd'hui, nous sommes le <a href="<?=$jc_url;?>"><?=$jc['jour'];?> <?=$jc['mois_nom'];?> <?=$jc['annee'];?></a></p>
<p id="info_semaine">Semaine du <a href="<?=$jc_url;?>"><?=$sjc_1['jour'];?> <?=$sjc_1['mois'];?> <?=$sjc_1['annee'];?> au <?=$sjc_7['jour'];?> <?=$sjc_7['mois'];?> <?=$sjc_7['annee'];?></a></p>
</div>
<div id="calendrier_gestion" class="calendrier">
<?php if ($bool_projets) : ?>
<form class="centre" id="gestion" name="gestion" action="<?=$url_gestion_valider;?>" method="post">
<table id="tab_gestion">
<caption>
<a href="<?=$url_semaine_precedente;?>">&lt;&lt;</a>
<?=$sj_1['jour'];?> <?=$sj_1['mois'];?> <?=$sj_1['annee'];?> au <?=$sj_7['jour'];?> <?=$sj_7['mois'];?> <?=$sj_7['annee'];?>
<a href="<?=$url_semaine_suivante;?>">&gt;&gt;</a>
</caption>
<thead>
<tr>
<th>Projets</th>
<?php foreach ($elements[$s] as $jour) : ?>
<th class="<?=$jour['class'];?>">
<?=$jour['jour_nom'];?> <?=$jour['jour'];?>
</th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php if ($bool_projets) : ?>
<?foreach ($preferences as $categorie => $projets):?>
<tr>
<td class="categorie"><?=$categorie;?></td>
<?php foreach ($elements[$s] as $num => $jour) : ?>
<td class="categorie_total"><?=$categorie_totaux[$categorie][$num];?></td>
<?php endforeach; ?>
</tr>
<?foreach ($projets as $projet):?>
<tr>
<td class="projet" title="<?=$projet['desc'];?>"><?=$projet['nom'];?></td>
<?php foreach ($elements[$s] as $num => $jour) : ?>
<td class="<?=$jour['class'];?>"><input id="pr:<?=$projet['id'];?>:<?=$num;?>" name="pr:<?=$projet['id'];?>:<?=$num;?>" value="<?=$projet['date'][$num];?>" type="text"/></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
<? endif;?>
<tr>
<td class="categorie">Absences</td>
<?php foreach ($elements[$s] as $num => $jour) : ?>
<td class="categorie_total"><?=$ab_total[$num];?></td>
<?php endforeach; ?>
</tr>
<?php foreach ($ab as $ab_id => $tab_ab_jours) : ?>
<tr>
<td class="absence_titre"><?=$ab_libelle[$ab_id];?></td>
<?php foreach ($elements[$s] as $num => $jour) : ?>
<td class="ab <?=$jour['class'];?>"><input id="ab:<?=$ab_id;?>:<?=$num;?>" name="ab:<?=$ab_id;?>:<?=$num;?>" value="<?=$tab_ab_jours[$num];?>" type="text"/></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<tr>
<td class="totaux_titre">Totaux journée</td>
<?php foreach ($elements[$s] as $num => $jour) : ?>
<td class="totaux"><?=$totaux[$num];?></td>
<?php endforeach; ?>
</tr>
</tbody>
</table>
<input class="btn_large" id="btn_valider" name="btn_valider" value="<?=$i18n_general_valider;?>" type="submit" />
</form>
<?php else : ?>
<p class="information">Veuillez sélectionner des projets via le menu "Gestion de mes projets".</p>
<? endif;?>
</div>
/tags/v1.0-Homere/presentation/stat_tableau_charge.tpl.csv
New file
0,0 → 1,22
<?php if (isset($projets) || isset($absences)) : ?>
Projets <?php foreach ($elements as $jour) : ?><?=$jour['jour_nom']?> <?=$jour['jour']?> <?php endforeach; ?>Total
<?php if (isset($projets)) : ?>
Travail <?php foreach ($elements as $jour) : ?><?=(!empty($jour['travail'])) ? $jour['travail'] : ' ';?> <?php endforeach; ?><?=$total_w;?>
<?foreach ($projets as $categorie => $pr):?>
 
<?=$categorie;?> [<?=$categories[$categorie]['abreviation'];?>] <?php foreach ($elements as $jour_id => $jour) : ?><?=(isset($categories[$categorie][$jour_id])) ? $categories[$categorie][$jour_id] : ' ';?> <?php endforeach; ?><?=$categories[$categorie]['total'];?>
 
<?foreach ($pr as $id => $projet):?>
<?=$projet['nom'];?> <?php foreach ($elements as $jour_id => $jour) : ?><?=(isset($projet['duree'][$jour_id])) ? $projet['duree'][$jour_id] : ' ';?> <?php endforeach; ?><?=(isset($projet['total'])) ? $projet['total'] : ' ';?>
 
<?php endforeach; ?><?php endforeach; ?><?php endif; ?>
 
<?php if (isset($absences)) : ?>
Absences <?php foreach ($elements as $jour) : ?><?=(!empty($jour['absence'])) ? $jour['absence'] : ' ';?> <?php endforeach; ?><?=$total_a;?>
 
<?php foreach ($absences as $ab_id => $absence) : ?>
<?=$absence['nom'];?> <?php foreach ($elements as $jour_id => $jour) : ?><?= (isset($ab[$ab_id][$jour_id])) ? $ab[$ab_id][$jour_id] : ' ';?> <?php endforeach; ?><?=(!empty($absence['total'])) ? $absence['total'] : '' ;?>
 
<?php endforeach; ?><?php endif; ?>
Total <?php foreach ($elements as $jour) : ?><?=(!empty($jour['w_et_a'])) ? $jour['w_et_a'] : ' ';?> <?php endforeach; ?><?=$total;?>
<?php endif; ?>
/tags/v1.0-Homere/presentation/admin_categorie.tpl.html
New file
0,0 → 1,43
<?php if (isset($message)) : ?>
<p class="information"><?=$message;?></p>
<?php endif; ?>
<?php if ($categories) : ?>
<form id="admin_categorie_editer" class="editer" name="admin_categorie_editer" action="index.php?action=admin-categorie_editer" method="post">
<fieldset>
<legend>Éditer une catégorie</legend>
<ul>
<li>
<label for="casu_id">Catégorie :</label>
<select id="casu_id" name="casu_id">
<?php foreach ($categories as $categorie) : ?>
<option value="<?=$categorie['id'];?>"><?=$categorie['libelle'];?></option>
<?php endforeach; ?>
</select>
</li>
<li><input id="btn_categorie_modifier" name="btn_categorie_modifier" value="Modifier" type="submit" /></li>
<li><input id="btn_categorie_supprimer" name="btn_categorie_supprimer" value="Supprimer" type="submit" onclick="javascript:return confirm('Êtes vous sûr de vouloir supprimer cette catégorie ?');" /></li>
</ul>
</fieldset>
</form>
<?php endif; ?>
<form id="admin_categorie_ajouter" name="admin_categorie_ajouter" action="<?=$form_url;?>" method="post">
<fieldset>
<legend><?=$form_legend;?></legend>
<ul>
<li>
<label for="caaj_libelle">Libelle :</label>
<input size="30" id="caaj_libelle" name="caaj_libelle" type="text" value="<?=$ProjetCategorie->getLibelle();?>"/>
<span class="symbole_obligatoire">*</span>
</li>
<li>
<label for="caaj_abreviation">Abréviation :</label>
<input size="25" maxlength="25" id="caaj_abreviation" name="caaj_abreviation" type="text" value="<?=$ProjetCategorie->getAbreviation();?>"/>
</li>
<li>
<input name="caaj_id_categorie" type="hidden" value="<?=$ProjetCategorie->getIdCategorie();?>"/>
<input id="<?=$form_bouton_id;?>" name="<?=$form_bouton_id;?>" value="<?=$form_bouton_value;?>" type="submit" />
<input id="btn_categorie_annuler" name="btn_categorie_annuler" value="Annuler" type="submit" />
<li><span class="symbole_obligatoire">*</span> =champs obligatoires</li>
</ul>
</fieldset>
</form>
/tags/v1.0-Homere/presentation/admin_projet.tpl.html
New file
0,0 → 1,78
<?php if (isset($messages)) : ?>
<?php foreach ($messages as $message) : ?>
<p class="information"><?=$message;?></p>
<?php endforeach; ?>
<?php endif; ?>
 
<?php if ($projets) : ?>
<form id="admin_projet_editer" class="editer" name="admin_projet_editer" action="index.php?action=admin-projet_editer" method="post">
<fieldset>
<legend>Éditer un projet</legend>
<ul>
<li>
<label for="prsu_id">Projet :</label>
<select id="prsu_id" name="prsu_id">
<?php foreach ($projets as $projet) : ?>
<option value="<?=$projet['id'];?>"><?=$projet['nom'];?></option>
<?php endforeach; ?>
</select>
</li>
<li><input id="btn_projet_modifier" name="btn_projet_modifier" value="Modifier" type="submit" /></li>
<li><input id="btn_projet_supprimer" name="btn_projet_supprimer" value="Supprimer" type="submit" onclick="javascript:return confirm('Êtes vous sûr de vouloir supprimer ce projet ?');" /></li>
</ul>
</fieldset>
</form>
<?php endif; ?>
<form id="admin_projet_ajouter" name="admin_projet_ajouter" action="<?=$form_url;?>" method="post">
<fieldset>
<legend><?=$form_legend;?></legend>
<ul>
<li>
<label for="praj_nom">Nom du projet :</label>
<input size="30" id="praj_nom" name="praj_nom" type="text" value="<?=$Projet->getNom();?>"/>
<span class="symbole_obligatoire">*</span>
</li>
<li>
<label for="praj_ce_categorie">Catégorie :</label>
<?php if ($categories) : ?>
<select id="praj_ce_categorie" name="praj_ce_categorie">
<?php foreach ($categories as $Categorie) : ?>
<option value="<?=$Categorie->getIdCategorie();?>" <?=(isset($CategorieDefaut) && $CategorieDefaut->getIdCategorie() == $Categorie->getIdCategorie()) ? 'selected="selected"' : '';?>><?=$Categorie->getLibelle();?></option>
<?php endforeach; ?>
</select>
<?php else : ?>
<input size="30" id="praj_ce_categorie" name="praj_ce_categorie" type="text" disabled="disabled" value="Veuillez définir des catégories..."/>
<?php endif; ?>
</li>
<li>
<label for="praj_description">Description :</label>
<textarea rows="10" cols="50" id="praj_description" name="praj_description"><?=$Projet->getDescription();?></textarea>
</li>
<li>
<label for="praj_date_debut">Date de début :</label>
<input size="30" id="praj_date_debut" name="praj_date_debut" type="text" value="<?=$Projet->getDateDebut();?>"/>
</li>
<li>
<label for="praj_date_fin">Date de fin :</label>
<input size="30" id="praj_date_fin" name="praj_date_fin" type="text" value="<?=$Projet->getDateFin();?>"/>
</li>
<li>
<label for="praj_duree_prevue">Durée prévue (en jour) :</label>
<input size="30" id="praj_duree_prevue" name="praj_duree_prevue" type="text" value="<?=$Projet->getDureePrevue();?>"/>
</li>
<li>
<label for="praj_duree_finance">Durée financée (en jour) :</label>
<input size="30" id="praj_duree_finance" name="praj_duree_finance" type="text" value="<?=$Projet->getDureeFinance();?>"/>
</li>
<li>
<label for="praj_avancement">Avancement (en %) :</label>
<input size="10" id="praj_avancement" name="praj_avancement" type="text" value="<?=$Projet->getAvancement();?>"/>
</li>
<li>
<input name="praj_id_projet" type="hidden" value="<?=$Projet->getIdProjet();?>"/>
<input id="<?=$form_bouton_id;?>" name="<?=$form_bouton_id;?>" value="<?=$form_bouton_value;?>" type="submit" />
<input id="btn_projet_annuler" name="btn_projet_annuler" value="Annuler" type="submit" />
<li><span class="symbole_obligatoire">*</span> =champs obligatoires</li>
</ul>
</fieldset>
</form>
/tags/v1.0-Homere/presentation/stat_tableau_global.tpl.csv
New file
0,0 → 1,19
<?php if ($categories || $absences) : ?>Projets <?php foreach ($utilisateurs as $utilisateur) : ?><?=$utilisateur['prenom_nom']?> <?php endforeach; ?>Total
Travail <?php foreach ($utilisateurs as $utilisateur) : ?><?=(isset($utilisateur['total_w'])) ? $utilisateur['total_w'] : ' ';?> <?php endforeach; ?><?=$total_projets;?>
 
<?foreach ($categories as $idc => $categorie):?>
<?=$categorie['nom'];?> [<?=$categorie['abreviation'];?>] <?php foreach ($utilisateurs as $utilisateur) : ?><?=(isset($utilisateur['projets'][$idc]['total'])) ? $utilisateur['projets'][$idc]['total'] : ' ';?> <?php endforeach; ?><?=$categorie['total'];?>
 
<?foreach ($categorie['projets'] as $idp => $projet):?><?=$projet['nom'];?> <?php foreach ($utilisateurs as $utilisateur) : ?><?=(isset($utilisateur['projets'][$idc][$idp])) ? $utilisateur['projets'][$idc][$idp]['duree'] : ' ';?> <?php endforeach; ?><?=$projet['total'];?>
 
<?php endforeach; ?><?php endforeach; ?><?php endif; ?>
<?php if ($absences) : ?>
Absences <?php foreach ($utilisateurs as $utilisateur) : ?><?=$utilisateur['total_a'];?> <?php endforeach; ?><?=$total_absences;?>
 
<?php foreach ($absences as $ida => $absence) : ?>
<?=$absence['nom'];?> <?php foreach ($utilisateurs as $utilisateur) : ?><?= (isset($utilisateur['ab'][$ida])) ? $utilisateur['ab'][$ida] : ' ';?> <?php endforeach; ?><?= (isset($absence['total'])) ? $absence['total'] : ' ';?>
 
<?php endforeach; ?>
<?php endif; ?>
Total <?php foreach ($utilisateurs as $utilisateur) : ?>
<?=(isset($utilisateur['total'])) ? $utilisateur['total'] : ' ';?> <?php endforeach; ?><?=$total_absences_projets;?>
/tags/v1.0-Homere/presentation/principal.tpl.html
New file
0,0 → 1,51
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
<head>
<title><?=$titre;?></title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<!-- Feuille de styles -->
<style type="text/css" media="screen"><!-- @import "presentation/styles/disposition.css"; --></style>
<style type="text/css" media="print"><!-- @import "presentation/styles/impression.css"; --></style>
<link rel="stylesheet" type="text/css" href="presentation/styles/emeraude/emeraude.css" media="screen" title="Émeraude" />
<!-- Icone de la page -->
<link rel="shortcut icon" type="image/x-icon" href="presentation/images/favicones/gtt.ico" />
<link rel="icon" type="image/png" href="presentation/images/favicones/gtt.png" />
<!-- Fichiers Javascript-->
<script type="text/javascript" src="presentation/scripts/commun.js"></script>
</head>
<body>
<div id="zone_conteneur">
<div id="zone_entete">
<h1 id="titre_principal"><?=$titre;?></h1>
<div id="zone_accessibilite">
<a href="#zone_menu">Aller aux menus</a>
<a href="#zone_contenu">Aller au texte</a>
</div>
</div>
<div id="zone_tronc">
<div id="zone_gauche">
<div id="zone_calendrier"><?=$zone_calendrier;?></div>
<div id="zone_identification"><?=$zone_identification;?></div>
</div>
<div id="zone_centre">
<div id="zone_contenu"><?=$zone_contenu;?></div>
</div>
<div id="zone_droite">
<div id="zone_menu"><?=$zone_menu;?></div>
</div>
</div>
<div id="zone_pied">
<div id="zone_erreur">
<?php if (GTT_DEBOGAGE) : ?>
<?=$GLOBALS['_GTT_']['erreur']->retournerErreur();?>
<p><strong>Temps total d'exexution des requêtes SQL :</strong> <?=$GLOBALS['_GTT_']['chrono']->getTempsSql();?> s.</p>
<?php endif; ?>
</div>
<p>Merci, de signalez <a href="http://suivi.tela-botanica.org/index.php?project=19&amp;do=index" class="ext">les bogues et améliorations pour cette application</a>.</p>
</div>
</div>
</body>
</html>
/tags/v1.0-Homere/presentation/stat_tableau_charge.tpl.html
New file
0,0 → 1,96
<div id="navigation">
<p>Navigation : <a href="<?=$url_mois_precedent;?>">&lt;&lt;</a> <?=$mois['mois'];?> <?=$mois['annee'];?> <a href="<?=$url_mois_suivant;?>">&gt;&gt;</a></p>
<?php if ($etre_admin) : ?>
<form id="form_utilisateur" name="form_utilisateur" action="<?=$form_url;?>" method="get">
<input type="hidden" name="action" value="<?=$form_param['action'];?>"/>
<input type="hidden" name="annee" value="<?=$form_param['annee'];?>"/>
<input type="hidden" name="mois" value="<?=$form_param['mois'];?>"/>
<label for="uid">Utilisateur :</label>
<select id="uid" name="uid" onchange="javascript:this.form.submit();">
<?php foreach ($utilisateurs as $id => $utilisateur) : ?>
<option value="<?php echo $id; ?>" <?php echo ($utilisateur['courant']) ? 'selected="selected"' : ''; ?>><?php echo $utilisateur['nom']; ?></option>
<?php endforeach; ?>
</select>
<input type="submit" name="btn_envoyer_utilisateur" value="OK"/>
</form>
<?php endif; ?>
</div>
<div id="export">
<p><a href="<?=$url_mois_courant;?>&amp;format=csv">Affichage au format CSV</a> - <a href="<?=$url_mois_courant;?>&amp;format=csv&amp;sortie=csvt">Export au format CSV</a></p>
</div>
<?php if (isset($projets) || isset($absences)) : ?>
<table id="tab_tps_w_mensuel_salarie" summary="Tableau du temps de travail mensuel par salarié.">
<caption>Plan de charge - <?=$mois['mois'];?> <?=$mois['annee'];?> - <?=$utilisateur_courant;?></caption>
<thead>
<tr>
<th>Projets</th>
<?php foreach ($elements as $jour) : ?>
<th class="<?=$jour['class']?>"><?=$jour['jour_nom']?> <?=$jour['jour']?></th>
<?php endforeach; ?>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php if (isset($projets)) : ?>
<?php $ligne = "impair"; ?>
<tr class="total">
<th>Travail</th>
<?php foreach ($elements as $jour) : ?>
<td><?=(!empty($jour['travail'])) ? $jour['travail'] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?=$total_w;?></td>
</tr>
<?foreach ($projets as $categorie => $pr):?>
<tr class="categories <?=$ligne ; $ligne = ($ligne == "impair") ? "pair" : "impair" ;?>">
<th class="entete categories_titre"><?=$categorie;?> [<?=$categories[$categorie]['abreviation'];?>]</th>
<?php foreach ($elements as $jour_id => $jour) : ?>
<td class="categories_total"><?=(isset($categories[$categorie][$jour_id])) ? $categories[$categorie][$jour_id] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?=$categories[$categorie]['total'];?></td>
</tr>
<?foreach ($pr as $id => $projet):?>
<tr class="projets <?=$ligne ; $ligne = ($ligne == "impair") ? "pair" : "impair" ;?>">
<th id="pr:<?=$id;?>" class="entete projet_nom" title="<?=$projet['desc'];?>"><?=$projet['nom'];?></th>
<?php foreach ($elements as $jour_id => $jour) : ?>
<td class="projet"><?=(isset($projet['duree'][$jour_id])) ? $projet['duree'][$jour_id] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?=(isset($projet['total'])) ? $projet['total'] : "&nbsp;";?></td>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
<?php endif; ?>
<?php if (isset($absences)) : ?>
<tr class="total">
<th class="entete absences_titre">Absences</th>
<?php foreach ($elements as $jour) : ?>
<td><?=(!empty($jour['absence'])) ? $jour['absence'] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?=$total_a;?></td>
</tr>
<?php $ligne = "impair"; ?>
<?php foreach ($absences as $ab_id => $absence) : ?>
<tr class="<?=$ligne ; $ligne = ($ligne == "impair") ? "pair" : "impair" ;?>">
<th id="ab:<?=$ab_id;?>" class="entete absence_nom"><?=$absence['nom'];?></th>
<?php foreach ($elements as $jour_id => $jour) : ?>
<td><?= (isset($ab[$ab_id][$jour_id])) ? $ab[$ab_id][$jour_id] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?=(!empty($absence['total'])) ? $absence['total'] : '&nbsp;' ;?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<tr class="total">
<th>Total</th>
<?php foreach ($elements as $jour) : ?>
<td><?=(!empty($jour['w_et_a'])) ? $jour['w_et_a'] : "&nbsp;";?></td>
<?php endforeach; ?>
<td class="total"><?=$total;?></td>
</tr>
</tbody>
</table>
<?php endif; ?>
<?php if (isset($messages)) : ?>
<?php foreach ($messages as $message) : ?>
<p class="information"><?=$message;?></p>
<?php endforeach; ?>
<?php endif; ?>
/tags/v1.0-Homere/presentation/styles/emeraude/license.txt
New file
0,0 → 1,243
Creative Commons </>
 
Creative Commons Legal Code
 
*Attribution 2.5*
 
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION
ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE
INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
ITS USE.
 
/License/
 
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
 
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE
RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS
AND CONDITIONS.
 
*1. Definitions*
 
1. *"Collective Work"* means a work, such as a periodical issue,
anthology or encyclopedia, in which the Work in its entirety in
unmodified form, along with a number of other contributions,
constituting separate and independent works in themselves, are
assembled into a collective whole. A work that constitutes a
Collective Work will not be considered a Derivative Work (as
defined below) for the purposes of this License.
2. *"Derivative Work"* means a work based upon the Work or upon the
Work and other pre-existing works, such as a translation, musical
arrangement, dramatization, fictionalization, motion picture
version, sound recording, art reproduction, abridgment,
condensation, or any other form in which the Work may be recast,
transformed, or adapted, except that a work that constitutes a
Collective Work will not be considered a Derivative Work for the
purpose of this License. For the avoidance of doubt, where the
Work is a musical composition or sound recording, the
synchronization of the Work in timed-relation with a moving image
("synching") will be considered a Derivative Work for the purpose
of this License.
3. *"Licensor"* means the individual or entity that offers the Work
under the terms of this License.
4. *"Original Author"* means the individual or entity who created the
Work.
5. *"Work"* means the copyrightable work of authorship offered under
the terms of this License.
6. *"You"* means an individual or entity exercising rights under this
License who has not previously violated the terms of this License
with respect to the Work, or who has received express permission
from the Licensor to exercise rights under this License despite a
previous violation.
 
*2. Fair Use Rights.* Nothing in this license is intended to reduce,
limit, or restrict any rights arising from fair use, first sale or other
limitations on the exclusive rights of the copyright owner under
copyright law or other applicable laws.
 
*3. License Grant.* Subject to the terms and conditions of this License,
Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
perpetual (for the duration of the applicable copyright) license to
exercise the rights in the Work as stated below:
 
1. to reproduce the Work, to incorporate the Work into one or more
Collective Works, and to reproduce the Work as incorporated in the
Collective Works;
2. to create and reproduce Derivative Works;
3. to distribute copies or phonorecords of, display publicly, perform
publicly, and perform publicly by means of a digital audio
transmission the Work including as incorporated in Collective Works;
4. to distribute copies or phonorecords of, display publicly, perform
publicly, and perform publicly by means of a digital audio
transmission Derivative Works.
5.
 
For the avoidance of doubt, where the work is a musical composition:
 
1. *Performance Royalties Under Blanket Licenses*. Licensor
waives the exclusive right to collect, whether individually
or via a performance rights society (e.g. ASCAP, BMI,
SESAC), royalties for the public performance or public
digital performance (e.g. webcast) of the Work.
2. *Mechanical Rights and Statutory Royalties*. Licensor waives
the exclusive right to collect, whether individually or via
a music rights agency or designated agent (e.g. Harry Fox
Agency), royalties for any phonorecord You create from the
Work ("cover version") and distribute, subject to the
compulsory license created by 17 USC Section 115 of the US
Copyright Act (or the equivalent in other jurisdictions).
6. *Webcasting Rights and Statutory Royalties*. For the avoidance of
doubt, where the Work is a sound recording, Licensor waives the
exclusive right to collect, whether individually or via a
performance-rights society (e.g. SoundExchange), royalties for the
public digital performance (e.g. webcast) of the Work, subject to
the compulsory license created by 17 USC Section 114 of the US
Copyright Act (or the equivalent in other jurisdictions).
 
The above rights may be exercised in all media and formats whether now
known or hereafter devised. The above rights include the right to make
such modifications as are technically necessary to exercise the rights
in other media and formats. All rights not expressly granted by Licensor
are hereby reserved.
 
*4. Restrictions.*The license granted in Section 3 above is expressly
made subject to and limited by the following restrictions:
 
1. You may distribute, publicly display, publicly perform, or
publicly digitally perform the Work only under the terms of this
License, and You must include a copy of, or the Uniform Resource
Identifier for, this License with every copy or phonorecord of the
Work You distribute, publicly display, publicly perform, or
publicly digitally perform. You may not offer or impose any terms
on the Work that alter or restrict the terms of this License or
the recipients' exercise of the rights granted hereunder. You may
not sublicense the Work. You must keep intact all notices that
refer to this License and to the disclaimer of warranties. You may
not distribute, publicly display, publicly perform, or publicly
digitally perform the Work with any technological measures that
control access or use of the Work in a manner inconsistent with
the terms of this License Agreement. The above applies to the Work
as incorporated in a Collective Work, but this does not require
the Collective Work apart from the Work itself to be made subject
to the terms of this License. If You create a Collective Work,
upon notice from any Licensor You must, to the extent practicable,
remove from the Collective Work any credit as required by clause
4(b), as requested. If You create a Derivative Work, upon notice
from any Licensor You must, to the extent practicable, remove from
the Derivative Work any credit as required by clause 4(b), as
requested.
2. If you distribute, publicly display, publicly perform, or publicly
digitally perform the Work or any Derivative Works or Collective
Works, You must keep intact all copyright notices for the Work and
provide, reasonable to the medium or means You are utilizing: (i)
the name of the Original Author (or pseudonym, if applicable) if
supplied, and/or (ii) if the Original Author and/or Licensor
designate another party or parties (e.g. a sponsor institute,
publishing entity, journal) for attribution in Licensor's
copyright notice, terms of service or by other reasonable means,
the name of such party or parties; the title of the Work if
supplied; to the extent reasonably practicable, the Uniform
Resource Identifier, if any, that Licensor specifies to be
associated with the Work, unless such URI does not refer to the
copyright notice or licensing information for the Work; and in the
case of a Derivative Work, a credit identifying the use of the
Work in the Derivative Work (e.g., "French translation of the Work
by Original Author," or "Screenplay based on original Work by
Original Author"). Such credit may be implemented in any
reasonable manner; provided, however, that in the case of a
Derivative Work or Collective Work, at a minimum such credit will
appear where any other comparable authorship credit appears and in
a manner at least as prominent as such other comparable authorship
credit.
 
*5. Representations, Warranties and Disclaimer*
 
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE
EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
 
*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY
APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL
THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY
DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF
LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 
*7. Termination*
 
1. This License and the rights granted hereunder will terminate
automatically upon any breach by You of the terms of this License.
Individuals or entities who have received Derivative Works or
Collective Works from You under this License, however, will not
have their licenses terminated provided such individuals or
entities remain in full compliance with those licenses. Sections
1, 2, 5, 6, 7, and 8 will survive any termination of this License.
2. Subject to the above terms and conditions, the license granted
here is perpetual (for the duration of the applicable copyright in
the Work). Notwithstanding the above, Licensor reserves the right
to release the Work under different license terms or to stop
distributing the Work at any time; provided, however that any such
election will not serve to withdraw this License (or any other
license that has been, or is required to be, granted under the
terms of this License), and this License will continue in full
force and effect unless terminated as stated above.
 
*8. Miscellaneous*
 
1. Each time You distribute or publicly digitally perform the Work or
a Collective Work, the Licensor offers to the recipient a license
to the Work on the same terms and conditions as the license
granted to You under this License.
2. Each time You distribute or publicly digitally perform a
Derivative Work, Licensor offers to the recipient a license to the
original Work on the same terms and conditions as the license
granted to You under this License.
3. If any provision of this License is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability
of the remainder of the terms of this License, and without further
action by the parties to this agreement, such provision shall be
reformed to the minimum extent necessary to make such provision
valid and enforceable.
4. No term or provision of this License shall be deemed waived and no
breach consented to unless such waiver or consent shall be in
writing and signed by the party to be charged with such waiver or
consent.
5. This License constitutes the entire agreement between the parties
with respect to the Work licensed here. There are no
understandings, agreements or representations with respect to the
Work not specified here. Licensor shall not be bound by any
additional provisions that may appear in any communication from
You. This License may not be modified without the mutual written
agreement of the Licensor and You.
 
Creative Commons is not a party to this License, and makes no warranty
whatsoever in connection with the Work. Creative Commons will not be
liable to You or any party on any legal theory for any damages
whatsoever, including without limitation any general, special,
incidental or consequential damages arising in connection to this
license. Notwithstanding the foregoing two (2) sentences, if Creative
Commons has expressly identified itself as the Licensor hereunder, it
shall have all rights and obligations of Licensor.
 
Except for the limited purpose of indicating to the public that the Work
is licensed under the CCPL, neither party will use the trademark
"Creative Commons" or any related trademark or logo of Creative Commons
without the prior written consent of Creative Commons. Any permitted use
will be in compliance with Creative Commons' then-current trademark
usage guidelines, as may be published on its website or otherwise made
available upon request from time to time.
 
Creative Commons may be contacted at http://creativecommons.org/
<http://creativecommons.org>.
 
« Back to Commons Deed <./>
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/tags/v1.0-Homere/presentation/styles/emeraude/images/a1.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/presentation/styles/emeraude/images/a1.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/presentation/styles/emeraude/images/a2.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/presentation/styles/emeraude/images/a2.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/presentation/styles/emeraude/images/a3.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/presentation/styles/emeraude/images/a3.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/presentation/styles/emeraude/images/a4.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/presentation/styles/emeraude/images/a4.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/presentation/styles/emeraude/images/a5.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/presentation/styles/emeraude/images/a5.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/presentation/styles/emeraude/images/help_view_16x16.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/presentation/styles/emeraude/images/help_view_16x16.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/presentation/styles/emeraude/emeraude.css
New file
0,0 → 1,231
/*
Design by Free CSS Templates
http://www.freecsstemplates.org
Released for free under a Creative Commons Attribution 2.5 License
Contributor for GTT : Jean-Pascal MILCENT <jpm@tela-botanica.org>
*/
/* Basic */
* {
margin:0em;
padding:0em;}
body {
font-family:"trebuchet ms", sans-serif;
color:#555555;
font-size:0.8em;}
a{
color: #669911;}
/* Presentation des listes de definitions */
dl {width:100%;}
dt {
float:left;
font-weight: bold;
line-height:1.1em;
text-align:top left;
margin-right:0.3em;}
dd {
width:auto;
margin-left:0;
line-height:1.1em;
margin:0.5em 0;}
 
/* Presentation des formulaires */
form.editer{
padding:0 0 1em 0;}
form ul li{
list-style-type:none;}
form label{
font-weight:bold;}
legend{
font-size:1.1em;
font-weight:bold;
text-transform:uppercase;
color: #5D5F53;}
 
/* Présentation générale des tableaux */
table{
border:1px dotted black;
width:100%;}
thead th{
background-color:#486300;
color:white;}
tbody th{
text-align:left !important;
width:20%;}
td{text-align:center;}
tr.pair{background-color: #F1F2E7;}
caption{margin-top:1em;}
 
/* Présentation d'icones*/
a.ext:after {
content: " "url(../../images/icones/lien_externe.png);}
 
/*Présentation des bulles d'aide */
*[title]:after {content:" "url(images/help_view_16x16.gif);}
 
/* Zone entête */
#zone_entete{
background-image: url('images/a2.gif');
background-position: bottom left;
padding-left: 40px;
padding-top: 45px;}
#zone_entete h1{
text-transform:uppercase;
font-size:1.6em;
color:white;}
#zone_entete a{
position: relative;
top:-0.3em;
color:#E8EFC2;
font-weight:normal;
font-size:1.1em;
text-transform:lowercase;}
 
/* Zone menu */
#zone_menu h3{
margin:0.5em 0 0 0;}
#zone_menu li{
font-size: 1.1em;
font-weight: bold;
text-decoration: none;
margin-right: 0em;}
#zone_menu li a{
display:block;
font-size: 0.8em;
font-weight: bold;
color: #5D5F53;
text-decoration: none;
margin-right: 1em;}
#zone_menu li a:hover{
background-color: #6B7E09;
color:white;}
 
/* Zone tronc */
#zone_tronc{
padding: 0 15px 1em 15px;
line-height: 1.6em;
background: url('images/a4.gif') repeat-x top left;}
#zone_tronc h2,#zone_tronc h3{
text-transform:uppercase;}
 
 
/* Zone gauche */
#zone_gauche{
padding: 0 1.5em 1.5em 0.5em;}
#zone_gauche h2, #zone_gauche h3{
color: #5D5F53;
border-bottom: dotted 1px #ECEEDF;
margin-bottom:0;}
#zone_gauche hr{margin-bottom: 0.5em;}
 
/* Zone centre */
#zone_centre{
padding: 0;}
#zone_centre h2,h3,h4,h5,h6{
margin-bottom:1em;
text-transform:uppercase;}
#zone_centre p{
margin-bottom: 1.5em;}
#zone_centre ul{
margin-bottom: 1.5em;
padding-left: 1em;}
 
/* Zone droite */
#zone_droite h3, #zone_droite h3{
background: url('images/a1.gif') no-repeat;
width: 185px;
height: 27px;
font-size: 1.0em;
font-weight: bold;
padding-left: 15px;
padding-top: 5px;
color: #5D5F53;}
 
/* Zone pied */
#zone_pied{
background: url('images/a4.gif') repeat-x top left;
border-top: solid 1px #D0D4BB;
padding: 2.0em 3.5em 3.0em 3.5em;
font-size: 0.8em;}
/*------------------------------------------*/
/*Spécial Appli GTT*/
#info,.information{
background-image: url('images/a3.gif');
background-repeat: repeat-x;
background-position: bottom left;
padding: 0.5em;}
/* Presentation des informations */
.information{
text-align:center;
font-weight:bold;
border:2px solid red;}
/*Formulaires*/
.symbole_obligatoire{
font-size:1em;
font-weight:bold;
color:red;}
/*Liste de définition*/
.ajout_2_points dt:after {content:" : ";}
.ajout_2_points dt[title]:after {content:" "url(images/help_view_16x16.gif)" : ";}
/* Le calendrier */
.calendrier {
font-family:verdana, arial, helvetica, sans-serif;
font-size:0.9em;}
.calendrier table {background-color: silver;}
.calendrier table td {text-align: center;}
.calendrier caption {font-weight: bold;}
.categorie,.totaux_titre {
font-size:1.6em;
text-align:left !important;
padding:1px;
margin:0 0.2em;}
.projet {
font-weight:bold;
width:300px;}
.utilisateur{
width:75px;
text-align:center;
background:white;}
.jour_courrant {
color:#BB0000;
background-color:yellow;
border:2px outset #74C054;}
.jour_ferie {
background-color:red;
border-width:2px outset #74C054;}
.jour_we {
color:black;
background-color: #F1F2E7;
border-width:2px outset #74C054;}
.jour_vide {
color:white;
background-color: grey;}
/* Tableau identification */
#connexion{border:0;}
#connexion td{
width:50%;}
/* Tableau stats*/
tbody td.total{
width:5%;}
tr.categories,tr.absences{
background-image: url('images/a2.gif');}
tr.total, tr.total th{
color:white;
font-weight:white;
background-color:#B30000;}
#tab_tps_w_mensuel_salarie{
width:100%;}
.entete{width:250px;}
#navigation{text-align:center;}
#navigation p{margin:0;}
#form_utilisateur label{
display:inline;
float:none;
min-width:0;
font-weight:normal;}
#preferences .pr_no {
font-weight:bold;
width:30%;}
#preferences .pr_de {
font-size:0.8em;
text-align:left;}
table#ut_tdt{width:50%;}
/tags/v1.0-Homere/presentation/styles/disposition.css
New file
0,0 → 1,78
@CHARSET "ISO-8859-1";
/* GTT VERSION 4 */
 
/* Modif des balises */
body,h1,h2,p{
margin:0;
padding:0;}
legend{margin:0 0 0 1em;}
form {width:100%;}
label{
display:block;
float:left;
padding-right:5px;
min-width:150px;}
 
/* Disposition des éléments sur la page */
#zone_entete {
height:75px;}
#zone_conteneur {
position: absolute;
min-width:1200px;
width:100%;}
#zone_tronc {
position:relative;
padding:5px;}
#zone_gauche {
position:absolute;
left:0;
top:5px;
width:200px;
height:100%;}
#zone_centre {
position:relative;
margin:0 200px;
padding:0;
min-height:500px;
min-width:750px;
overflow:auto;}
#zone_droite {
position:absolute;
right:0;
top:5px;
width:205px;
height:100%;}
#zone_pied {
margin-top:10px;
height:100%;}
 
/* Autres zones mineures*/
#zone_accessibilite {
float:right;}
#zone_menu{
padding:0 0 0 5px;}
 
/* Détails */
#gestion input {width:80px;}
#gestion #btn_valider,.btn_large{
width:50%;
height:50px;
margin:5px auto;}
form.centre{
text-align:center;}
#calendrier_gestion table{
width:100%;
clear:both;}
#connexion input[type=submit]{width:100%}
#info{margin:0;
padding:0;}
#info_aujourdhui{
float:left;
margin:0;}
#info_semaine{text-align:right;}
 
/*Formulaires*/
.editer li{
display:block;
float:left;
margin:0 0 0 5px}
/tags/v1.0-Homere/presentation/styles/impression.css
New file
0,0 → 1,10
#zone_droite, #zone_erreur,#navigation,#zone_accessibilite {display:none;}
#zone_gauche{page-break-after: always;}
table{
border: medium solid grey;
border-collapse: collapse;
margin:0}
td,th{border:thin solid grey;}
th{border-bottom: medium solid grey;}
td,th{text-align:center;}
.entete{text-align:left;}
/tags/v1.0-Homere/presentation/admin_utilisateur.tpl.html
New file
0,0 → 1,141
<?php if (isset($messages)) : ?>
<?php foreach ($messages as $message) : ?>
<p class="information"><?=$message;?></p>
<?php endforeach; ?>
<?php endif; ?>
<form id="admin_utilisateur_editer" class="editer" name="admin_utilisateur_editer" action="index.php?action=admin-utilisateur_editer" method="post">
<fieldset>
<legend>Éditer un utilisateur</legend>
<ul>
<li>
<label for="utsu_id">Utilisateur :</label>
<select id="utsu_id" name="utsu_id">
<?php foreach ($utilisateurs as $utilisateur) : ?>
<option value="<?=$utilisateur['id'];?>"><?=$utilisateur['libelle'];?></option>
<?php endforeach; ?>
</select>
</li>
<li><input id="btn_utilisateur_supprimer" name="btn_utilisateur_supprimer" value="Supprimer" type="submit" onclick="javascript:return confirm('Êtes vous sûr de vouloir supprimer cet utilisateur ?');" /></li>
<li><input id="btn_utilisateur_modifier" name="btn_utilisateur_modifier" value="Modifier" type="submit" /></li>
</ul>
</fieldset>
</form>
<form id="admin_utilisateur_ajouter" name="admin_utilisateur_ajouter" action="<?=$form_url;?>" method="post">
<fieldset>
<legend><?=$form_legend;?></legend>
<ul>
<li>
<label for="ut_nom">Nom :</label>
<input size="50" name="ut_nom" type="text" value="<?=$Utilisateur->getNom();?>"/><span class="symbole_obligatoire">*</span>
</li>
<li>
<label for="ut_prenom">Prenom :</label>
<input size="50" name="ut_prenom" type="text" value="<?=$Utilisateur->getPrenom();?>"/><span class="symbole_obligatoire">*</span>
</li>
<li>
<label for="ut_adresse">Adresse :</label>
<input size="75" name="ut_adresse" type="text" value="<?=$Utilisateur->getAdresse();?>"/>
</li>
<li>
<label for="ut_ville">Ville :</label>
<input size="50" name="ut_ville" type="text" value="<?=$Utilisateur->getVille();?>"/>
</li>
<li>
<label for="ut_code_postal">Code postal :</label>
<input size="5" name="ut_code_postal" type="text" value="<?=$Utilisateur->getCodePostal();?>"/>
</li>
<li>
<label for="ut_telephone">Téléphone :</label>
<input size="10" name="ut_telephone" type="text" value="<?=$Utilisateur->getTelephone();?>"/>
</li>
<li>
<label for="ut_email">Courriel :</label>
<input size="50" name="ut_email" type="text" value="<?=$Utilisateur->getEmail();?>"/><span class="symbole_obligatoire">*</span>
</li>
<?php if ($mode == 'M') : ?>
<li>
<fieldset>
<legend>Mot de passe</legend>
<strong>Si vous ne voulez pas modifier le mot de passe :</strong> laisser vide les champs "Mot de passe" et "Confirmer mot de passe".
<ul>
<?php endif; ?>
<li>
<label for="ut_mot_de_passe">Mot de passe :</label>
<input size="20" name="ut_mot_de_passe" type="password"/><span class="symbole_obligatoire">*</span></li>
<li>
<label for="ut_mot_de_passe_confirmation">Confirmer mot de passe :</label>
<input size="20" name="ut_mot_de_passe_confirmation" type="password"/><span class="symbole_obligatoire">*</span>
</li>
<?php if ($mode == 'M') : ?>
</ul>
</fieldset>
</li>
<?php endif; ?>
<li>
<label for="ut_statut">Statut :</label>
<select id="ut_statut" name="ut_statut">
<?php foreach ($utilisateur_statuts as $statut) : ?>
<option value="<?=$statut['id'];?>"><?=$statut['libelle'];?></option>
<?php endforeach; ?>
</select>
</li>
<li>
<label for="ut_conges_payes">Congés payés initiaux (en heure) :</label>
<input size="3" name="ut_conges_payes" type="text" value="<?=$Utilisateur->getCongesPayes();?>"/>
</li>
<li>
<label for="ut_temps_de_travail_jour">Temps journalier de travail :</label>
<input size="3" name="ut_temps_de_travail_jour" type="text" value="<?=$Utilisateur->getTempsDeTravailJour();?>"/>
</li>
<li>
<label for="ut_temps_de_travail_mois">Temps de travail mensuel fixe :</label>
<input size="3" name="ut_temps_de_travail_mois" type="text" value="<?=$Utilisateur->getTempsDeTravailMois();?>"/>
</li>
<li>
<label for="ut_tdt">Temps de travail hebdomadaire :</label>
<table id="ut_tdt">
<thead>
<tr>
<th>Lundi</th>
<th>Mardi</th>
<th>Mercredi</th>
<th>Jeudi</th>
<th>Vendredi</th>
<th>Samedi</th>
<th>Dimanche</th>
</tr>
</thead>
<tbody>
<tr>
<td><input size="3" name="ut_tdt_lundi" type="text" value="<?=$Utilisateur->getTdtLundi();?>"/></td>
<td><input size="3" name="ut_tdt_mardi" type="text" value="<?=$Utilisateur->getTdtMardi();?>"/></td>
<td><input size="3" name="ut_tdt_mercredi" type="text" value="<?=$Utilisateur->getTdtMercredi();?>"/></td>
<td><input size="3" name="ut_tdt_jeudi" type="text" value="<?=$Utilisateur->getTdtJeudi();?>"/></td>
<td><input size="3" name="ut_tdt_vendredi" type="text" value="<?=$Utilisateur->getTdtVendredi();?>"/></td>
<td><input size="3" name="ut_tdt_samedi" type="text" value="<?=$Utilisateur->getTdtSamedi();?>"/></td>
<td><input size="3" name="ut_tdt_dimanche" type="text" value="<?=$Utilisateur->getTdtDimanche();?>"/></td>
</tr>
</tbody>
</table>
</li>
<li>
<label for="ut_quota_heures_sup">Heures supplémentaires initiales :</label>
<input size="3" name="ut_quota_heures_supp" type="text" value="<?=$Utilisateur->getQuotaHeuresSupp();?>"/>
</li>
<li>
<label for="ut_mark_admin">Adminitrateur :</label>
<input id="ut_mark_admin" name="ut_mark_admin" type="checkbox" value="1" <?=($bool_mark_admin)?'checked="checked"':'';?>/>
</li>
<li>
<label for="ut_mark_recapitulatif">Cet utilisateur ne doit pas apparaître dans les divers récapitulatif :</label>
<input id="ut_mark_recapitulatif" name="ut_mark_recapitulatif" type="checkbox" value="1" <?=($bool_mark_recapitulatif)?'checked="checked"':'';?>/>
</li>
<li>
<input name="ut_id_utilisateur" type="hidden" value="<?=$Utilisateur->getIdUtilisateur();?>"/>
<input id="<?=$form_bouton_id;?>" name="<?=$form_bouton_id;?>" value="<?=$form_bouton_value;?>" type="submit" />
<input id="btn_utilisateur_annuler" name="btn_utilisateur_annuler" value="Annuler" type="submit" />
</li>
<li><span class="symbole_obligatoire">*</span> =champs obligatoires</li>
</ul>
</fieldset>
</form>
/tags/v1.0-Homere/bibliotheque/pear/Auth/PrefManager.php
New file
0,0 → 1,426
<?php
require_once("DB.php");
 
/**
* A simple preference manager, takes userid, preference name pairs and returns the value
* of that preference.
*
* CREATE TABLE `preferences` (
* `user_id` varchar( 255 ) NOT NULL default '',
* `pref_id` varchar( 32 ) NOT NULL default '',
* `pref_value` longtext NOT NULL ,
* PRIMARY KEY ( `user_id` , `pref_id` )
* )
*
* @author Jon Wood <jon@jellybob.co.uk>
* @package Auth_PrefManager
* @category Authentication
*/
class Auth_PrefManager
{
/**
* The database object.
* @var object
* @access private
*/
var $_db;
 
/**
* The user name to get preferences from if the user specified doesn't
* have that preference set.
* @var string
* @access private
*/
var $_defaultUser = "__default__";
 
/**
* Should we search for default values, or just fail when we find out that
* the specified user didn't have it set.
*
* @var bool
* @access private
*/
var $_returnDefaults = true;
 
/**
* The table containing the preferences.
* @var string
* @access private
*/
var $_table = "preferences";
 
/**
* The column containing user ids.
* @var string
* @access private
*/
var $_userColumn = "user_id";
 
/**
* The column containing preference names.
* @var string
* @access private
*/
var $_nameColumn = "pref_id";
 
/**
* The column containing preference values.
* @var string
* @access private
*/
var $_valueColumn = "pref_value";
 
/**
* The quoted value column.
* @var string
* @access private
*/
var $_valueColumnQuoted = "pref_value";
/**
* The session variable that the cache array is stored in.
* @var string
* @access private
*/
var $_cacheName = "prefCache";
 
/**
* The last error given.
* @var string
* @access private
*/
var $_lastError;
 
/**
* Defines whether the cache should be used or not.
* @var bool
* @access private
*/
var $_useCache = true;
/**
* Defines whether values should be serialized before saving.
* @var bool
* @access private
*/
var $_serialize = false;
/**
* Constructor
*
* Options:
* table: The table to get prefs from. [preferences]
* userColumn: The field name to search for userid's [user_id]
* nameColumn: The field name to search for preference names [pref_name]
* valueColumn: The field name to search for preference values [pref_value]
* defaultUser: The userid assigned to default values [__default__]
* cacheName: The name of cache in the session variable ($_SESSION[cacheName]) [prefsCache]
* useCache: Whether or not values should be cached.
* serialize: Should preference values be serialzed before saving?
*
* @param string $dsn The DSN of the database connection to make, or a DB object.
* @param array $properties An array of properties to set.
* @param string $defaultUser The default user to manage for.
* @return bool Success or failure.
* @access public
*/
function Auth_PrefManager($dsn, $properties = NULL)
{
// Connect to the database.
if (isset($dsn)) {
if (is_string($dsn)) {
$this->_db = DB::Connect($dsn);
if (DB::isError($this->_db)) {
$this->_lastError = "DB Error: ".$this->_db->getMessage();
}
} else if (is_subclass_of($dsn, 'db_common')) {
$this->_db = &$dsn;
} else {
$this->_lastError = "Invalid DSN specified.";
return false;
}
} else {
$this->_lastError = "No DSN specified.";
return false;
}
 
if (is_array($properties)) {
if (isset($properties["table"])) { $this->_table = $this->_db->quoteIdentifier($properties["table"]); }
if (isset($properties["userColumn"])) { $this->_userColumn = $this->_db->quoteIdentifier($properties["userColumn"]); }
if (isset($properties["nameColumn"])) { $this->_nameColumn = $this->_db->quoteIdentifier($properties["nameColumn"]); }
if (isset($properties["valueColumn"])) { $this->_valueColumn = $properties["valueColumn"]; }
if (isset($properties["valueColumn"])) { $this->_valueColumnQuoted = $this->_db->quoteIdentifier($properties["valueColumn"]); }
if (isset($properties["defaultUser"])) { $this->_defaultUser = $properties["defaultUser"]; }
if (isset($properties["cacheName"])) { $this->_cacheName = $properties["cacheName"]; }
if (isset($properties["useCache"])) { $this->_useCache = $properties["useCache"]; }
if (isset($properties["serialize"])) { $this->_serialize = $properties["serialize"]; }
}
 
return true;
}
 
function setReturnDefaults($returnDefaults = true)
{
if (is_bool($returnDefaults)) {
$this->_returnDefaults = $returnDefaults;
}
}
 
/**
* Sets whether the cache should be used.
*
* @param bool $use Should the cache be used.
* @access public
*/
function useCache($use = true)
{
$this->_useCache = $use;
}
/**
* Cleans out the cache.
*
* @access public
*/
function clearCache()
{
unset($_SESSION[$this->_cacheName]);
}
 
/**
* Get a preference for the specified user, or, if returning default values
* is enabled, the default.
*
* @param string $user_id The user to get the preference for.
* @param string $pref_id The preference to get.
* @param bool $showDefaults Should default values be searched (overrides the global setting).
* @return mixed The value if it's found, or NULL if it isn't.
* @access public
*/
function getPref($user_id, $pref_id, $showDefaults = true)
{
if (isset($_SESSION[$this->_cacheName][$user_id][$pref_id]) && $this->_useCache) {
// Value is cached for the specified user, so give them the cached copy.
return $_SESSION[$this->_cacheName][$user_id][$pref_id];
} else {
// Not cached, search the database for this user's preference.
$query = sprintf("SELECT * FROM %s WHERE %s=%s AND %s=%s", $this->_table,
$this->_userColumn,
$this->_db->quote($user_id),
$this->_nameColumn,
$this->_db->quote($pref_id));
$result = $this->_db->query($query);
if (DB::isError($result)) {
// Ouch! The query failed!
$this->_lastError = "DB Error: ".$result->getMessage();
return NULL;
} else if ($result->numRows()) {
// The query found a value, so we can cache that, and then return it.
$row = $result->fetchRow(DB_FETCHMODE_ASSOC);
$_SESSION[$this->_cacheName][$user_id][$pref_id] = $this->_unpack($row[$this->_valueColumn]);
return $_SESSION[$this->_cacheName][$user_id][$pref_id];
} else if ($this->_returnDefaults && $showDefaults) {
// I was doing this with a call to getPref again, but it threw things into an
// infinite loop if the default value didn't exist. If you can fix that, it would
// be great ;)
if (isset($_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id]) && $this->_useCache) {
$_SESSION[$this->_cacheName][$user_id][$pref_id] = $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
return $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
} else {
$query = sprintf("SELECT * FROM %s WHERE %s=%s AND %s=%s", $this->_table,
$this->_userColumn,
$this->_db->quote($this->_defaultUser),
$this->_nameColumn,
$this->_db->quote($pref_id));
$result = $this->_db->query($query);
if (DB::isError($result)) {
$this->_lastError = "DB Error: ".$result->getMessage();
return NULL;
} else {
if ($result->numRows()) {
$row = $result->fetchRow(DB_FETCHMODE_ASSOC);
$_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id] = $this->_unpack($row[$this->_valueColumn]);
$_SESSION[$this->_cacheName][$user_id][$pref_id] = $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
return $_SESSION[$this->_cacheName][$user_id][$pref_id];
} else {
return NULL;
}
}
}
} else {
// We've used up all the resources we're allowed to search, so return a NULL.
return NULL;
}
}
}
 
/**
* A shortcut function for getPref($this->_defaultUser, $pref_id, $value),
* useful if you have a logged in user, but want to get defaults anyway.
*
* @param string $pref_id The name of the preference to get.
* @return mixed The value if it's found, or NULL if it isn't.
* @access public
*/
function getDefaultPref($pref_id)
{
return $this->getPref($this->_defaultUser, $pref_id);
}
 
/**
* Set a preference for the specified user.
*
* @param string $user_id The user to set for.
* @param string $pref_id The preference to set.
* @param mixed $value The value it should be set to.
* @return bool Sucess or failure.
* @access public
*/
function setPref($user_id, $pref_id, $value)
{
// Start off by checking if the preference is already set (if it is we need to do
// an UPDATE, if not, it's an INSERT.
if ($this->_exists($user_id, $pref_id, false)) {
$query = sprintf("UPDATE %s SET %s=%s WHERE %s=%s AND %s=%s", $this->_table,
$this->_valueColumnQuoted,
$this->_db->quote($this->_pack($value)),
$this->_userColumn,
$this->_db->quote($user_id),
$this->_nameColumn,
$this->_db->quote($pref_id));
} else {
$query = sprintf("INSERT INTO %s (%s, %s, %s) VALUES(%s, %s, %s)", $this->_table,
$this->_userColumn,
$this->_nameColumn,
$this->_valueColumnQuoted,
$this->_db->quote($user_id),
$this->_db->quote($pref_id),
$this->_db->quote($this->_pack($value)));
}
$result = $this->_db->query($query);
if (DB::isError($result)) {
$this->_lastError = "DB Error: ".$result->getMessage();
return false;
} else {
if ($this->_useCache) {
$_SESSION[$this->_cacheName][$user_id][$pref_id] = $value;
}
return true;
}
}
 
/**
* A shortcut function for setPref($this->_defaultUser, $pref_id, $value)
*
* @param string $pref_id The name of the preference to set.
* @param mixed $value The value to set it to.
* @return bool Sucess or failure.
* @access public
*/
function setDefaultPref($pref_id, $value)
{
return $this->setPref($this->_defaultUser, $pref_id, $value);
}
 
/**
* Deletes a preference for the specified user.
*
* @param string $user_id The userid of the user to delete from.
* @param string $pref_id The preference to delete.
* @return bool Success/Failure
* @access public
*/
function deletePref($user_id, $pref_id)
{
if ($this->getPref($user_id, $pref_id) == NULL) {
// The user doesn't have this variable anyway ;)
return true;
} else {
$query = sprintf("DELETE FROM %s WHERE %s=%s AND %s=%s", $this->_table,
$this->_userColumn,
$this->_db->quote($user_id),
$this->_nameColumn,
$this->_db->quote($pref_id));
$result = $this->_db->query($query);
if (DB::isError($result)) {
$this->_lastError = "DB Error: ".$result->getMessage();
return false;
} else {
if ($this->_useCache) {
unset($_SESSION[$this->_cacheName][$user_id][$pref_id]);
}
return true;
}
}
}
 
/**
* Deletes a preference for the default user.
*
* @param string $pref_id The preference to delete.
* @return bool Success/Failure
* @access public
*/
function deleteDefaultPref($pref_id)
{
return $this->deletePref($this->_defaultUser, $pref_id);
}
/**
* Checks if a preference exists in the database.
*
* @param string $user_id The userid of the preference owner.
* @param string $pref_id The preference to check for.
* @return bool True if the preference exists.
* @access private
*/
function _exists($user_id, $pref_id)
{
$query = sprintf("SELECT COUNT(%s) FROM %s WHERE %s=%s AND %s=%s", $this->_nameColumn,
$this->_table,
$this->_userColumn,
$this->_db->quoteSmart($user_id),
$this->_nameColumn,
$this->_db->quote($pref_id));
$result = $this->_db->getOne($query);
if (DB::isError($result)) {
$this->_lastError = "DB Error: ".$result->getMessage();
return false;
} else {
return (bool)$result;
}
}
 
/**
* Does anything needed to prepare a value for saving in the database.
*
* @param mixed $value The value to be saved.
* @return string The value in a format valid for saving to the database.
* @access private
*/
function _pack($value)
{
if ($this->_serialize) {
return serialize($value);
} else {
return $value;
}
}
/**
* Does anything needed to create a value of the preference, such as unserializing.
*
* @param string $value The value of the preference.
* @return mixed The unpacked version of the preference.
* @access private
*/
function _unpack($value)
{
if ($this->_serialize) {
return unserialize($value);
} else {
return $value;
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/RADIUS.php
New file
0,0 → 1,964
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/*
Copyright (c) 2003, Michael Bretterklieber <michael@bretterklieber.com>
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
 
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
This code cannot simply be copied and put under the GNU Public License or
any other GPL-like (LGPL, GPL2) License.
 
$Id: RADIUS.php,v 1.3 2003/05/02 11:04:02 mbretter Exp $
*/
 
require_once 'PEAR.php';
 
/**
* Client implementation of RADIUS. This are wrapper classes for
* the RADIUS PECL.
* Provides RADIUS Authentication (RFC2865) and RADIUS Accounting (RFC2866).
*
* @package Auth_RADIUS
* @author Michael Bretterklieber <michael@bretterklieber.com>
* @access public
* @version $Revision: 1.3 $
*/
 
/**
* class Auth_RADIUS
*
* Abstract base class for RADIUS
*
* @package Auth_RADIUS
*/
class Auth_RADIUS extends PEAR {
 
/**
* List of RADIUS servers.
* @var array
* @see addServer(), putServer()
*/
var $_servers = array();
/**
* Path to the configuration-file.
* @var string
* @see setConfigFile()
*/
var $_configfile = null;
/**
* Resource.
* @var resource
* @see open(), close()
*/
var $res = null;
/**
* Username for authentication and accounting requests.
* @var string
*/
var $username = null;
 
/**
* Password for plaintext-authentication (PAP).
* @var string
*/
var $password = null;
/**
* List of known attributes.
* @var array
* @see dumpAttributes(), getAttributes()
*/
var $attributes = array();
/**
* List of raw attributes.
* @var array
* @see dumpAttributes(), getAttributes()
*/
var $rawAttributes = array();
 
/**
* List of raw vendor specific attributes.
* @var array
* @see dumpAttributes(), getAttributes()
*/
var $rawVendorAttributes = array();
/**
* Constructor
*
* Loads the RADIUS PECL/extension
*
* @return void
*/
function Auth_RADIUS()
{
$this->PEAR();
$this->loadExtension('radius');
}
/**
* Adds a RADIUS server to the list of servers for requests.
*
* At most 10 servers may be specified. When multiple servers
* are given, they are tried in round-robin fashion until a
* valid response is received
*
* @access public
* @param string $servername Servername or IP-Address
* @param integer $port Portnumber
* @param string $sharedSecret Shared secret
* @param integer $timeout Timeout for each request
* @param integer $maxtries Max. retries for each request
* @return void
*/
function addServer($servername = 'localhost', $port = 0, $sharedSecret = 'testing123', $timeout = 3, $maxtries = 3)
{
$this->_servers[] = array($servername, $port, $sharedSecret, $timeout, $maxtries);
}
/**
* Returns an error message, if an error occurred.
*
* @access public
* @return string
*/
function getError()
{
return radius_strerror($this->res);
}
/**
* Sets the configuration-file.
*
* @access public
* @param string $file Path to the configuration file
* @return void
*/
function setConfigfile($file)
{
$this->_configfile = $file;
}
 
/**
* Puts an attribute.
*
* @access public
* @param integer $attrib Attribute-number
* @param mixed $port Attribute-value
* @param type $type Attribute-type
* @return bool true on success, false on error
*/
function putAttribute($attrib, $value, $type = null)
{
if ($type == null) {
$type = gettype($value);
}
switch ($type) {
case 'integer':
return radius_put_int($this->res, $attrib, $value);
case 'addr':
return radius_put_addr($this->res, $attrib, $value);
case 'string':
default:
return radius_put_attr($this->res, $attrib, $value);
}
}
/**
* Puts a vendor-specific attribute.
*
* @access public
* @param integer $vendor Vendor (MSoft, Cisco, ...)
* @param integer $attrib Attribute-number
* @param mixed $port Attribute-value
* @param type $type Attribute-type
* @return bool true on success, false on error
*/
function putVendorAttribute($vendor, $attrib, $value, $type = null)
{
if ($type == null) {
$type = gettype($value);
}
switch ($type) {
case 'integer':
return radius_put_vendor_int($this->res, $vendor, $attrib, $value);
case 'addr':
return radius_put_vendor_addr($this->res, $vendor,$attrib, $value);
case 'string':
default:
return radius_put_vendor_attr($this->res, $vendor, $attrib, $value);
}
}
 
/**
* Prints known attributes received from the server.
*
* @access public
*/
function dumpAttributes()
{
foreach ($this->attributes as $name => $data) {
echo "$name:$data<br>\n";
}
}
/**
* Overwrite this.
*
* @access public
*/
function open()
{
}
 
/**
* Overwrite this.
*
* @access public
*/
function createRequest()
{
}
/**
* Puts standard attributes.
*
* @access public
*/
function putStandardAttributes()
{
if (isset($_SERVER)) {
$var = &$_SERVER;
} else {
$var = &$GLOBALS['HTTP_SERVER_VARS'];
}
$this->putAttribute(RADIUS_NAS_IDENTIFIER, isset($var['HTTP_HOST']) ? $var['HTTP_HOST'] : 'localhost');
$this->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_VIRTUAL);
$this->putAttribute(RADIUS_SERVICE_TYPE, RADIUS_FRAMED);
$this->putAttribute(RADIUS_FRAMED_PROTOCOL, RADIUS_PPP);
$this->putAttribute(RADIUS_CALLING_STATION_ID, isset($var['REMOTE_HOST']) ? $var['REMOTE_HOST'] : '127.0.0.1');
}
/**
* Puts custom attributes.
*
* @access public
*/
function putAuthAttributes()
{
if (isset($this->username)) {
$this->putAttribute(RADIUS_USER_NAME, $this->username);
}
}
/**
* Configures the radius library.
*
* @access public
* @param string $servername Servername or IP-Address
* @param integer $port Portnumber
* @param string $sharedSecret Shared secret
* @param integer $timeout Timeout for each request
* @param integer $maxtries Max. retries for each request
* @return bool true on success, false on error
* @see addServer()
*/
function putServer($servername, $port = 0, $sharedsecret = 'testing123', $timeout = 3, $maxtries = 3)
{
if (!radius_add_server($this->res, $servername, $port, $sharedsecret, $timeout, $maxtries)) {
return false;
}
return true;
}
/**
* Configures the radius library via external configurationfile
*
* @access public
* @param string $servername Servername or IP-Address
* @return bool true on success, false on error
*/
function putConfigfile($file)
{
if (!radius_config($this->res, $file)) {
return false;
}
return true;
}
/**
* Initiates a RADIUS request.
*
* @access public
* @return bool true on success, false on errors
*/
function start()
{
if (!$this->open()) {
return false;
}
foreach ($this->_servers as $s) {
// Servername, port, sharedsecret, timeout, retries
if (!$this->putServer($s[0], $s[1], $s[2], $s[3], $s[4])) {
return false;
}
}
if (!empty($this->_configfile)) {
if (!$this->putConfigfile($this->_configfile)) {
return false;
}
}
$this->createRequest();
$this->putStandardAttributes();
$this->putAuthAttributes();
return true;
}
/**
* Sends a prepared RADIUS request and waits for a response
*
* @access public
* @return mixed true on success, false on reject, PEAR_Error on error
*/
function send()
{
$req = radius_send_request($this->res);
if (!$req) {
return $this->raiseError('Error sending request: ' . $this->getError());
}
 
switch($req) {
case RADIUS_ACCESS_ACCEPT:
if (is_subclass_of($this, 'auth_radius_acct')) {
return $this->raiseError('RADIUS_ACCESS_ACCEPT is unexpected for accounting');
}
return true;
 
case RADIUS_ACCESS_REJECT:
return false;
case RADIUS_ACCOUNTING_RESPONSE:
if (is_subclass_of($this, 'auth_radius_pap')) {
return $this->raiseError('RADIUS_ACCOUNTING_RESPONSE is unexpected for authentication');
}
return true;
 
default:
return $this->raiseError("Unexpected return value: $req");
}
}
 
/**
* Reads all received attributes after sending the request.
*
* This methos stores know attributes in the property attributes,
* all attributes (including known attibutes) are stored in rawAttributes
* or rawVendorAttributes.
* NOTE: call this functio also even if the request was rejected, because the
* Server returns usualy an errormessage
*
* @access public
* @return bool true on success, false on error
*/
function getAttributes()
{
 
while ($attrib = radius_get_attr($this->res)) {
 
if (!is_array($attrib)) {
return false;
}
 
$attr = $attrib['attr'];
$data = $attrib['data'];
 
$this->rawAttributes[$attr] = $data;
 
switch ($attr) {
case RADIUS_FRAMED_IP_ADDRESS:
$this->attributes['framed_ip'] = radius_cvt_addr($data);
break;
 
case RADIUS_FRAMED_IP_NETMASK:
$this->attributes['framed_mask'] = radius_cvt_addr($data);
break;
 
case RADIUS_FRAMED_MTU:
$this->attributes['framed_mtu'] = radius_cvt_int($data);
break;
 
case RADIUS_FRAMED_COMPRESSION:
$this->attributes['framed_compression'] = radius_cvt_int($data);
break;
 
case RADIUS_SESSION_TIMEOUT:
$this->attributes['session_timeout'] = radius_cvt_int($data);
break;
 
case RADIUS_IDLE_TIMEOUT:
$this->attributes['idle_timeout'] = radius_cvt_int($data);
break;
 
case RADIUS_SERVICE_TYPE:
$this->attributes['service_type'] = radius_cvt_int($data);
break;
 
case RADIUS_CLASS:
$this->attributes['class'] = radius_cvt_int($data);
break;
 
case RADIUS_FRAMED_PROTOCOL:
$this->attributes['framed_protocol'] = radius_cvt_int($data);
break;
 
case RADIUS_FRAMED_ROUTING:
$this->attributes['framed_routing'] = radius_cvt_int($data);
break;
 
case RADIUS_FILTER_ID:
$this->attributes['filter_id'] = radius_cvt_string($data);
break;
 
case RADIUS_VENDOR_SPECIFIC:
$attribv = radius_get_vendor_attr($data);
if (!is_array($attribv)) {
return false;
}
$vendor = $attribv['vendor'];
$attrv = $attribv['attr'];
$datav = $attribv['data'];
$this->rawVendorAttributes[$vendor][$attrv] = $datav;
 
if ($vendor == RADIUS_VENDOR_MICROSOFT) {
 
switch ($attrv) {
case RADIUS_MICROSOFT_MS_CHAP2_SUCCESS:
$this->attributes['ms_chap2_success'] = radius_cvt_string($datav);
break;
 
case RADIUS_MICROSOFT_MS_CHAP_ERROR:
$this->attributes['ms_chap_error'] = radius_cvt_string(substr($datav,1));
break;
 
case RADIUS_MICROSOFT_MS_CHAP_DOMAIN:
$this->attributes['ms_chap_domain'] = radius_cvt_string($datav);
break;
 
case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
$this->attributes['ms_mppe_encryption_policy'] = radius_cvt_int($datav);
break;
 
case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
$this->attributes['ms_mppe_encryption_types'] = radius_cvt_int($datav);
break;
 
case RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS:
$demangled = radius_demangle($this->res, $datav);
$this->attributes['ms_chap_mppe_lm_key'] = substr($demangled, 0, 8);
$this->attributes['ms_chap_mppe_nt_key'] = substr($demangled, 8, RADIUS_MPPE_KEY_LEN);
break;
 
case RADIUS_MICROSOFT_MS_MPPE_SEND_KEY:
$this->attributes['ms_chap_mppe_send_key'] = radius_demangle_mppe_key($this->res, $datav);
break;
 
case RADIUS_MICROSOFT_MS_MPPE_RECV_KEY:
$this->attributes['ms_chap_mppe_recv_key'] = radius_demangle_mppe_key($this->res, $datav);
break;
 
case RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER:
$this->attributes['ms_primary_dns_server'] = radius_cvt_string($datav);
break;
}
}
break;
}
}
 
return true;
}
/**
* Frees resources.
*
* Calling this method is always a good idea, because all security relevant
* attributes are filled with Nullbytes to leave nothing in the mem.
*
* @access public
*/
function close()
{
if ($this->res != null) {
radius_close($this->res);
$this->res = null;
}
$this->username = str_repeat("\0", strlen($this->username));
$this->password = str_repeat("\0", strlen($this->password));
}
}
 
/**
* class Auth_RADIUS_PAP
*
* Class for authenticating using PAP (Plaintext)
*
* @package Auth_RADIUS
*/
class Auth_RADIUS_PAP extends Auth_RADIUS
{
 
/**
* Constructor
*
* @param string $username Username
* @param string $password Password
* @return void
*/
function Auth_RADIUS_PAP($username = null, $password = null)
{
$this->Auth_RADIUS();
$this->username = $username;
$this->password = $password;
}
/**
* Creates a RADIUS resource
*
* Creates a RADIUS resource for authentication. This should be the first
* call before you make any other things with the library.
*
* @return bool true on success, false on error
*/
function open()
{
$this->res = radius_auth_open();
if (!$this->res) {
return false;
}
return true;
}
/**
* Creates an authentication request
*
* Creates an authentication request.
* You MUST call this method before you can put any attribute
*
* @return bool true on success, false on error
*/
function createRequest()
{
if (!radius_create_request($this->res, RADIUS_ACCESS_REQUEST)) {
return false;
}
return true;
}
 
/**
* Put authentication specific attributes
*
* @return void
*/
function putAuthAttributes()
{
if (isset($this->username)) {
$this->putAttribute(RADIUS_USER_NAME, $this->username);
}
if (isset($this->password)) {
$this->putAttribute(RADIUS_USER_PASSWORD, $this->password);
}
}
 
}
 
/**
* class Auth_RADIUS_CHAP_MD5
*
* Class for authenticating using CHAP-MD5 see RFC1994.
* Instead og the plaintext password the challenge and
* the response are needed.
*
* @package Auth_RADIUS
*/
class Auth_RADIUS_CHAP_MD5 extends Auth_RADIUS_PAP
{
/**
* 8 Bytes binary challenge
* @var string
*/
var $challenge = null;
 
/**
* 16 Bytes MD5 response binary
* @var string
*/
var $response = null;
/**
* Id of the authentication request. Should incremented after every request.
* @var integer
*/
var $chapid = 1;
/**
* Constructor
*
* @param string $username Username
* @param string $challenge 8 Bytes Challenge (binary)
* @param integer $chapid Requestnumber
* @return void
*/
function Auth_RADIUS_CHAP_MD5($username = null, $challenge = null, $chapid = 1)
{
$this->Auth_RADIUS_PAP();
$this->username = $username;
$this->challenge = $challenge;
$this->chapid = $chapid;
}
/**
* Put CHAP-MD5 specific attributes
*
* For authenticating using CHAP-MD5 via RADIUS you have to put the challenge
* and the response. The chapid is inserted in the first byte of the response.
*
* @return void
*/
function putAuthAttributes()
{
if (isset($this->username)) {
$this->putAttribute(RADIUS_USER_NAME, $this->username);
}
if (isset($this->response)) {
$response = pack('C', $this->chapid) . $this->response;
$this->putAttribute(RADIUS_CHAP_PASSWORD, $response);
}
if (isset($this->challenge)) {
$this->putAttribute(RADIUS_CHAP_CHALLENGE, $this->challenge);
}
}
/**
* Frees resources.
*
* Calling this method is always a good idea, because all security relevant
* attributes are filled with Nullbytes to leave nothing in the mem.
*
* @access public
*/
function close()
{
Auth_RADIUS_PAP::close();
$this->challenge = str_repeat("\0", strlen($this->challenge));
$this->response = str_repeat("\0", strlen($this->response));
}
}
 
/**
* class Auth_RADIUS_MSCHAPv1
*
* Class for authenticating using MS-CHAPv1 see RFC2433
*
* @package Auth_RADIUS
*/
class Auth_RADIUS_MSCHAPv1 extends Auth_RADIUS_CHAP_MD5
{
/**
* LAN-Manager-Response
* @var string
*/
var $lmResponse = null;
 
/**
* Wether using deprecated LM-Responses or not.
* 0 = use LM-Response, 1 = use NT-Response
* @var bool
*/
var $flags = 1;
/**
* Put MS-CHAPv1 specific attributes
*
* For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge
* and the response. The response has this structure:
* struct rad_mschapvalue {
* u_char ident;
* u_char flags;
* u_char lm_response[24];
* u_char response[24];
* };
*
* @return void
*/
function putAuthAttributes()
{
if (isset($this->username)) {
$this->putAttribute(RADIUS_USER_NAME, $this->username);
}
if (isset($this->response) || isset($this->lmResponse)) {
$lmResp = isset($this->lmResponse) ? $this->lmResponse : str_repeat ("\0", 24);
$ntResp = isset($this->response) ? $this->response : str_repeat ("\0", 24);
$resp = pack('CC', $this->chapid, $this->flags) . $lmResp . $ntResp;
$this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_RESPONSE, $resp);
}
if (isset($this->challenge)) {
$this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
}
}
}
 
/**
* class Auth_RADIUS_MSCHAPv2
*
* Class for authenticating using MS-CHAPv2 see RFC2759
*
* @package Auth_RADIUS
*/
class Auth_RADIUS_MSCHAPv2 extends Auth_RADIUS_MSCHAPv1
{
/**
* 16 Bytes binary challenge
* @var string
*/
var $challenge = null;
/**
* 16 Bytes binary Peer Challenge
* @var string
*/
var $peerChallenge = null;
 
/**
* Put MS-CHAPv2 specific attributes
*
* For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge
* and the response. The response has this structure:
* struct rad_mschapv2value {
* u_char ident;
* u_char flags;
* u_char pchallenge[16];
* u_char reserved[8];
* u_char response[24];
* };
* where pchallenge is the peer challenge. Like for MS-CHAPv1 we set the flags field to 1.
* @return void
*/
function putAuthAttributes()
{
if (isset($this->username)) {
$this->putAttribute(RADIUS_USER_NAME, $this->username);
}
if (isset($this->response) && isset($this->peerChallenge)) {
// Response: chapid, flags (1 = use NT Response), Peer challenge, reserved, Response
$resp = pack('CCa16a8a24',$this->chapid , 1, $this->peerChallenge, str_repeat("\0", 8), $this->response);
$this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP2_RESPONSE, $resp);
}
if (isset($this->challenge)) {
$this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
}
}
/**
* Frees resources.
*
* Calling this method is always a good idea, because all security relevant
* attributes are filled with Nullbytes to leave nothing in the mem.
*
* @access public
*/
function close()
{
Auth_RADIUS_MSCHAPv1::close();
$this->peerChallenge = str_repeat("\0", strlen($this->peerChallenge));
}
}
 
/**
* class Auth_RADIUS_Acct
*
* Class for RADIUS accounting
*
* @package Auth_RADIUS
*/
class Auth_RADIUS_Acct extends Auth_RADIUS
{
/**
* Defines where the Authentication was made, possible values are:
* RADIUS_AUTH_RADIUS, RADIUS_AUTH_LOCAL, RADIUS_AUTH_REMOTE
* @var integer
*/
var $authentic = null;
 
/**
* Defines the type of the accounting request, on of:
* RADIUS_START, RADIUS_STOP, RADIUS_ACCOUNTING_ON, RADIUS_ACCOUNTING_OFF
* @var integer
*/
var $status_type = null;
 
/**
* The time the user was logged in in seconds
* @var integer
*/
var $session_time = null;
 
/**
* A uniq identifier for the session of the user, maybe the PHP-Session-Id
* @var string
*/
var $session_id = null;
/**
* Constructor
*
* Generates a predefined session_id. We use the Remote-Address, the PID, and the Current user.
* @return void
*/
function Auth_RADIUS_Acct()
{
$this->Auth_RADIUS();
if (isset($_SERVER)) {
$var = &$_SERVER;
} else {
$var = &$GLOBALS['HTTP_SERVER_VARS'];
}
 
$this->session_id = sprintf("%s:%d-%s", isset($var['REMOTE_ADDR']) ? $var['REMOTE_ADDR'] : '127.0.0.1' , getmypid(), get_current_user());
}
 
/**
* Creates a RADIUS resource
*
* Creates a RADIUS resource for accounting. This should be the first
* call before you make any other things with the library.
*
* @return bool true on success, false on error
*/
function open()
{
$this->res = radius_acct_open();
if (!$this->res) {
return false;
}
return true;
}
 
/**
* Creates an accounting request
*
* Creates an accounting request.
* You MUST call this method before you can put any attribute.
*
* @return bool true on success, false on error
*/
function createRequest()
{
if (!radius_create_request($this->res, RADIUS_ACCOUNTING_REQUEST)) {
return false;
}
return true;
}
/**
* Put attributes for accounting.
*
* Here we put some accounting values. There many more attributes for accounting,
* but for web-applications only certain attributes make sense.
* @return void
*/
function putAuthAttributes()
{
$this->putAttribute(RADIUS_ACCT_SESSION_ID, $this->session_id);
$this->putAttribute(RADIUS_ACCT_STATUS_TYPE, $this->status_type);
if (isset($this->session_time) && $this->status_type == RADIUS_STOP) {
$this->putAttribute(RADIUS_ACCT_SESSION_TIME, $this->session_time);
}
if (isset($this->authentic)) {
$this->putAttribute(RADIUS_ACCT_AUTHENTIC, $this->authentic);
}
}
}
 
/**
* class Auth_RADIUS_Acct_Start
*
* Class for RADIUS accounting. Its usualy used, after the user has logged in.
*
* @package Auth_RADIUS
*/
class Auth_RADIUS_Acct_Start extends Auth_RADIUS_Acct
{
/**
* Defines the type of the accounting request.
* It is set to RADIUS_START by default in this class.
* @var integer
*/
var $status_type = Auth_RADIUS_Acct_Stop;
}
 
/**
* class Auth_RADIUS_Acct_Start
*
* Class for RADIUS accounting. Its usualy used, after the user has logged out.
*
* @package Auth_RADIUS
*/
class Auth_RADIUS_Acct_Stop extends Auth_RADIUS_Acct
{
/**
* Defines the type of the accounting request.
* It is set to RADIUS_STOP by default in this class.
* @var integer
*/
var $status_type = RADIUS_STOP;
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container/LDAP.php
New file
0,0 → 1,472
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Jan Wagner <wagner@netsols.de> |
// +----------------------------------------------------------------------+
//
// $Id: LDAP.php,v 1.14 2003/06/02 16:55:10 mj Exp $
//
 
require_once "Auth/Container.php";
require_once "PEAR.php";
 
/**
* Storage driver for fetching login data from LDAP
*
* This class is heavily based on the DB and File containers. By default it
* connects to localhost:389 and searches for uid=$username with the scope
* "sub". If no search base is specified, it will try to determine it via
* the namingContexts attribute. It takes its parameters in a hash, connects
* to the ldap server, binds anonymously, searches for the user, and tries
* to bind as the user with the supplied password. When a group was set, it
* will look for group membership of the authenticated user. If all goes
* well the authentication was successful.
*
* Parameters:
*
* host: localhost (default), ldap.netsols.de or 127.0.0.1
* port: 389 (default) or 636 or whereever your server runs
* url: ldap://localhost:389/
* useful for ldaps://, works only with openldap2 ?
* it will be preferred over host and port
* binddn: If set, searching for user will be done after binding
* as this user, if not set the bind will be anonymous.
* This is reported to make the container work with MS
* Active Directory, but should work with any server that
* is configured this way.
* This has to be a complete dn for now (basedn and
* userdn will not be appended).
* bindpw: The password to use for binding with binddn
* scope: one, sub (default), or base
* basedn: the base dn of your server
* userdn: gets prepended to basedn when searching for user
* userattr: the user attribute to search for (default: uid)
* useroc: objectclass of user (for the search filter)
* (default: posixAccount)
* groupdn: gets prepended to basedn when searching for group
* groupattr : the group attribute to search for (default: cn)
* groupoc : objectclass of group (for the search filter)
* (default: groupOfUniqueNames)
* memberattr : the attribute of the group object where the user dn
* may be found (default: uniqueMember)
* memberisdn: whether the memberattr is the dn of the user (default)
* or the value of userattr (usually uid)
* group: the name of group to search for
* debug: Enable/Disable debugging output (default: false)
*
* To use this storage container, you have to use the following syntax:
*
* <?php
* ...
*
* $a = new Auth("LDAP", array(
* 'host' => 'localhost',
* 'port' => '389',
* 'basedn' => 'o=netsols,c=de',
* 'userattr' => 'uid'
* 'binddn' => 'cn=admin,o=netsols,c=de',
* 'bindpw' => 'password'));
*
* $a2 = new Auth('LDAP', array(
* 'url' => 'ldaps://ldap.netsols.de',
* 'basedn' => 'o=netsols,c=de',
* 'scope' => 'one',
* 'userdn' => 'ou=People',
* 'groupdn' => 'ou=Groups',
* 'groupoc' => 'posixGroup',
* 'memberattr' => 'memberUid',
* 'memberisdn' => false,
* 'group' => 'admin'
* ));
*
* $a3 = new Auth('LDAP', array(
* 'host' => 'ad.netsols.de',
* 'basedn' => 'dc=netsols,dc=de',
* 'userdn' => 'ou=Users',
* 'binddn' => 'cn=Jan Wagner,ou=Users,dc=netsols,dc=de',
* 'bindpw' => '*******',
* 'userattr' => 'samAccountName',
* 'useroc' => 'user',
* 'debug' => true
* ));
*
* The parameter values have to correspond
* to the ones for your LDAP server of course.
*
* When talking to a Microsoft ActiveDirectory server you have to
* use 'samaccountname' as the 'userattr' and follow special rules
* to translate the ActiveDirectory directory names into 'basedn'.
* The 'basedn' for the default 'Users' folder on an ActiveDirectory
* server for the ActiveDirectory Domain (which is not related to
* its DNS name) "win2000.example.org" would be:
* "CN=Users, DC=win2000, DC=example, DC=org'
* where every component of the domain name becomes a DC attribute
* of its own. If you want to use a custom users folder you have to
* replace "CN=Users" with a sequence of "OU" attributes that specify
* the path to your custom folder in reverse order.
* So the ActiveDirectory folder
* "win2000.example.org\Custom\Accounts"
* would become
* "OU=Accounts, OU=Custom, DC=win2000, DC=example, DC=org'
*
* It seems that binding anonymously to an Active Directory
* is not allowed, so you have to set binddn and bindpw for
* user searching,
*
* Example a3 shows a tested example for connenction to Windows 2000
* Active Directory
*
* @author Jan Wagner <wagner@netsols.de>
* @package Auth
* @version $Revision: 1.14 $
*/
class Auth_Container_LDAP extends Auth_Container
{
/**
* Options for the class
* @var array
*/
var $options = array();
 
/**
* Connection ID of LDAP Link
* @var string
*/
var $conn_id = false;
 
/**
* LDAP search function to use
* @var string
*/
var $ldap_search_func;
 
/**
* Constructor of the container class
*
* @param $params, associative hash with host,port,basedn and userattr key
* @return object Returns an error object if something went wrong
*/
function Auth_Container_LDAP($params)
{
$this->_setDefaults();
 
if (is_array($params)) {
$this->_parseOptions($params);
}
}
 
// }}}
// {{{ _connect()
 
/**
* Connect to the LDAP server using the global options
*
* @access private
* @return object Returns a PEAR error object if an error occurs.
*/
function _connect()
{
// connect
if (isset($this->options['url']) && $this->options['url'] != '') {
$this->_debug('Connecting with URL', __LINE__);
$conn_params = array($this->options['url']);
} else {
$this->_debug('Connecting with host:port', __LINE__);
$conn_params = array($this->options['host'], $this->options['port']);
}
 
if(($this->conn_id = @call_user_func_array('ldap_connect', $conn_params)) === false) {
return PEAR::raiseError('Auth_Container_LDAP: Could not connect to server.', 41, PEAR_ERROR_DIE);
}
$this->_debug('Successfully connected to server', __LINE__);
 
// try switchig to LDAPv3
$ver = 0;
if(@ldap_get_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $ver) && $ver >= 2) {
$this->_debug('Switching to LDAPv3', __LINE__);
@ldap_set_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, 3);
}
 
// bind with credentials or anonymously
if($this->options['binddn'] && $this->options['bindpw']) {
$this->_debug('Binding with credentials', __LINE__);
$bind_params = array($this->conn_id, $this->options['binddn'], $this->options['bindpw']);
} else {
$this->_debug('Binding anonymously', __LINE__);
$bind_params = array($this->conn_id);
}
// bind for searching
if ((@call_user_func_array('ldap_bind', $bind_params)) == false) {
$this->_debug();
$this->_disconnect();
return PEAR::raiseError("Auth_Container_LDAP: Could not bind to LDAP server.", 41, PEAR_ERROR_DIE);
}
$this->_debug('Binding was successful', __LINE__);
}
 
/**
* Disconnects (unbinds) from ldap server
*
* @access private
*/
function _disconnect()
{
if($this->_isValidLink()) {
$this->_debug('disconnecting from server');
@ldap_unbind($this->conn_id);
}
}
 
/**
* Tries to find Basedn via namingContext Attribute
*
* @access private
*/
function _getBaseDN()
{
if ($this->options['basedn'] == "" && $this->_isValidLink()) {
$this->_debug("basedn not set, searching via namingContexts.", __LINE__);
 
$result_id = @ldap_read($this->conn_id, "", "(objectclass=*)", array("namingContexts"));
if (ldap_count_entries($this->conn_id, $result_id) == 1) {
$this->_debug("got result for namingContexts", __LINE__);
$entry_id = ldap_first_entry($this->conn_id, $result_id);
$attrs = ldap_get_attributes($this->conn_id, $entry_id);
$basedn = $attrs['namingContexts'][0];
 
if ($basedn != "") {
$this->_debug("result for namingContexts was $basedn", __LINE__);
$this->options['basedn'] = $basedn;
}
}
ldap_free_result($result_id);
}
 
// if base ist still not set, raise error
if ($this->options['basedn'] == "") {
return PEAR::raiseError("Auth_Container_LDAP: LDAP search base not specified!", 41, PEAR_ERROR_DIE);
}
return true;
}
 
/**
* determines whether there is a valid ldap conenction or not
*
* @accessd private
* @return boolean
*/
function _isValidLink()
{
if(is_resource($this->conn_id)) {
if(get_resource_type($this->conn_id) == 'ldap link') {
return true;
}
}
return false;
}
 
/**
* Set some default options
*
* @access private
*/
function _setDefaults()
{
$this->options['host'] = 'localhost';
$this->options['port'] = '389';
$this->options['binddn'] = '';
$this->options['bindpw'] = '';
$this->options['scope'] = 'sub';
$this->options['basedn'] = '';
$this->options['userdn'] = '';
$this->options['userattr'] = "uid";
$this->options['useroc'] = 'posixAccount';
$this->options['groupdn'] = '';
$this->options['groupattr'] = 'cn';
$this->options['groupoc'] = 'groupOfUniqueNames';
$this->options['memberattr'] = 'uniqueMember';
$this->options['memberisdn'] = true;
$this->options['debug'] = false;
}
 
/**
* Parse options passed to the container class
*
* @access private
* @param array
*/
function _parseOptions($array)
{
foreach ($array as $key => $value) {
$this->options[$key] = $value;
}
 
// get the according search function for selected scope
switch($this->options['scope']) {
case 'one':
$this->ldap_search_func = 'ldap_list';
break;
case 'base':
$this->ldap_search_func = 'ldap_read';
break;
default:
$this->ldap_search_func = 'ldap_search';
break;
}
$this->_debug("LDAP search function will be: {$this->ldap_search_func}", __LINE__);
}
 
/**
* Fetch data from LDAP server
*
* Searches the LDAP server for the given username/password
* combination.
*
* @param string Username
* @param string Password
* @return boolean
*/
function fetchData($username, $password)
{
 
$this->_connect();
$this->_getBaseDN();
// make search filter
$filter = sprintf('(&(objectClass=%s)(%s=%s))', $this->options['useroc'], $this->options['userattr'], $username);
 
// make search base dn
$search_basedn = $this->options['userdn'];
if ($search_basedn != '' && substr($search_basedn, -1) != ',') {
$search_basedn .= ',';
}
$search_basedn .= $this->options['basedn'];
// make functions params array
$func_params = array($this->conn_id, $search_basedn, $filter, array($this->options['userattr']));
 
$this->_debug("Searching with $filter in $search_basedn", __LINE__);
 
// search
if (($result_id = @call_user_func_array($this->ldap_search_func, $func_params)) == false) {
$this->_debug('User not found', __LINE__);
} elseif (ldap_count_entries($this->conn_id, $result_id) == 1) { // did we get just one entry?
 
$this->_debug('User was found', __LINE__);
// then get the user dn
$entry_id = ldap_first_entry($this->conn_id, $result_id);
$user_dn = ldap_get_dn($this->conn_id, $entry_id);
 
ldap_free_result($result_id);
 
// need to catch an empty password as openldap seems to return TRUE
// if anonymous binding is allowed
if ($password != "") {
$this->_debug("Bind as $user_dn", __LINE__);
 
// try binding as this user with the supplied password
if (@ldap_bind($this->conn_id, $user_dn, $password)) {
$this->_debug('Bind successful', __LINE__);
 
// check group if appropiate
if(isset($this->options['group'])) {
// decide whether memberattr value is a dn or the username
$this->_debug('Checking group membership', __LINE__);
return $this->checkGroup(($this->options['memberisdn']) ? $user_dn : $username);
} else {
$this->_debug('Authenticated', __LINE__);
$this->_disconnect();
return true; // user authenticated
} // checkGroup
} // bind
} // non-empty password
} // one entry
// default
$this->_debug('NOT authenticated!', __LINE__);
$this->_disconnect();
return false;
}
 
/**
* Validate group membership
*
* Searches the LDAP server for group membership of the
* authenticated user
*
* @param string Distinguished Name of the authenticated User
* @return boolean
*/
function checkGroup($user)
{
// make filter
$filter = sprintf('(&(%s=%s)(objectClass=%s)(%s=%s))',
$this->options['groupattr'],
$this->options['group'],
$this->options['groupoc'],
$this->options['memberattr'],
$user
);
 
// make search base dn
$search_basedn = $this->options['groupdn'];
if($search_basedn != '' && substr($search_basedn, -1) != ',') {
$search_basedn .= ',';
}
$search_basedn .= $this->options['basedn'];
$func_params = array($this->conn_id, $search_basedn, $filter, array($this->options['memberattr']));
 
$this->_debug("Searching with $filter in $search_basedn", __LINE__);
// search
if(($result_id = @call_user_func_array($this->ldap_search_func, $func_params)) != false) {
if(ldap_count_entries($this->conn_id, $result_id) == 1) {
ldap_free_result($result_id);
$this->_debug('User is member of group', __LINE__);
$this->_disconnect();
return true;
}
}
 
// default
$this->_debug('User is NOT member of group', __LINE__);
$this->_disconnect();
return false;
}
 
/**
* Outputs debugging messages
*
* @access private
* @param string Debugging Message
* @param integer Line number
*/
function _debug($msg = '', $line = 0)
{
if($this->options['debug'] === true) {
if($msg == '' && $this->_isValidLink()) {
$msg = 'LDAP_Error: ' . @ldap_err2str(@ldap_errno($this->_conn_id));
}
print("$line: $msg <br />");
}
}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container/POP3.php
New file
0,0 → 1,107
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Stefan Ekman <stekman@sedata.org> |
// | Martin Jansen <mj@php.net> |
// | Mika Tuupola <tuupola@appelsiini.net> |
// +----------------------------------------------------------------------+
//
// $Id: POP3.php,v 1.3 2003/07/28 21:39:39 yavo Exp $
//
 
 
require_once('Auth/Container.php');
require_once('PEAR.php');
require_once('Net/POP3.php');
 
/**
* Storage driver for Authentication on a POP3 server.
*
* @author Yavor Shahpasov <yavo@netsmart.com.cy>
* @package Auth
* @version $Revision: 1.3 $
*/
class Auth_Container_POP3 extends Auth_Container
{
/**
* POP3 Server
* @var string
*/
var $server='localhost';
 
/**
* POP3 Server port
* @var string
*/
var $port='110';
 
// {{{ Constructor
 
/**
* Constructor of the container class
*
* @param $server string server or server:port combination
* @return object Returns an error object if something went wrong
*/
function Auth_Container_POP3($server=null)
{
if(isset($server)){
if(is_array($server)){
if(isset($server['host'])){
$this->server = $server['host'];
}
if(isset($server['port'])){
$this->port = $server['port'];
}
}
else{
if(strstr($server, ':')){
$serverparts = explode(':', trim($server));
$this->server = $serverparts[0];
$this->port = $serverparts[1];
}
else
{
$this->server = $server;
}
}
}
}
 
// }}}
// {{{ fetchData()
 
/**
* Try to login to the POP3 server
*
* @param string Username
* @param string Password
* @return boolean
*/
function fetchData($username, $password)
{
$pop3 =& new Net_POP3();
$res = $pop3->connect($this->server, $this->port);
if(!$res){
return($res);
}
$result = $pop3->login($username, $password);
$pop3->disconnect();
return $result;
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container/MDB.php
New file
0,0 → 1,392
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Lorenzo Alberton <l.alberton@quipo.it> |
// +----------------------------------------------------------------------+
//
// $Id: MDB.php,v 1.12 2003/10/13 08:08:45 yavo Exp $
//
 
require_once 'Auth/Container.php';
require_once 'MDB.php';
 
/**
* Storage driver for fetching login data from a database
*
* This storage driver can use all databases which are supported
* by the PEAR MDB abstraction layer to fetch login data.
*
* @author Lorenzo Alberton <l.alberton@quipo.it>
* @package Auth
* @version $Revision: 1.12 $
*/
class Auth_Container_MDB extends Auth_Container
{
 
/**
* Additional options for the storage container
* @var array
*/
var $options = array();
 
/**
* DB object
* @var object
*/
var $db = null;
var $dsn = '';
 
/**
* User that is currently selected from the DB.
* @var string
*/
var $activeUser = '';
 
// {{{ Constructor
 
/**
* Constructor of the container class
*
* Initate connection to the database via PEAR::DB
*
* @param string Connection data or DB object
* @return object Returns an error object if something went wrong
*/
function Auth_Container_MDB($dsn)
{
$this->_setDefaults();
 
if (is_array($dsn)) {
$this->_parseOptions($dsn);
if (empty($this->options['dsn'])) {
PEAR::raiseError('No connection parameters specified!');
}
} else {
$this->options['dsn'] = $dsn;
}
}
 
// }}}
// {{{ _connect()
 
/**
* Connect to database by using the given DSN string
*
* @access private
* @param string DSN string
* @return mixed Object on error, otherwise bool
*/
function _connect($dsn)
{
if (is_string($dsn) || is_array($dsn)) {
$this->db =& MDB::Connect($dsn);
} elseif (get_parent_class($dsn) == "mdb_common") {
$this->db = $dsn;
} elseif (is_object($dsn) && MDB::isError($dsn)) {
return PEAR::raiseError($dsn->getMessage(), $dsn->code);
} else {
return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
41,
PEAR_ERROR_RETURN,
null,
null
);
 
}
 
if (MDB::isError($this->db) || PEAR::isError($this->db)) {
return PEAR::raiseError($this->db->getMessage(), $this->db->code);
} else {
return true;
}
}
 
// }}}
// {{{ _prepare()
 
/**
* Prepare database connection
*
* This function checks if we have already opened a connection to
* the database. If that's not the case, a new connection is opened.
*
* @access private
* @return mixed True or a DB error object.
*/
function _prepare()
{
return $this->_connect($this->options['dsn']);
}
 
// }}}
// {{{ query()
 
/**
* Prepare query to the database
*
* This function checks if we have already opened a connection to
* the database. If that's not the case, a new connection is opened.
* After that the query is passed to the database.
*
* @access public
* @param string Query string
* @return mixed a MDB_result object or MDB_OK on success, a MDB
* or PEAR error on failure
*/
function query($query)
{
$err = $this->_prepare();
if ($err !== true) {
return $err;
}
return $this->db->query($query);
}
 
// }}}
// {{{ _setDefaults()
 
/**
* Set some default options
*
* @access private
* @return void
*/
function _setDefaults()
{
$this->options['table'] = 'auth';
$this->options['usernamecol'] = 'username';
$this->options['passwordcol'] = 'password';
$this->options['dsn'] = '';
$this->options['db_fields'] = '';
$this->options['cryptType'] = 'md5';
}
 
// }}}
// {{{ _parseOptions()
 
/**
* Parse options passed to the container class
*
* @access private
* @param array
*/
function _parseOptions($array)
{
foreach ($array as $key => $value) {
if (isset($this->options[$key])) {
$this->options[$key] = $value;
}
}
 
// Include additional fields if they exist
if (!empty($this->options['db_fields'])) {
if (is_array($this->options['db_fields'])) {
$this->options['db_fields'] = join($this->options['db_fields'], ', ');
}
$this->options['db_fields'] = ', ' . $this->options['db_fields'];
}
 
}
 
// }}}
// {{{ fetchData()
 
/**
* Get user information from database
*
* This function uses the given username to fetch
* the corresponding login data from the database
* table. If an account that matches the passed username
* and password is found, the function returns true.
* Otherwise it returns false.
*
* @param string Username
* @param string Password
* @return mixed Error object or boolean
*/
function fetchData($username, $password)
{
// Prepare for a database query
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
}
 
// Find if db_fileds contains a *, i so assume all col are selected
if (strstr($this->options['db_fields'], '*')) {
$sql_from = '*';
} else{
$sql_from = $this->options['usernamecol'] . ', '. $this->options['passwordcol'] . $this->options['db_fields'];
}
 
$query = sprintf("SELECT %s FROM %s WHERE %s = %s",
$sql_from,
$this->options['table'],
$this->options['usernamecol'],
$this->db->getTextValue($username)
);
 
$res = $this->db->getRow($query, null, null, null, MDB_FETCHMODE_ASSOC);
 
if (MDB::isError($res) || PEAR::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->getCode());
}
if (!is_array($res)) {
$this->activeUser = '';
return false;
}
if ($this->verifyPassword(trim($password, "\r\n"),
trim($res[$this->options['passwordcol']], "\r\n"),
$this->options['cryptType'])) {
// Store additional field values in the session
foreach ($res as $key => $value) {
if ($key == $this->options['passwordcol'] ||
$key == $this->options['usernamecol']) {
continue;
}
// Use reference to the auth object if exists
// This is because the auth session variable can change so a static call to setAuthData does not make sence
if(is_object($this->_auth_obj)){
$this->_auth_obj->setAuthData($key, $value);
} else {
Auth::setAuthData($key, $value);
}
}
 
return true;
}
 
$this->activeUser = $res[$this->options['usernamecol']];
return false;
}
 
// }}}
// {{{ listUsers()
 
function listUsers()
{
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
}
 
$retVal = array();
 
// Find if db_fileds contains a *, i so assume all col are selected
if (strstr($this->options['db_fields'], '*')) {
$sql_from = '*';
} else{
$sql_from = $this->options['db_fields'];
}
 
$query = sprintf('SELECT %s FROM %s',
$sql_from,
$this->options['table']
);
 
$res = $this->db->getAll($query, null, null, null, MDB_FETCHMODE_ASSOC);
 
if (MDB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->getCode());
} else {
foreach ($res as $user) {
$user['username'] = $user[$this->options['usernamecol']];
$retVal[] = $user;
}
}
return $retVal;
}
 
// }}}
// {{{ addUser()
 
/**
* Add user to the storage container
*
* @access public
* @param string Username
* @param string Password
* @param mixed Additional information that are stored in the DB
*
* @return mixed True on success, otherwise error object
*/
function addUser($username, $password, $additional = "")
{
if (function_exists($this->options['cryptType'])) {
$cryptFunction = $this->options['cryptType'];
} else {
$cryptFunction = 'md5';
}
 
$additional_key = '';
$additional_value = '';
 
if (is_array($additional)) {
foreach ($additional as $key => $value) {
$additional_key .= ', ' . $key;
$additional_value .= ', ' . $this->db->getTextValue($value);
}
}
 
$query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)",
$this->options['table'],
$this->options['usernamecol'],
$this->options['passwordcol'],
$additional_key,
$this->db->getTextValue($username),
$this->db->getTextValue($cryptFunction($password)),
$additional_value
);
 
$res = $this->query($query);
 
if (MDB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->code);
} else {
return true;
}
}
 
// }}}
// {{{ removeUser()
 
/**
* Remove user from the storage container
*
* @access public
* @param string Username
*
* @return mixed True on success, otherwise error object
*/
function removeUser($username)
{
$query = sprintf("DELETE FROM %s WHERE %s = %s",
$this->options['table'],
$this->options['usernamecol'],
$this->db->getTextValue($username)
);
 
$res = $this->query($query);
 
if (MDB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->code);
} else {
return true;
}
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container/SOAP.php
New file
0,0 → 1,170
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Bruno Pedro <bpedro@co.sapo.pt> |
// +----------------------------------------------------------------------+
//
// $Id: SOAP.php,v 1.6 2003/09/08 11:24:05 yavo Exp $
//
 
require_once "Auth/Container.php";
require_once "PEAR.php";
require_once 'SOAP/Client.php';
 
/**
* Storage driver for fetching login data from SOAP
*
* This class takes one parameter (options), where
* you specify the following fields: endpoint, namespace,
* method, encoding, usernamefield and passwordfield.
*
* You can use specify features of your SOAP service
* by providing its parameters in an associative manner by
* using the '_features' array through the options parameter.
*
* The 'matchpassword' option should be set to false if your
* webservice doesn't return (username,password) pairs, but
* instead returns error when the login is invalid.
*
* Example usage:
*
* <?php
*
* ...
*
* $options = array (
* 'endpoint' => 'http://your.soap.service/endpoint',
* 'namespace' => 'urn:/Your/Namespace',
* 'method' => 'get',
* 'encoding' => 'UTF-8',
* 'usernamefield' => 'login',
* 'passwordfield' => 'password',
* 'matchpasswords' => false,
* '_features' => array (
* 'example_feature' => 'example_value',
* 'another_example' => ''
* )
* );
* $auth = new Auth('SOAP', $options, 'loginFunction');
* $auth->start();
*
* ...
*
* ?>
*
* @author Bruno Pedro <bpedro@co.sapo.pt>
* @package Auth
* @version $Revision: 1.6 $
*/
class Auth_Container_SOAP extends Auth_Container
{
 
/**
* Required options for the class
* @var array
* @access private
*/
var $_requiredOptions = array('endpoint', 'namespace', 'method', 'encoding', 'usernamefield', 'passwordfield');
 
/**
* Options for the class
* @var array
* @access private
*/
var $_options = array();
 
/**
* Optional SOAP features
* @var array
* @access private
*/
var $_features = array();
 
/**
* The SOAP response
* @var array
* @access public
*/
var $soapResponse = array();
 
/**
* Constructor of the container class
*
* @param $options, associative array with endpoint, namespace, method,
* usernamefield, passwordfield and optional features
*/
function Auth_Container_SOAP($options)
{
$this->_options = $options;
if (!isset($this->_options['matchpasswords'])) {
$this->_options['matchpasswords'] = true;
}
if (!empty($this->_options['_features'])) {
$this->_features = $this->_options['_features'];
unset($this->_options['_features']);
}
}
 
/**
* Fetch data from SOAP service
*
* Requests the SOAP service for the given username/password
* combination.
*
* @param string Username
* @param string Password
* @return mixed Returns the SOAP response or false if something went wrong
*/
function fetchData($username, $password)
{
// check if all required options are set
if (array_intersect($this->_requiredOptions, array_keys($this->_options)) != $this->_requiredOptions) {
return false;
} else {
// create a SOAP client and set encoding
$soapClient = new SOAP_Client($this->_options['endpoint']);
$soapClient->setEncoding($this->_options['encoding']);
}
// assign username and password fields
$usernameField = new SOAP_Value($this->_options['usernamefield'],'string', $username);
$passwordField = new SOAP_Value($this->_options['passwordfield'],'string', $password);
$SOAPParams = array($usernameField, $passwordField);
// assign optional features
foreach ($this->_features as $fieldName => $fieldValue) {
$SOAPParams[] = new SOAP_Value($fieldName, 'string', $fieldValue);
}
// make SOAP call
$this->soapResponse = $soapClient->call(
$this->_options['method'],
$SOAPParams,
array('namespace' => $this->_options['namespace'])
);
if (!PEAR::isError($this->soapResponse)) {
if ($this->_options['matchpasswords']) {
// check if passwords match
if ($password == $this->soapResponse->{$this->_options['passwordfield']}) {
return true;
} else {
return false;
}
} else {
return true;
}
} else {
return false;
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container/SMBPasswd.php
New file
0,0 → 1,134
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Michael Bretterklieber <michael@bretterklieber.com> |
// +----------------------------------------------------------------------+
//
// $Id: SMBPasswd.php,v 1.1 2003/05/13 19:23:54 mbretter Exp $
//
 
require_once "File/SMBPasswd.php";
require_once "Auth/Container.php";
require_once "PEAR.php";
 
/**
* Storage driver for fetching login data from an SAMBA smbpasswd file.
*
* This storage container can handle SAMBA smbpasswd files.
*
* Example:
* $a = new Auth("SMBPasswd", '/usr/local/private/smbpasswd');
* $a->start();
* if ($a->getAuth()) {
* printf ("AUTH OK<br>\n");
* $a->logout();
* }
*
* @author Michael Bretterklieber <michael@bretterklieber.com>
* @package Auth
* @version $Revision: 1.1 $
*/
class Auth_Container_SMBPasswd extends Auth_Container
{
/**
* File_SMBPasswd object
* @var object
*/
var $pwfile;
 
// {{{ Constructor
 
/**
* Constructor of the container class
*
* @param $filename string filename for a passwd type file
* @return object Returns an error object if something went wrong
*/
function Auth_Container_SMBPasswd($filename)
{
$this->pwfile = new File_SMBPasswd($filename,0);
 
if (!$this->pwfile->load()) {
PEAR::raiseError("Error while reading file contents.", 41, PEAR_ERROR_DIE);
return;
}
 
}
 
// }}}
// {{{ fetchData()
 
/**
* Get user information from pwfile
*
* @param string Username
* @param string Password
* @return boolean
*/
function fetchData($username, $password)
{
return $this->pwfile->verifyAccount($username, $password);
}
 
// }}}
// {{{ listUsers()
function listUsers()
{
return $this->pwfile->getAccounts();
}
 
// }}}
// {{{ addUser()
 
/**
* Add a new user to the storage container
*
* @param string Username
* @param string Password
* @param array Additional information
*
* @return boolean
*/
function addUser($username, $password, $additional = '')
{
$res = $this->pwfile->addUser($user, $additional['userid'], $pass);
if ($res === true) {
return $this->pwfile->save();
}
return $res;
}
 
// }}}
// {{{ removeUser()
 
/**
* Remove user from the storage container
*
* @param string Username
*/
function removeUser($username)
{
$res = $this->pwfile->delUser($username);
if ($res === true) {
return $this->pwfile->save();
}
return $res;
}
 
// }}}
 
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container/DB.php
New file
0,0 → 1,409
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Martin Jansen <mj@php.net> |
// +----------------------------------------------------------------------+
//
// $Id: DB.php,v 1.40 2003/11/15 13:37:26 yavo Exp $
//
 
require_once 'Auth/Container.php';
require_once 'DB.php';
 
/**
* Storage driver for fetching login data from a database
*
* This storage driver can use all databases which are supported
* by the PEAR DB abstraction layer to fetch login data.
*
* @author Martin Jansen <mj@php.net>
* @package Auth
* @version $Revision: 1.40 $
*/
class Auth_Container_DB extends Auth_Container
{
 
/**
* Additional options for the storage container
* @var array
*/
var $options = array();
 
/**
* DB object
* @var object
*/
var $db = null;
var $dsn = '';
 
/**
* User that is currently selected from the DB.
* @var string
*/
var $activeUser = '';
 
// {{{ Constructor
 
/**
* Constructor of the container class
*
* Initate connection to the database via PEAR::DB
*
* @param string Connection data or DB object
* @return object Returns an error object if something went wrong
*/
function Auth_Container_DB($dsn)
{
$this->_setDefaults();
 
if (is_array($dsn)) {
$this->_parseOptions($dsn);
 
if (empty($this->options['dsn'])) {
PEAR::raiseError('No connection parameters specified!');
}
} else {
$this->options['dsn'] = $dsn;
}
}
 
// }}}
// {{{ _connect()
 
/**
* Connect to database by using the given DSN string
*
* @access private
* @param string DSN string
* @return mixed Object on error, otherwise bool
*/
function _connect($dsn)
{
if (is_string($dsn) || is_array($dsn)) {
$this->db = DB::Connect($dsn);
} elseif (get_parent_class($dsn) == "db_common") {
$this->db = $dsn;
} elseif (DB::isError($dsn)) {
return PEAR::raiseError($dsn->getMessage(), $dsn->getCode());
} else {
return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
41,
PEAR_ERROR_RETURN,
null,
null
);
}
 
if (DB::isError($this->db) || PEAR::isError($this->db)) {
return PEAR::raiseError($this->db->getMessage(), $this->db->getCode());
} else {
return true;
}
}
 
// }}}
// {{{ _prepare()
 
/**
* Prepare database connection
*
* This function checks if we have already opened a connection to
* the database. If that's not the case, a new connection is opened.
*
* @access private
* @return mixed True or a DB error object.
*/
function _prepare()
{
if (!DB::isConnection($this->db)) {
$res = $this->_connect($this->options['dsn']);
if(DB::isError($res) || PEAR::isError($res)){
return $res;
}
}
return true;
}
 
// }}}
// {{{ query()
 
/**
* Prepare query to the database
*
* This function checks if we have already opened a connection to
* the database. If that's not the case, a new connection is opened.
* After that the query is passed to the database.
*
* @access public
* @param string Query string
* @return mixed a DB_result object or DB_OK on success, a DB
* or PEAR error on failure
*/
function query($query)
{
$err = $this->_prepare();
if ($err !== true) {
return $err;
}
return $this->db->query($query);
}
 
// }}}
// {{{ _setDefaults()
 
/**
* Set some default options
*
* @access private
* @return void
*/
function _setDefaults()
{
$this->options['table'] = 'auth';
$this->options['usernamecol'] = 'username';
$this->options['passwordcol'] = 'password';
$this->options['dsn'] = '';
$this->options['db_fields'] = '';
$this->options['cryptType'] = 'md5';
}
 
// }}}
// {{{ _parseOptions()
 
/**
* Parse options passed to the container class
*
* @access private
* @param array
*/
function _parseOptions($array)
{
foreach ($array as $key => $value) {
if (isset($this->options[$key])) {
$this->options[$key] = $value;
}
}
 
/* Include additional fields if they exist */
if(!empty($this->options['db_fields'])){
if(is_array($this->options['db_fields'])){
$this->options['db_fields'] = join($this->options['db_fields'], ', ');
}
$this->options['db_fields'] = ', '.$this->options['db_fields'];
}
}
 
// }}}
// {{{ fetchData()
 
/**
* Get user information from database
*
* This function uses the given username to fetch
* the corresponding login data from the database
* table. If an account that matches the passed username
* and password is found, the function returns true.
* Otherwise it returns false.
*
* @param string Username
* @param string Password
* @return mixed Error object or boolean
*/
function fetchData($username, $password)
{
// Prepare for a database query
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
}
 
// Find if db_fileds contains a *, i so assume all col are selected
if(strstr($this->options['db_fields'], '*')){
$sql_from = "*";
}
else{
$sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
}
/**
Old Style, removed to go around the oci8
problem
See bug 206
http://pear.php.net/bugs/bug.php?id=206
$query = "SELECT ! FROM ! WHERE ! = ?";
$query_params = array(
$sql_from,
$this->options['table'],
$this->options['usernamecol'],
$username
);
*/
$query = "SELECT ".$sql_from.
" FROM ".$this->options['table'].
" WHERE ".$this->options['usernamecol']." = '".$this->db->quoteString($username)."'";
$res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC);
 
if (DB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->getCode());
}
if (!is_array($res)) {
$this->activeUser = '';
return false;
}
if ($this->verifyPassword(trim($password, "\r\n"),
trim($res[$this->options['passwordcol']], "\r\n"),
$this->options['cryptType'])) {
// Store additional field values in the session
foreach ($res as $key => $value) {
if ($key == $this->options['passwordcol'] ||
$key == $this->options['usernamecol']) {
continue;
}
// Use reference to the auth object if exists
// This is because the auth session variable can change so a static call to setAuthData does not make sence
if(is_object($this->_auth_obj)){
$this->_auth_obj->setAuthData($key, $value);
} else {
Auth::setAuthData($key, $value);
}
}
 
return true;
}
 
$this->activeUser = $res[$this->options['usernamecol']];
return false;
}
 
// }}}
// {{{ listUsers()
 
function listUsers()
{
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
}
 
$retVal = array();
 
// Find if db_fileds contains a *, i so assume all col are selected
if(strstr($this->options['db_fields'], '*')){
$sql_from = "*";
}
else{
$sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
}
 
$query = sprintf("SELECT %s FROM %s",
$sql_from,
$this->options['table']
);
$res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC);
 
if (DB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->getCode());
} else {
foreach ($res as $user) {
$user['username'] = $user[$this->options['usernamecol']];
$retVal[] = $user;
}
}
return $retVal;
}
 
// }}}
// {{{ addUser()
 
/**
* Add user to the storage container
*
* @access public
* @param string Username
* @param string Password
* @param mixed Additional information that are stored in the DB
*
* @return mixed True on success, otherwise error object
*/
function addUser($username, $password, $additional = "")
{
if (function_exists($this->options['cryptType'])) {
$cryptFunction = $this->options['cryptType'];
} else {
$cryptFunction = 'md5';
}
 
$additional_key = '';
$additional_value = '';
 
if (is_array($additional)) {
foreach ($additional as $key => $value) {
$additional_key .= ', ' . $key;
$additional_value .= ", '" . $value . "'";
}
}
 
$query = sprintf("INSERT INTO %s (%s, %s%s) VALUES ('%s', '%s'%s)",
$this->options['table'],
$this->options['usernamecol'],
$this->options['passwordcol'],
$additional_key,
$username,
$cryptFunction($password),
$additional_value
);
 
$res = $this->query($query);
 
if (DB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->getCode());
} else {
return true;
}
}
 
// }}}
// {{{ removeUser()
 
/**
* Remove user from the storage container
*
* @access public
* @param string Username
*
* @return mixed True on success, otherwise error object
*/
function removeUser($username)
{
$query = sprintf("DELETE FROM %s WHERE %s = '%s'",
$this->options['table'],
$this->options['usernamecol'],
$username
);
 
$res = $this->query($query);
 
if (DB::isError($res)) {
return PEAR::raiseError($res->getMessage(), $res->getCode());
} else {
return true;
}
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container/IMAP.php
New file
0,0 → 1,170
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Jeroen Houben <jeroen@terena.nl> |
// +----------------------------------------------------------------------+
//
// $Id: IMAP.php,v 1.7 2003/10/20 09:38:29 yavo Exp $
//
 
require_once "Auth/Container.php";
require_once "PEAR.php";
 
/**
* Storage driver for fetching login data from an IMAP server
*
* This class is based on LDAP containers, but it very simple.
* By default it connects to localhost:143
* The constructor will first check if the host:port combination is
* actually reachable. This behaviour can be disabled.
* It then tries to create an IMAP stream (without opening a mailbox)
* If you wish to pass extended options to the connections, you may
* do so by specifying protocol options.
*
* To use this storage containers, you have to use the
* following syntax:
*
* <?php
* ...
* $params = array(
* 'host' => 'mail.example.com',
* 'port' => 143,
* );
* $myAuth = new Auth('IMAP', $params);
* ....
*
* By default we connect without any protocol options set. However, some
* servers require you to connect with the notls or norsh options set.
* To do this you need to add the following value to the params array:
* 'baseDSN' => '/imap/notls/norsh'
*
* To connect to an SSL IMAP server:
* 'baseDSN' => '/imap/ssl'
*
* To connect to an SSL IMAP server with a self-signed certificate:
* 'baseDSN' => '/imap/ssl/novalidate-cert'
*
* Further options may be available and can be found on the php site at
* http://www.php.net/manual/function.imap-open.php
*
*/
 
/*
*
* @author Jeroen Houben <jeroen@terena.nl>, Cipriano Groenendal <cipri@campai.nl>
* @package Auth
* @version $Revision: 1.7 $
*/
class Auth_Container_IMAP extends Auth_Container
{
/**
* Options for the class
* @var array
*/
var $options = array();
 
/**
* Constructor of the container class
*
* @param $params, associative hash with host,port,basedn and userattr key
* @param $params, associative array with host, port, baseDSN, checkServer key.
* @return object Returns an error object if something went wrong
*/
function Auth_Container_IMAP($params)
{
if (!extension_loaded('imap')) {
return PEAR::raiseError("Cannot use IMAP authentication, IMAP extension not loaded!",
41, PEAR_ERROR_DIE);
}
$this->_setDefaults();
// set parameters (if any)
if (is_array($params)) {
$this->_parseOptions($params);
}
if ($this->options['checkServer']) {
$this->_checkServer($this->options['timeout']);
}
return true;
}
 
/**
* Set some default options
*
* @access private
*/
function _setDefaults()
{
$this->options['host'] = 'localhost';
$this->options['port'] = 143;
$this->options['baseDSN'] = '';
$this->options['checkServer'] = true;
$this->options['timeout'] = 20;
}
 
 
/**
* Check if the given server and port are reachable
*
* @access private
*/
function _checkServer() {
$fp = @fsockopen ($this->options['host'], $this->options['port'],
$errno, $errstr, $timeout);
if (is_resource($fp)) {
@fclose($fp);
} else {
$message = "Error connecting to IMAP server "
. $this->options['host']
. ":" . $this->options['port'];
return PEAR::raiseError($message, 41, PEAR_ERROR_DIE);
}
}
 
/**
* Parse options passed to the container class
*
* @access private
* @param array
*/
function _parseOptions($array)
{
foreach ($array as $key => $value) {
$this->options[$key] = $value;
}
}
 
/**
* Try to open a IMAP stream using $username / $password
*
* @param string Username
* @param string Password
* @return boolean
*/
function fetchData($username, $password)
{
$dsn = '{'.$this->options['host'].':'.$this->options['port'].$this->options['baseDSN'].'}';
$conn = @imap_open ($dsn, $username, $password, OP_HALFOPEN);
if (is_resource($conn)){
$this->activeUser = $username;
@imap_close($conn);
return true;
} else {
$this->activeUser = '';
return false;
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container/RADIUS.php
New file
0,0 → 1,154
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Michael Bretterklieber <michael@bretterklieber.com> |
// +----------------------------------------------------------------------+
//
// $Id: RADIUS.php,v 1.7 2003/05/13 19:27:35 mbretter Exp $
//
 
require_once "Auth/Container.php";
require_once "Auth/RADIUS.php";
 
/**
* Storage driver for authenticating users against RADIUS servers.
*
* @author Michael Bretterklieber <michael@bretterklieber.com>
* @access public
* @version $Revision: 1.7 $
*/
class Auth_Container_RADIUS extends Auth_Container
{
 
/**
* Contains a RADIUS object
* @var object
*/
var $radius;
/**
* Contains the authentication type
* @var string
*/
var $authtype;
 
/**
* Constructor of the container class.
*
* $options can have these keys:
* 'servers' an array containing an array: servername, port,
* sharedsecret, timeout, maxtries
* 'configfile' The filename of the configuration file
* 'authtype' The type of authentication, one of: PAP, CHAP_MD5,
* MSCHAPv1, MSCHAPv2, default is PAP
*
* @param $options associative array
* @return object Returns an error object if something went wrong
*/
function Auth_Container_RADIUS($options)
{
$this->authtype = 'PAP';
if (isset($options['authtype'])) {
$this->authtype = $options['authtype'];
}
$classname = 'Auth_RADIUS_' . $this->authtype;
if (!class_exists($classname)) {
PEAR::raiseError("Unknown Authtype, please use on of: PAP, CHAP_MD5, MSCHAPv1, MSCHAPv2!",
41, PEAR_ERROR_DIE);
}
$this->radius = new $classname;
 
if (isset($options['configfile'])) {
$this->radius->setConfigfile($options['configfile']);
}
 
$servers = $options['servers'];
if (is_array($servers)) {
foreach ($servers as $server) {
$servername = $server[0];
$port = isset($server[1]) ? $server[1] : 0;
$sharedsecret = isset($server[2]) ? $server[2] : 'testing123';
$timeout = isset($server[3]) ? $server[3] : 3;
$maxtries = isset($server[4]) ? $server[4] : 3;
$this->radius->addServer($servername, $port, $sharedsecret, $timeout, $maxtries);
}
}
if (!$this->radius->start()) {
PEAR::raiseError($this->radius->getError(), 41, PEAR_ERROR_DIE);
}
}
 
/**
* Authenticate
*
* @param string Username
* @param string Password
* @return bool true on success, false on reject
*/
function fetchData($username, $password, $challenge = null)
{
switch($this->authtype) {
case 'CHAP_MD5':
case 'MSCHAPv1':
if (isset($challenge)) {
echo $password;
$this->radius->challenge = $challenge;
$this->radius->chapid = 1;
$this->radius->response = pack('H*', $password);
} else {
require_once 'Crypt_CHAP/CHAP.php';
$classname = 'Crypt_' . $this->authtype;
$crpt = new $classname;
$crpt->password = $password;
$this->radius->challenge = $crpt->challenge;
$this->radius->chapid = $crpt->chapid;
$this->radius->response = $crpt->challengeResponse();
break;
}
 
case 'MSCHAPv2':
require_once 'Crypt_CHAP/CHAP.php';
$crpt = new Crypt_MSCHAPv2;
$crpt->username = $username;
$crpt->password = $password;
$this->radius->challenge = $crpt->authChallenge;
$this->radius->peerChallenge = $crpt->peerChallenge;
$this->radius->chapid = $crpt->chapid;
$this->radius->response = $crpt->challengeResponse();
break;
 
default:
$this->radius->password = $password;
break;
}
 
$this->radius->username = $username;
 
$this->radius->putAuthAttributes();
$result = $this->radius->send();
if (PEAR::isError($result)) {
return false;
}
 
$this->radius->getAttributes();
// just for debugging
// $this->radius->dumpAttributes();
 
return $result;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container/vpopmail.php
New file
0,0 → 1,66
<?PHP
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Stanislav Grozev <tacho@orbitel.bg> |
// +----------------------------------------------------------------------+
//
// $Id: vpopmail.php,v 1.3 2003/09/08 11:24:05 yavo Exp $
//
 
require_once "Auth/Container.php";
 
/**
* Storage driver for fetching login data from vpopmail
*
* @author Stanislav Grozev <tacho@orbitel.bg>
* @package Auth
* @version $Revision: 1.3 $
*/
class Auth_Container_vpopmail extends Auth_Container {
 
// {{{ Constructor
 
/**
* Constructor of the container class
*
* @return integer Always returns 1.
*/
function Auth_Container_vpopmail()
{
return 1;
}
 
// }}}
// {{{ fetchData()
 
/**
* Get user information from vpopmail
*
* @param string Username - has to be valid email address
* @param string Password
* @return boolean
*/
function fetchData($username, $password)
{
$userdata = array();
$userdata = preg_split("/@/", $username, 2);
$result = @vpopmail_auth_user($userdata[0], $userdata[1], $password);
 
return $result;
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container/File.php
New file
0,0 → 1,200
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Stefan Ekman <stekman@sedata.org> |
// | Martin Jansen <mj@php.net> |
// | Mika Tuupola <tuupola@appelsiini.net> |
// +----------------------------------------------------------------------+
//
// $Id: File.php,v 1.14 2003/10/29 13:42:40 mike Exp $
//
 
require_once "File/Passwd.php";
require_once "Auth/Container.php";
require_once "PEAR.php";
 
/**
* Storage driver for fetching login data from an encrypted password file.
*
* This storage container can handle CVS pserver style passwd files.
*
* @author Stefan Ekman <stekman@sedata.org>
* @author Michael Wallner <mike@php.net>
* @package Auth
* @version $Revision: 1.14 $
*/
class Auth_Container_File extends Auth_Container
{
/**
* Path to passwd file
*
* @var string
*/
var $pwfile = '';
 
// {{{ Constructor
 
/**
* Constructor of the container class
*
* @param string $filename path to passwd file
* @return object Auth_Container_File new Auth_Container_File object
*/
function Auth_Container_File($filename)
{
$this->pwfile = $filename;
}
 
// }}}
// {{{ fetchData()
 
/**
* Authenticate an user
*
* @param string username
* @param string password
* @return mixed boolean|PEAR_Error
*/
function fetchData($user, $pass)
{
return File_Passwd::staticAuth('Cvs', $this->pwfile, $user, $pass);
}
 
// }}}
// {{{ listUsers()
/**
* List all available users
*
* @return array
*/
function listUsers()
{
$pw_obj = &$this->_load();
if (PEAR::isError($pw_obj)) {
return array();
}
 
$users = $pw_obj->listUser();
if (!is_array($users)) {
return array();
}
 
foreach ($users as $key => $value) {
$retVal[] = array("username" => $key,
"password" => $value['passwd'],
"cvsuser" => $value['system']);
}
 
return $retVal;
}
 
// }}}
// {{{ addUser()
 
/**
* Add a new user to the storage container
*
* @param string username
* @param string password
* @param mixed CVS username
*
* @return boolean
*/
function addUser($user, $pass, $additional='')
{
$cvs = (string) (is_array($additional) && isset($additional['cvsuser'])) ?
$additional['cvsuser'] : $additional;
 
$pw_obj = &$this->_load();
if (PEAR::isError($pw_obj)) {
return false;
}
$res = $pw_obj->addUser($user, $pass, $cvs);
if(PEAR::isError($res)){
return false;
}
$res = $pw_obj->save();
if (PEAR::isError($res)) {
return false;
}
return true;
}
 
// }}}
// {{{ removeUser()
 
/**
* Remove user from the storage container
*
* @param string Username
* @return boolean
*/
function removeUser($user)
{
$pw_obj = &$this->_load();
if (PEAR::isError($pw_obj)) {
return false;
}
$res = $pw_obj->delUser($user);
if(PEAR::isError($res)){
return false;
}
$res = $pw_obj->save();
if (PEAR::isError($res)) {
return false;
}
return true;
}
 
// }}}
// {{{ _load()
/**
* Load and initialize the File_Passwd object
*
* @return object File_Passwd_Cvs|PEAR_Error
*/
function &_load()
{
static $pw_obj;
if (!isset($pw_obj)) {
$pw_obj = File_Passwd::factory('Cvs');
if (PEAR::isError($pw_obj)) {
return $pw_obj;
}
$pw_obj->setFile($this->pwfile);
$res = $pw_obj->load();
if (PEAR::isError($res)) {
return $res;
}
}
return $pw_obj;
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/SASL/DigestMD5.php
New file
0,0 → 1,198
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id: DigestMD5.php,v 1.8 2006/03/22 05:20:11 amistry Exp $
 
/**
* Implmentation of DIGEST-MD5 SASL mechanism
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
 
require_once('Auth/SASL/Common.php');
 
class Auth_SASL_DigestMD5 extends Auth_SASL_Common
{
/**
* Provides the (main) client response for DIGEST-MD5
* requires a few extra parameters than the other
* mechanisms, which are unavoidable.
*
* @param string $authcid Authentication id (username)
* @param string $pass Password
* @param string $challenge The digest challenge sent by the server
* @param string $hostname The hostname of the machine you're connecting to
* @param string $service The servicename (eg. imap, pop, acap etc)
* @param string $authzid Authorization id (username to proxy as)
* @return string The digest response (NOT base64 encoded)
* @access public
*/
function getResponse($authcid, $pass, $challenge, $hostname, $service, $authzid = '')
{
$challenge = $this->_parseChallenge($challenge);
$authzid_string = '';
if ($authzid != '') {
$authzid_string = ',authzid="' . $authzid . '"';
}
 
if (!empty($challenge)) {
$cnonce = $this->_getCnonce();
$digest_uri = sprintf('%s/%s', $service, $hostname);
$response_value = $this->_getResponseValue($authcid, $pass, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $authzid);
 
if ($challenge['realm']) {
return sprintf('username="%s",realm="%s"' . $authzid_string .
',nonce="%s",cnonce="%s",nc=00000001,qop=auth,digest-uri="%s",response=%s,maxbuf=%d', $authcid, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $response_value, $challenge['maxbuf']);
} else {
return sprintf('username="%s"' . $authzid_string . ',nonce="%s",cnonce="%s",nc=00000001,qop=auth,digest-uri="%s",response=%s,maxbuf=%d', $authcid, $challenge['nonce'], $cnonce, $digest_uri, $response_value, $challenge['maxbuf']);
}
} else {
return PEAR::raiseError('Invalid digest challenge');
}
}
/**
* Parses and verifies the digest challenge*
*
* @param string $challenge The digest challenge
* @return array The parsed challenge as an assoc
* array in the form "directive => value".
* @access private
*/
function _parseChallenge($challenge)
{
$tokens = array();
while (preg_match('/^([a-z-]+)=("[^"]+(?<!\\\)"|[^,]+)/i', $challenge, $matches)) {
 
// Ignore these as per rfc2831
if ($matches[1] == 'opaque' OR $matches[1] == 'domain') {
$challenge = substr($challenge, strlen($matches[0]) + 1);
continue;
}
 
// Allowed multiple "realm" and "auth-param"
if (!empty($tokens[$matches[1]]) AND ($matches[1] == 'realm' OR $matches[1] == 'auth-param')) {
if (is_array($tokens[$matches[1]])) {
$tokens[$matches[1]][] = preg_replace('/^"(.*)"$/', '\\1', $matches[2]);
} else {
$tokens[$matches[1]] = array($tokens[$matches[1]], preg_replace('/^"(.*)"$/', '\\1', $matches[2]));
}
 
// Any other multiple instance = failure
} elseif (!empty($tokens[$matches[1]])) {
$tokens = array();
break;
 
} else {
$tokens[$matches[1]] = preg_replace('/^"(.*)"$/', '\\1', $matches[2]);
}
 
// Remove the just parsed directive from the challenge
$challenge = substr($challenge, strlen($matches[0]) + 1);
}
 
/**
* Defaults and required directives
*/
// Realm
if (empty($tokens['realm'])) {
$tokens['realm'] = "";
}
 
// Maxbuf
if (empty($tokens['maxbuf'])) {
$tokens['maxbuf'] = 65536;
}
 
// Required: nonce, algorithm
if (empty($tokens['nonce']) OR empty($tokens['algorithm'])) {
return array();
}
 
return $tokens;
}
 
/**
* Creates the response= part of the digest response
*
* @param string $authcid Authentication id (username)
* @param string $pass Password
* @param string $realm Realm as provided by the server
* @param string $nonce Nonce as provided by the server
* @param string $cnonce Client nonce
* @param string $digest_uri The digest-uri= value part of the response
* @param string $authzid Authorization id
* @return string The response= part of the digest response
* @access private
*/
function _getResponseValue($authcid, $pass, $realm, $nonce, $cnonce, $digest_uri, $authzid = '')
{
if ($authzid == '') {
$A1 = sprintf('%s:%s:%s', pack('H32', md5(sprintf('%s:%s:%s', $authcid, $realm, $pass))), $nonce, $cnonce);
} else {
$A1 = sprintf('%s:%s:%s:%s', pack('H32', md5(sprintf('%s:%s:%s', $authcid, $realm, $pass))), $nonce, $cnonce, $authzid);
}
$A2 = 'AUTHENTICATE:' . $digest_uri;
return md5(sprintf('%s:%s:00000001:%s:auth:%s', md5($A1), $nonce, $cnonce, md5($A2)));
}
 
/**
* Creates the client nonce for the response
*
* @return string The cnonce value
* @access private
*/
function _getCnonce()
{
if (file_exists('/dev/urandom') && $fd = @fopen('/dev/urandom', 'r')) {
return base64_encode(fread($fd, 32));
 
} elseif (file_exists('/dev/random') && $fd = @fopen('/dev/random', 'r')) {
return base64_encode(fread($fd, 32));
 
} else {
$str = '';
mt_srand((double)microtime()*10000000);
for ($i=0; $i<32; $i++) {
$str .= chr(mt_rand(0, 255));
}
return base64_encode($str);
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/SASL/Anonymous.php
New file
0,0 → 1,71
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id: Anonymous.php,v 1.4 2003/02/21 16:07:17 mj Exp $
 
/**
* Implmentation of ANONYMOUS SASL mechanism
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
 
require_once('Auth/SASL/Common.php');
 
class Auth_SASL_Anonymous extends Auth_SASL_Common
{
/**
* Not much to do here except return the token supplied.
* No encoding, hashing or encryption takes place for this
* mechanism, simply one of:
* o An email address
* o An opaque string not containing "@" that can be interpreted
* by the sysadmin
* o Nothing
*
* We could have some logic here for the second option, but this
* would by no means create something interpretable.
*
* @param string $token Optional email address or string to provide
* as trace information.
* @return string The unaltered input token
*/
function getResponse($token = '')
{
return $token;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/SASL/Common.php
New file
0,0 → 1,74
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id: Common.php,v 1.6 2003/02/21 16:07:17 mj Exp $
 
/**
* Common functionality to SASL mechanisms
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
 
class Auth_SASL_Common
{
/**
* Function which implements HMAC MD5 digest
*
* @param string $key The secret key
* @param string $data The data to protect
* @return string The HMAC MD5 digest
*/
function _HMAC_MD5($key, $data)
{
if (strlen($key) > 64) {
$key = pack('H32', md5($key));
}
 
if (strlen($key) < 64) {
$key = str_pad($key, 64, chr(0));
}
 
$k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
$k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64);
 
$inner = pack('H32', md5($k_ipad . $data));
$digest = md5($k_opad . $inner);
 
return $digest;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/SASL/CramMD5.php
New file
0,0 → 1,68
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id: CramMD5.php,v 1.4 2003/02/21 16:07:17 mj Exp $
 
/**
* Implmentation of CRAM-MD5 SASL mechanism
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
 
require_once('Auth/SASL/Common.php');
 
class Auth_SASL_CramMD5 extends Auth_SASL_Common
{
/**
* Implements the CRAM-MD5 SASL mechanism
* This DOES NOT base64 encode the return value,
* you will need to do that yourself.
*
* @param string $user Username
* @param string $pass Password
* @param string $challenge The challenge supplied by the server.
* this should be already base64_decoded.
*
* @return string The string to pass back to the server, of the form
* "<user> <digest>". This is NOT base64_encoded.
*/
function getResponse($user, $pass, $challenge)
{
return $user . ' ' . $this->_HMAC_MD5($pass, $challenge);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/SASL/Login.php
New file
0,0 → 1,65
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id: Login.php,v 1.4 2003/02/21 16:07:17 mj Exp $
 
/**
* This is technically not a SASL mechanism, however
* it's used by Net_Sieve, Net_Cyrus and potentially
* other protocols , so here is a good place to abstract
* it.
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
 
require_once('Auth/SASL/Common.php');
 
class Auth_SASL_Login extends Auth_SASL_Common
{
/**
* Pseudo SASL LOGIN mechanism
*
* @param string $user Username
* @param string $pass Password
* @return string LOGIN string
*/
function getResponse($user, $pass)
{
return sprintf('LOGIN %s %s', $user, $pass);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/SASL/Plain.php
New file
0,0 → 1,63
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id: Plain.php,v 1.6 2003/09/11 18:53:56 mbretter Exp $
 
/**
* Implmentation of PLAIN SASL mechanism
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
 
require_once('Auth/SASL/Common.php');
 
class Auth_SASL_Plain extends Auth_SASL_Common
{
/**
* Returns PLAIN response
*
* @param string $authcid Authentication id (username)
* @param string $pass Password
* @param string $authzid Autorization id
* @return string PLAIN Response
*/
function getResponse($authcid, $pass, $authzid = '')
{
return $authzid . chr(0) . $authcid . chr(0) . $pass;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/HTTP.php
New file
0,0 → 1,795
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2004 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Martin Jansen <mj@php.net> |
// | Rui Hirokawa <hirokawa@php.net> |
// | David Costa <gurugeek@php.net> |
// +----------------------------------------------------------------------+
//
// $Id: Auth_HTTP.php,v 1.27 2005/04/04 12:48:33 hirokawa Exp $
//
 
require_once "Auth/Auth.php";
 
define('AUTH_HTTP_NONCE_TIME_LEN', 16);
define('AUTH_HTTP_NONCE_HASH_LEN', 32);
 
// {{{ class Auth_HTTP
 
/**
* PEAR::Auth_HTTP
*
* The PEAR::Auth_HTTP class provides methods for creating an
* HTTP authentication system based on RFC-2617 using PHP.
*
* Instead of generating an HTML driven form like PEAR::Auth
* does, this class sends header commands to the clients which
* cause them to present a login box like they are e.g. used
* in Apache's .htaccess mechanism.
*
* This class requires the PEAR::Auth package.
*
* @notes The HTTP Digest Authentication part is based on
* authentication class written by Tom Pike <tom.pike@xiven.com>
*
* @author Martin Jansen <mj@php.net>
* @author Rui Hirokawa <hirokawa@php.net>
* @author David Costa <gurugeek@php.net>
* @package Auth_HTTP
* @extends Auth
* @version $Revision: 1.27 $
*/
class Auth_HTTP extends Auth
{
// {{{ properties
 
/**
* Authorization method: 'basic' or 'digest'
*
* @access public
* @var string
*/
var $authType = 'basic';
/**
* Name of the realm for Basic Authentication
*
* @access public
* @var string
* @see drawLogin()
*/
var $realm = "protected area";
 
/**
* Text to send if user hits cancel button
*
* @access public
* @var string
* @see drawLogin()
*/
var $CancelText = "Error 401 - Access denied";
 
/**
* option array
*
* @access public
* @var array
*/
var $options = array();
 
/**
* flag to indicate the nonce was stale.
*
* @access public
* @var bool
*/
var $stale = false;
 
/**
* opaque string for digest authentication
*
* @access public
* @var string
*/
var $opaque = 'dummy';
 
/**
* digest URI
*
* @access public
* @var string
*/
var $uri = '';
 
/**
* authorization info returned by the client
*
* @access public
* @var array
*/
var $auth = array();
 
/**
* next nonce value
*
* @access public
* @var string
*/
var $nextNonce = '';
 
/**
* nonce value
*
* @access public
* @var string
*/
var $nonce = '';
 
/**
* Holds a reference to the global server variable
* @var array
*/
var $server;
 
/**
* Holds a reference to the global post variable
* @var array
*/
var $post;
 
/**
* Holds a reference to the global cookie variable
* @var array
*/
var $cookie;
 
 
// }}}
// {{{ Constructor
 
/**
* Constructor
*
* @param string Type of the storage driver
* @param mixed Additional options for the storage driver
* (example: if you are using DB as the storage
* driver, you have to pass the dsn string here)
*
* @return void
*/
function Auth_HTTP($storageDriver, $options = '')
{
/* set default values for options */
$this->options = array('cryptType' => 'md5',
'algorithm' => 'MD5',
'qop' => 'auth-int,auth',
'opaquekey' => 'moo',
'noncekey' => 'moo',
'digestRealm' => 'protected area',
'forceDigestOnly' => false,
'nonceLife' => 300,
'sessionSharing' => true,
);
if (!empty($options['authType'])) {
$this->authType = strtolower($options['authType']);
}
if (is_array($options)) {
foreach($options as $key => $value) {
if (array_key_exists( $key, $this->options)) {
$this->options[$key] = $value;
}
}
if (!empty($this->options['opaquekey'])) {
$this->opaque = md5($this->options['opaquekey']);
}
}
$this->Auth($storageDriver, $options);
}
// }}}
// {{{ assignData()
 
/**
* Assign values from $PHP_AUTH_USER and $PHP_AUTH_PW or 'Authorization' header
* to internal variables and sets the session id based
* on them
*
* @access public
* @return void
*/
function assignData()
{
if (method_exists($this, '_importGlobalVariable')) {
$this->server = &$this->_importGlobalVariable('server');
}
if ($this->authType == 'basic') {
if (!empty($this->server['PHP_AUTH_USER'])) {
$this->username = $this->server['PHP_AUTH_USER'];
}
if (!empty($this->server['PHP_AUTH_PW'])) {
$this->password = $this->server['PHP_AUTH_PW'];
}
/**
* Try to get authentication information from IIS
*/
if (empty($this->username) && empty($this->password)) {
if (!empty($this->server['HTTP_AUTHORIZATION'])) {
list($this->username, $this->password) =
explode(':', base64_decode(substr($this->server['HTTP_AUTHORIZATION'], 6)));
}
}
} elseif ($this->authType == 'digest') {
$this->username = '';
$this->password = '';
 
$this->digest_header = null;
if (!empty($this->server['PHP_AUTH_DIGEST'])) {
$this->digest_header = substr($this->server['PHP_AUTH_DIGEST'],
strpos($this->server['PHP_AUTH_DIGEST'],' ')+1);
} else {
$headers = getallheaders();
if(isset($headers['Authorization']) && !empty($headers['Authorization'])) {
$this->digest_header = substr($headers['Authorization'],
strpos($headers['Authorization'],' ')+1);
}
}
 
if($this->digest_header) {
$authtemp = explode(',', $this->digest_header);
$auth = array();
foreach($authtemp as $key => $value) {
$value = trim($value);
if(strpos($value,'=') !== false) {
$lhs = substr($value,0,strpos($value,'='));
$rhs = substr($value,strpos($value,'=')+1);
if(substr($rhs,0,1) == '"' && substr($rhs,-1,1) == '"') {
$rhs = substr($rhs,1,-1);
}
$auth[$lhs] = $rhs;
}
}
}
if (!isset($auth['uri']) || !isset($auth['realm'])) {
return;
}
if ($this->selfURI() == $auth['uri']) {
$this->uri = $auth['uri'];
if (substr($headers['Authorization'],0,7) == 'Digest ') {
$this->authType = 'digest';
 
if (!isset($auth['nonce']) || !isset($auth['username']) ||
!isset($auth['response']) || !isset($auth['qop']) ||
!isset($auth['nc']) || !isset($auth['cnonce'])){
return;
}
 
if ($auth['qop'] != 'auth' && $auth['qop'] != 'auth-int') {
return;
}
$this->stale = $this->_judgeStale($auth['nonce']);
 
if ($this->nextNonce == false) {
return;
}
 
$this->username = $auth['username'];
$this->password = $auth['response'];
$this->auth['nonce'] = $auth['nonce'];
$this->auth['qop'] = $auth['qop'];
$this->auth['nc'] = $auth['nc'];
$this->auth['cnonce'] = $auth['cnonce'];
 
if (isset($auth['opaque'])) {
$this->auth['opaque'] = $auth['opaque'];
}
} elseif (substr($headers['Authorization'],0,6) == 'Basic ') {
if ($this->options['forceDigestOnly']) {
return; // Basic authentication is not allowed.
}
$this->authType = 'basic';
list($username, $password) =
explode(':',base64_decode(substr($headers['Authorization'],6)));
$this->username = $username;
$this->password = $password;
}
}
} else {
return PEAR::raiseError('authType is invalid.');
}
 
if ($this->options['sessionSharing'] &&
isset($this->username) && isset($this->password)) {
session_id(md5('Auth_HTTP' . $this->username . $this->password));
}
/**
* set sessionName for AUTH, so that the sessionName is different
* for distinct realms
*/
$this->_sessionName = "_authhttp".md5($this->realm);
}
 
// }}}
// {{{ login()
 
/**
* Login function
*
* @access private
* @return void
*/
function login()
{
$login_ok = false;
if (method_exists($this, '_loadStorage')) {
$this->_loadStorage();
}
$this->storage->_auth_obj->_sessionName =& $this->_sessionName;
 
/**
* When the user has already entered a username,
* we have to validate it.
*/
if (!empty($this->username) && !empty($this->password)) {
if ($this->authType == 'basic' && !$this->options['forceDigestOnly']) {
if (true === $this->storage->fetchData($this->username, $this->password)) {
$login_ok = true;
}
} else { /* digest authentication */
 
if (!$this->getAuth() || $this->getAuthData('a1') == null) {
/*
* note:
* - only PEAR::DB is supported as container.
* - password should be stored in container as plain-text
* (if $options['cryptType'] == 'none') or
* A1 hashed form (md5('username:realm:password'))
* (if $options['cryptType'] == 'md5')
*/
$dbs = $this->storage;
if (!DB::isConnection($dbs->db)) {
$dbs->_connect($dbs->options['dsn']);
}
$query = 'SELECT '.$dbs->options['passwordcol']." FROM ".$dbs->options['table'].
' WHERE '.$dbs->options['usernamecol']." = '".
$dbs->db->quoteString($this->username)."' ";
$pwd = $dbs->db->getOne($query); // password stored in container.
if (DB::isError($pwd)) {
return PEAR::raiseError($pwd->getMessage(), $pwd->getCode());
}
if ($this->options['cryptType'] == 'none') {
$a1 = md5($this->username.':'.$this->options['digestRealm'].':'.$pwd);
} else {
$a1 = $pwd;
}
$this->setAuthData('a1', $a1, true);
} else {
$a1 = $this->getAuthData('a1');
}
$login_ok = $this->validateDigest($this->password, $a1);
if ($this->nextNonce == false) {
$login_ok = false;
}
}
if (!$login_ok && is_callable($this->loginFailedCallback)) {
call_user_func($this->loginFailedCallback,$this->username, $this);
}
}
if (!empty($this->username) && $login_ok) {
$this->setAuth($this->username);
if (is_callable($this->loginCallback)) {
call_user_func($this->loginCallback,$this->username, $this);
}
}
/**
* If the login failed or the user entered no username,
* output the login screen again.
*/
if (!empty($this->username) && !$login_ok) {
$this->status = AUTH_WRONG_LOGIN;
}
if ((empty($this->username) || !$login_ok) && $this->showLogin) {
$this->drawLogin($this->storage->activeUser);
return;
}
 
if (!empty($this->username) && $login_ok && $this->authType == 'digest'
&& $this->auth['qop'] == 'auth') {
$this->authenticationInfo();
}
}
// }}}
// {{{ drawLogin()
 
/**
* Launch the login box
*
* @param string $username Username
* @return void
* @access private
*/
function drawLogin($username = "")
{
/**
* Send the header commands
*/
if ($this->authType == 'basic') {
header("WWW-Authenticate: Basic realm=\"".$this->realm."\"");
header('HTTP/1.0 401 Unauthorized');
} else if ($this->authType == 'digest') {
$this->nonce = $this->_getNonce();
 
$wwwauth = 'WWW-Authenticate: Digest ';
$wwwauth .= 'qop="'.$this->options['qop'].'", ';
$wwwauth .= 'algorithm='.$this->options['algorithm'].', ';
$wwwauth .= 'realm="'.$this->options['digestRealm'].'", ';
$wwwauth .= 'nonce="'.$this->nonce.'", ';
if ($this->stale) {
$wwwauth .= 'stale=true, ';
}
if (!empty($this->opaque)) {
$wwwauth .= 'opaque="'.$this->opaque.'"' ;
}
$wwwauth .= "\r\n";
if (!$this->options['forceDigestOnly']) {
$wwwauth .= 'WWW-Authenticate: Basic realm="'.$this->realm.'"';
}
header($wwwauth);
header('HTTP/1.0 401 Unauthorized');
}
 
/**
* This code is only executed if the user hits the cancel
* button or if he enters wrong data 3 times.
*/
if ($this->stale) {
echo 'Stale nonce value, please re-authenticate.';
} else {
echo $this->CancelText;
}
exit;
}
 
// }}}
// {{{ setRealm()
 
/**
* Set name of the current realm
*
* @access public
* @param string $realm Name of the realm
* @param string $digestRealm Name of the realm for digest authentication
* @return void
*/
function setRealm($realm, $digestRealm = '')
{
$this->realm = $realm;
if (!empty($digestRealm)) {
$this->options['digestRealm'] = $digestRealm;
}
}
 
// }}}
// {{{ setCancelText()
 
/**
* Set the text to send if user hits the cancel button
*
* @access public
* @param string $text Text to send
* @return void
*/
function setCancelText($text)
{
$this->CancelText = $text;
}
 
// }}}
// {{{ validateDigest()
/**
* judge if the client response is valid.
*
* @access private
* @param string $response client response
* @param string $a1 password or hashed password stored in container
* @return bool true if success, false otherwise
*/
function validateDigest($response, $a1)
{
if (method_exists($this, '_importGlobalVariable')) {
$this->server = &$this->_importGlobalVariable('server');
}
 
$a2unhashed = $this->server['REQUEST_METHOD'].":".$this->selfURI();
if($this->auth['qop'] == 'auth-int') {
if(isset($GLOBALS["HTTP_RAW_POST_DATA"])) {
// In PHP < 4.3 get raw POST data from this variable
$body = $GLOBALS["HTTP_RAW_POST_DATA"];
} else if($lines = @file('php://input')) {
// In PHP >= 4.3 get raw POST data from this file
$body = implode("\n", $lines);
} else {
if (method_exists($this, '_importGlobalVariable')) {
$this->post = &$this->_importGlobalVariable('post');
}
$body = '';
foreach($this->post as $key => $value) {
if($body != '') $body .= '&';
$body .= rawurlencode($key) . '=' . rawurlencode($value);
}
}
 
$a2unhashed .= ':'.md5($body);
}
$a2 = md5($a2unhashed);
$combined = $a1.':'.
$this->auth['nonce'].':'.
$this->auth['nc'].':'.
$this->auth['cnonce'].':'.
$this->auth['qop'].':'.
$a2;
$expectedResponse = md5($combined);
if(!isset($this->auth['opaque']) || $this->auth['opaque'] == $this->opaque) {
if($response == $expectedResponse) { // password is valid
if(!$this->stale) {
return true;
} else {
$this->drawLogin();
}
}
}
return false;
}
// }}}
// {{{ _judgeStale()
/**
* judge if nonce from client is stale.
*
* @access private
* @param string $nonce nonce value from client
* @return bool stale
*/
function _judgeStale($nonce)
{
$stale = false;
if(!$this->_decodeNonce($nonce, $time, $hash_cli)) {
$this->nextNonce = false;
$stale = true;
return $stale;
}
 
if ($time < time() - $this->options['nonceLife']) {
$this->nextNonce = $this->_getNonce();
$stale = true;
} else {
$this->nextNonce = $nonce;
}
 
return $stale;
}
// }}}
// {{{ _nonceDecode()
/**
* decode nonce string
*
* @access private
* @param string $nonce nonce value from client
* @param string $time decoded time
* @param string $hash decoded hash
* @return bool false if nonce is invalid
*/
function _decodeNonce($nonce, &$time, &$hash)
{
if (method_exists($this, '_importGlobalVariable')) {
$this->server = &$this->_importGlobalVariable('server');
}
 
if (strlen($nonce) != AUTH_HTTP_NONCE_TIME_LEN + AUTH_HTTP_NONCE_HASH_LEN) {
return false;
}
 
$time = base64_decode(substr($nonce, 0, AUTH_HTTP_NONCE_TIME_LEN));
$hash_cli = substr($nonce, AUTH_HTTP_NONCE_TIME_LEN, AUTH_HTTP_NONCE_HASH_LEN);
 
$hash = md5($time . $this->server['HTTP_USER_AGENT'] . $this->options['noncekey']);
 
if ($hash_cli != $hash) {
return false;
}
return true;
}
 
// }}}
// {{{ _getNonce()
/**
* return nonce to detect timeout
*
* @access private
* @return string nonce value
*/
function _getNonce()
{
if (method_exists($this, '_importGlobalVariable')) {
$this->server = &$this->_importGlobalVariable('server');
}
 
$time = time();
$hash = md5($time . $this->server['HTTP_USER_AGENT'] . $this->options['noncekey']);
 
return base64_encode($time) . $hash;
}
 
// }}}
// {{{ authenticationInfo()
/**
* output HTTP Authentication-Info header
*
* @notes md5 hash of contents is required if 'qop' is 'auth-int'
*
* @access private
* @param string MD5 hash of content
*/
function authenticationInfo($contentMD5 = '') {
if($this->getAuth() && ($this->getAuthData('a1') != null)) {
$a1 = $this->getAuthData('a1');
 
// Work out authorisation response
$a2unhashed = ":".$this->selfURI();
if($this->auth['qop'] == 'auth-int') {
$a2unhashed .= ':'.$contentMD5;
}
$a2 = md5($a2unhashed);
$combined = $a1.':'.
$this->nonce.':'.
$this->auth['nc'].':'.
$this->auth['cnonce'].':'.
$this->auth['qop'].':'.
$a2;
// Send authentication info
$wwwauth = 'Authentication-Info: ';
if($this->nonce != $this->nextNonce) {
$wwwauth .= 'nextnonce="'.$this->nextNonce.'", ';
}
$wwwauth .= 'qop='.$this->auth['qop'].', ';
$wwwauth .= 'rspauth="'.md5($combined).'", ';
$wwwauth .= 'cnonce="'.$this->auth['cnonce'].'", ';
$wwwauth .= 'nc='.$this->auth['nc'].'';
header($wwwauth);
}
}
// }}}
// {{{ setOption()
/**
* set authentication option
*
* @access public
* @param mixed $name key of option
* @param mixed $value value of option
* @return void
*/
function setOption($name, $value = null)
{
if (is_array($name)) {
foreach($name as $key => $value) {
if (array_key_exists( $key, $this->options)) {
$this->options[$key] = $value;
}
}
} else {
if (array_key_exists( $name, $this->options)) {
$this->options[$name] = $value;
}
}
}
 
// }}}
// {{{ getOption()
/**
* get authentication option
*
* @access public
* @param string $name key of option
* @return mixed option value
*/
function getOption($name)
{
if (array_key_exists( $name, $this->options)) {
return $this->options[$name];
}
if ($name == 'CancelText') {
return $this->CancelText;
}
if ($name == 'Realm') {
return $this->realm;
}
return false;
}
 
// }}}
// {{{ selfURI()
/**
* get self URI
*
* @access public
* @return string self URI
*/
function selfURI()
{
if (method_exists($this, '_importGlobalVariable')) {
$this->server = &$this->_importGlobalVariable('server');
}
 
if (preg_match("/MSIE/",$this->server['HTTP_USER_AGENT'])) {
// query string should be removed for MSIE
$uri = preg_replace("/^(.*)\?/","\\1",$this->server['REQUEST_URI']);
} else {
$uri = $this->server['REQUEST_URI'];
}
return $uri;
}
 
// }}}
 
}
 
// }}}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Auth.php
New file
0,0 → 1,5
<?php
 
include_once('Auth.php');
 
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/Container.php
New file
0,0 → 1,177
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Martin Jansen <mj@php.net> |
// +----------------------------------------------------------------------+
//
// $Id: Container.php,v 1.15 2003/10/19 14:03:19 yavo Exp $
//
 
define("AUTH_METHOD_NOT_SUPPORTED", -4);
 
/**
* Storage class for fetching login data
*
* @author Martin Jansen <mj@php.net>
* @package Auth
*/
class Auth_Container
{
 
/**
* User that is currently selected from the storage container.
*
* @access public
*/
var $activeUser = "";
 
// {{{ Constructor
 
/**
* Constructor
*
* Has to be overwritten by each storage class
*
* @access public
*/
function Auth_Container()
{
}
 
// }}}
// {{{ fetchData()
 
/**
* Fetch data from storage container
*
* Has to be overwritten by each storage class
*
* @access public
*/
function fetchData()
{
}
 
// }}}
// {{{ verifyPassword()
 
/**
* Crypt and verfiy the entered password
*
* @param string Entered password
* @param string Password from the data container (usually this password
* is already encrypted.
* @param string Type of algorithm with which the password from
* the container has been crypted. (md5, crypt etc.)
* Defaults to "md5".
* @return bool True, if the passwords match
*/
function verifyPassword($password1, $password2, $cryptType = "md5")
{
switch ($cryptType) {
case "crypt" :
return (($password2 == "**" . $password1) ||
(crypt($password1, $password2) == $password2)
);
break;
 
case "none" :
return ($password1 == $password2);
break;
 
case "md5" :
return (md5($password1) == $password2);
break;
 
default :
if (function_exists($cryptType)) {
return ($cryptType($password1) == $password2);
}
else if (method_exists($this,$cryptType)) {
return ($this->$cryptType($password1) == $password2);
} else {
return false;
}
break;
}
}
 
// }}}
// {{{ listUsers()
 
/**
* List all users that are available from the storage container
*/
function listUsers()
{
return AUTH_METHOD_NOT_SUPPORTED;
}
 
/**
* Returns a user assoc array
*
* Containers which want should overide this
*
* @param string The username
*/
function getUser($username)
{
$users = $this->listUsers();
if($users === AUTH_METHOD_NOT_SUPPORTED){
return(AUTH_METHOD_NOT_SUPPORTED);
}
for($i=0;$c = count($users),$i<$c;$i++){
if($users[$i]['username'] == $username){
return($users[$i]);
}
}
return(false);
}
 
// }}}
// {{{ addUser()
 
/**
* Add a new user to the storage container
*
* @param string Username
* @param string Password
* @param array Additional information
*
* @return boolean
*/
function addUser($username, $password, $additional=null)
{
return AUTH_METHOD_NOT_SUPPORTED;
}
 
// }}}
// {{{ removeUser()
 
/**
* Remove user from the storage container
*
* @param string Username
*/
function removeUser($username)
{
return AUTH_METHOD_NOT_SUPPORTED;
}
 
// }}}
 
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth/SASL.php
New file
0,0 → 1,99
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id: SASL.php,v 1.5 2006/03/22 05:20:11 amistry Exp $
 
/**
* Client implementation of various SASL mechanisms
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
 
require_once('PEAR.php');
 
class Auth_SASL
{
/**
* Factory class. Returns an object of the request
* type.
*
* @param string $type One of: Anonymous
* Plain
* CramMD5
* DigestMD5
* Types are not case sensitive
*/
function &factory($type)
{
switch (strtolower($type)) {
case 'anonymous':
$filename = 'Auth/SASL/Anonymous.php';
$classname = 'Auth_SASL_Anonymous';
break;
 
case 'login':
$filename = 'Auth/SASL/Login.php';
$classname = 'Auth_SASL_Login';
break;
 
case 'plain':
$filename = 'Auth/SASL/Plain.php';
$classname = 'Auth_SASL_Plain';
break;
 
case 'crammd5':
$filename = 'Auth/SASL/CramMD5.php';
$classname = 'Auth_SASL_CramMD5';
break;
 
case 'digestmd5':
$filename = 'Auth/SASL/DigestMD5.php';
$classname = 'Auth_SASL_DigestMD5';
break;
 
default:
return PEAR::raiseError('Invalid SASL mechanism type');
break;
}
 
require_once($filename);
$obj = new $classname();
return $obj;
}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/ibase.php
New file
0,0 → 1,1071
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's interbase extension
* for interacting with Interbase and Firebird databases
*
* While this class works with PHP 4, PHP's InterBase extension is
* unstable in PHP 4. Use PHP 5.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: ibase.php,v 1.109 2005/03/04 23:12:36 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's interbase extension
* for interacting with Interbase and Firebird databases
*
* These methods overload the ones declared in DB_common.
*
* While this class works with PHP 4, PHP's InterBase extension is
* unstable in PHP 4. Use PHP 5.
*
* NOTICE: limitQuery() only works for Firebird.
*
* @category Database
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
* @since Class became stable in Release 1.7.0
*/
class DB_ibase extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'ibase';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'ibase';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* NOTE: only firebird supports limit.
*
* @var array
*/
var $features = array(
'limit' => false,
'new_link' => false,
'numrows' => 'emulate',
'pconnect' => true,
'prepare' => true,
'ssl' => false,
'transactions' => true,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
-104 => DB_ERROR_SYNTAX,
-150 => DB_ERROR_ACCESS_VIOLATION,
-151 => DB_ERROR_ACCESS_VIOLATION,
-155 => DB_ERROR_NOSUCHTABLE,
-157 => DB_ERROR_NOSUCHFIELD,
-158 => DB_ERROR_VALUE_COUNT_ON_ROW,
-170 => DB_ERROR_MISMATCH,
-171 => DB_ERROR_MISMATCH,
-172 => DB_ERROR_INVALID,
// -204 => // Covers too many errors, need to use regex on msg
-205 => DB_ERROR_NOSUCHFIELD,
-206 => DB_ERROR_NOSUCHFIELD,
-208 => DB_ERROR_INVALID,
-219 => DB_ERROR_NOSUCHTABLE,
-297 => DB_ERROR_CONSTRAINT,
-303 => DB_ERROR_INVALID,
-413 => DB_ERROR_INVALID_NUMBER,
-530 => DB_ERROR_CONSTRAINT,
-551 => DB_ERROR_ACCESS_VIOLATION,
-552 => DB_ERROR_ACCESS_VIOLATION,
// -607 => // Covers too many errors, need to use regex on msg
-625 => DB_ERROR_CONSTRAINT_NOT_NULL,
-803 => DB_ERROR_CONSTRAINT,
-804 => DB_ERROR_VALUE_COUNT_ON_ROW,
-904 => DB_ERROR_CONNECT_FAILED,
-922 => DB_ERROR_NOSUCHDB,
-923 => DB_ERROR_CONNECT_FAILED,
-924 => DB_ERROR_CONNECT_FAILED
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* The number of rows affected by a data manipulation query
* @var integer
* @access private
*/
var $affected = 0;
 
/**
* Should data manipulation queries be committed automatically?
* @var bool
* @access private
*/
var $autocommit = true;
 
/**
* The prepared statement handle from the most recently executed statement
*
* {@internal Mainly here because the InterBase/Firebird API is only
* able to retrieve data from result sets if the statemnt handle is
* still in scope.}}
*
* @var resource
*/
var $last_stmt;
 
/**
* Is the given prepared statement a data manipulation query?
* @var array
* @access private
*/
var $manip_query = array();
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_ibase()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* PEAR DB's ibase driver supports the following extra DSN options:
* + buffers The number of database buffers to allocate for the
* server-side cache.
* + charset The default character set for a database.
* + dialect The default SQL dialect for any statement
* executed within a connection. Defaults to the
* highest one supported by client libraries.
* Functional only with InterBase 6 and up.
* + role Functional only with InterBase 5 and up.
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('interbase')) {
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
if ($this->dbsyntax == 'firebird') {
$this->features['limit'] = 'alter';
}
 
$params = array(
$dsn['hostspec']
? ($dsn['hostspec'] . ':' . $dsn['database'])
: $dsn['database'],
$dsn['username'] ? $dsn['username'] : null,
$dsn['password'] ? $dsn['password'] : null,
isset($dsn['charset']) ? $dsn['charset'] : null,
isset($dsn['buffers']) ? $dsn['buffers'] : null,
isset($dsn['dialect']) ? $dsn['dialect'] : null,
isset($dsn['role']) ? $dsn['role'] : null,
);
 
$connect_function = $persistent ? 'ibase_pconnect' : 'ibase_connect';
 
$this->connection = @call_user_func_array($connect_function, $params);
if (!$this->connection) {
return $this->ibaseRaiseError(DB_ERROR_CONNECT_FAILED);
}
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @ibase_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
$result = @ibase_query($this->connection, $query);
 
if (!$result) {
return $this->ibaseRaiseError();
}
if ($this->autocommit && $ismanip) {
@ibase_commit($this->connection);
}
if ($ismanip) {
$this->affected = $result;
return DB_OK;
} else {
$this->affected = 0;
return $result;
}
}
 
// }}}
// {{{ modifyLimitQuery()
 
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* Only works with Firebird.
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
if ($this->dsn['dbsyntax'] == 'firebird') {
$query = preg_replace('/^([\s(])*SELECT/i',
"SELECT FIRST $count SKIP $from", $query);
}
return $query;
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal ibase result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
function nextResult($result)
{
return false;
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE);
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
if (function_exists('ibase_fetch_assoc')) {
$arr = @ibase_fetch_assoc($result);
} else {
$arr = get_object_vars(ibase_fetch_object($result));
}
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @ibase_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return @ibase_free_result($result);
}
 
// }}}
// {{{ freeQuery()
 
function freeQuery($query)
{
@ibase_free_query($query);
return true;
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
if (is_integer($this->affected)) {
return $this->affected;
}
return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @ibase_num_fields($result);
if (!$cols) {
return $this->ibaseRaiseError();
}
return $cols;
}
 
// }}}
// {{{ prepare()
 
/**
* Prepares a query for multiple execution with execute().
*
* prepare() requires a generic query as string like <code>
* INSERT INTO numbers VALUES (?, ?, ?)
* </code>. The <kbd>?</kbd> characters are placeholders.
*
* Three types of placeholders can be used:
* + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers
* + <kbd>!</kbd> value is inserted 'as is'
* + <kbd>&</kbd> requires a file name. The file's contents get
* inserted into the query (i.e. saving binary
* data in a db)
*
* Use backslashes to escape placeholder characters if you don't want
* them to be interpreted as placeholders. Example: <code>
* "UPDATE foo SET col=? WHERE col='over \& under'"
* </code>
*
* @param string $query query to be prepared
* @return mixed DB statement resource on success. DB_Error on failure.
*/
function prepare($query)
{
$tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1,
PREG_SPLIT_DELIM_CAPTURE);
$token = 0;
$types = array();
$newquery = '';
 
foreach ($tokens as $key => $val) {
switch ($val) {
case '?':
$types[$token++] = DB_PARAM_SCALAR;
break;
case '&':
$types[$token++] = DB_PARAM_OPAQUE;
break;
case '!':
$types[$token++] = DB_PARAM_MISC;
break;
default:
$tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val);
$newquery .= $tokens[$key] . '?';
}
}
 
$newquery = substr($newquery, 0, -1);
$this->last_query = $query;
$newquery = $this->modifyQuery($newquery);
$stmt = @ibase_prepare($this->connection, $newquery);
$this->prepare_types[(int)$stmt] = $types;
$this->manip_query[(int)$stmt] = DB::isManip($query);
return $stmt;
}
 
// }}}
// {{{ execute()
 
/**
* Executes a DB statement prepared with prepare().
*
* @param resource $stmt a DB statement resource returned from prepare()
* @param mixed $data array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 for non-array items or the
* quantity of elements in the array.
* @return object a new DB_Result or a DB_Error when fail
* @see DB_ibase::prepare()
* @access public
*/
function &execute($stmt, $data = array())
{
$data = (array)$data;
$this->last_parameters = $data;
 
$types =& $this->prepare_types[(int)$stmt];
if (count($types) != count($data)) {
$tmp =& $this->raiseError(DB_ERROR_MISMATCH);
return $tmp;
}
 
$i = 0;
foreach ($data as $key => $value) {
if ($types[$i] == DB_PARAM_MISC) {
/*
* ibase doesn't seem to have the ability to pass a
* parameter along unchanged, so strip off quotes from start
* and end, plus turn two single quotes to one single quote,
* in order to avoid the quotes getting escaped by
* ibase and ending up in the database.
*/
$data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]);
$data[$key] = str_replace("''", "'", $data[$key]);
} elseif ($types[$i] == DB_PARAM_OPAQUE) {
$fp = @fopen($data[$key], 'rb');
if (!$fp) {
$tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
return $tmp;
}
$data[$key] = fread($fp, filesize($data[$key]));
fclose($fp);
}
$i++;
}
 
array_unshift($data, $stmt);
 
$res = call_user_func_array('ibase_execute', $data);
if (!$res) {
$tmp =& $this->ibaseRaiseError();
return $tmp;
}
/* XXX need this?
if ($this->autocommit && $this->manip_query[(int)$stmt]) {
@ibase_commit($this->connection);
}*/
$this->last_stmt = $stmt;
if ($this->manip_query[(int)$stmt]) {
$tmp = DB_OK;
} else {
$tmp =& new DB_result($this, $res);
}
return $tmp;
}
 
/**
* Frees the internal resources associated with a prepared query
*
* @param resource $stmt the prepared statement's PHP resource
* @param bool $free_resource should the PHP resource be freed too?
* Use false if you need to get data
* from the result set later.
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_ibase::prepare()
*/
function freePrepared($stmt, $free_resource = true)
{
if (!is_resource($stmt)) {
return false;
}
if ($free_resource) {
@ibase_free_query($stmt);
}
unset($this->prepare_tokens[(int)$stmt]);
unset($this->prepare_types[(int)$stmt]);
unset($this->manip_query[(int)$stmt]);
return true;
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff = false)
{
$this->autocommit = $onoff ? 1 : 0;
return DB_OK;
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
return @ibase_commit($this->connection);
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
return @ibase_rollback($this->connection);
}
 
// }}}
// {{{ transactionInit()
 
function transactionInit($trans_args = 0)
{
return $trans_args
? @ibase_trans($trans_args, $this->connection)
: @ibase_trans();
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_ibase::createSequence(), DB_ibase::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$sqn = strtoupper($this->getSequenceName($seq_name));
$repeat = 0;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result =& $this->query("SELECT GEN_ID(${sqn}, 1) "
. 'FROM RDB$GENERATORS '
. "WHERE RDB\$GENERATOR_NAME='${sqn}'");
$this->popErrorHandling();
if ($ondemand && DB::isError($result)) {
$repeat = 1;
$result = $this->createSequence($seq_name);
if (DB::isError($result)) {
return $result;
}
} else {
$repeat = 0;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
$result->free();
return $arr[0];
}
 
// }}}
// {{{ createSequence()
 
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_ibase::nextID(), DB_ibase::dropSequence()
*/
function createSequence($seq_name)
{
$sqn = strtoupper($this->getSequenceName($seq_name));
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("CREATE GENERATOR ${sqn}");
$this->popErrorHandling();
 
return $result;
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_ibase::nextID(), DB_ibase::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DELETE FROM RDB$GENERATORS '
. "WHERE RDB\$GENERATOR_NAME='"
. strtoupper($this->getSequenceName($seq_name))
. "'");
}
 
// }}}
// {{{ _ibaseFieldFlags()
 
/**
* Get the column's flags
*
* Supports "primary_key", "unique_key", "not_null", "default",
* "computed" and "blob".
*
* @param string $field_name the name of the field
* @param string $table_name the name of the table
*
* @return string the flags
*
* @access private
*/
function _ibaseFieldFlags($field_name, $table_name)
{
$sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE'
.' FROM RDB$INDEX_SEGMENTS I'
.' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME'
.' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\''
.' AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'';
 
$result = @ibase_query($this->connection, $sql);
if (!$result) {
return $this->ibaseRaiseError();
}
 
$flags = '';
if ($obj = @ibase_fetch_object($result)) {
@ibase_free_result($result);
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') {
$flags .= 'primary_key ';
}
if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') {
$flags .= 'unique_key ';
}
}
 
$sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,'
.' R.RDB$DEFAULT_SOURCE AS DSOURCE,'
.' F.RDB$FIELD_TYPE AS FTYPE,'
.' F.RDB$COMPUTED_SOURCE AS CSOURCE'
.' FROM RDB$RELATION_FIELDS R '
.' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME'
.' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''
.' AND R.RDB$FIELD_NAME=\'' . $field_name . '\'';
 
$result = @ibase_query($this->connection, $sql);
if (!$result) {
return $this->ibaseRaiseError();
}
if ($obj = @ibase_fetch_object($result)) {
@ibase_free_result($result);
if (isset($obj->NFLAG)) {
$flags .= 'not_null ';
}
if (isset($obj->DSOURCE)) {
$flags .= 'default ';
}
if (isset($obj->CSOURCE)) {
$flags .= 'computed ';
}
if (isset($obj->FTYPE) && $obj->FTYPE == 261) {
$flags .= 'blob ';
}
}
 
return trim($flags);
}
 
// }}}
// {{{ ibaseRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_ibase::errorNative(), DB_ibase::errorCode()
*/
function &ibaseRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode($this->errorNative());
}
$tmp =& $this->raiseError($errno, null, null, null, @ibase_errmsg());
return $tmp;
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error code produced by the last query
*
* @return int the DBMS' error code. NULL if there is no error code.
*
* @since Method available since Release 1.7.0
*/
function errorNative()
{
if (function_exists('ibase_errcode')) {
return @ibase_errcode();
}
if (preg_match('/^Dynamic SQL Error SQL error code = ([0-9-]+)/i',
@ibase_errmsg(), $m)) {
return (int)$m[1];
}
return null;
}
 
// }}}
// {{{ errorCode()
 
/**
* Maps native error codes to DB's portable ones
*
* @param int $nativecode the error code returned by the DBMS
*
* @return int the portable DB error code. Return DB_ERROR if the
* current driver doesn't have a mapping for the
* $nativecode submitted.
*
* @since Method available since Release 1.7.0
*/
function errorCode($nativecode = null)
{
if (isset($this->errorcode_map[$nativecode])) {
return $this->errorcode_map[$nativecode];
}
 
static $error_regexps;
if (!isset($error_regexps)) {
$error_regexps = array(
'/generator .* is not defined/'
=> DB_ERROR_SYNTAX, // for compat. w ibase_errcode()
'/table.*(not exist|not found|unknown)/i'
=> DB_ERROR_NOSUCHTABLE,
'/table .* already exists/i'
=> DB_ERROR_ALREADY_EXISTS,
'/unsuccessful metadata update .* failed attempt to store duplicate value/i'
=> DB_ERROR_ALREADY_EXISTS,
'/unsuccessful metadata update .* not found/i'
=> DB_ERROR_NOT_FOUND,
'/validation error for column .* value "\*\*\* null/i'
=> DB_ERROR_CONSTRAINT_NOT_NULL,
'/violation of [\w ]+ constraint/i'
=> DB_ERROR_CONSTRAINT,
'/conversion error from string/i'
=> DB_ERROR_INVALID_NUMBER,
'/no permission for/i'
=> DB_ERROR_ACCESS_VIOLATION,
'/arithmetic exception, numeric overflow, or string truncation/i'
=> DB_ERROR_INVALID,
);
}
 
$errormsg = @ibase_errmsg();
foreach ($error_regexps as $regexp => $code) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
}
return DB_ERROR;
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
* is a table name.
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @ibase_query($this->connection,
"SELECT * FROM $result WHERE 1=0");
$got_string = true;
} elseif (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$id = $result->result;
$got_string = false;
} else {
/*
* Probably received a result resource identifier.
* Copy it.
* Deprecated. Here for compatibility only.
*/
$id = $result;
$got_string = false;
}
 
if (!is_resource($id)) {
return $this->ibaseRaiseError(DB_ERROR_NEED_MORE_DATA);
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$count = @ibase_num_fields($id);
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
$info = @ibase_field_info($id, $i);
$res[$i] = array(
'table' => $got_string ? $case_func($result) : '',
'name' => $case_func($info['name']),
'type' => $info['type'],
'len' => $info['length'],
'flags' => ($got_string)
? $this->_ibaseFieldFlags($info['name'], $result)
: '',
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
// free the result only if we were called on a table
if ($got_string) {
@ibase_free_result($id);
}
return $res;
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'tables':
return 'SELECT DISTINCT R.RDB$RELATION_NAME FROM '
. 'RDB$RELATION_FIELDS R WHERE R.RDB$SYSTEM_FLAG=0';
case 'views':
return 'SELECT DISTINCT RDB$VIEW_NAME from RDB$VIEW_RELATIONS';
case 'users':
return 'SELECT DISTINCT RDB$USER FROM RDB$USER_PRIVILEGES';
default:
return null;
}
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/ifx.php
New file
0,0 → 1,681
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's ifx extension
* for interacting with Informix databases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: ifx.php,v 1.70 2005/02/20 00:44:48 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's ifx extension
* for interacting with Informix databases
*
* These methods overload the ones declared in DB_common.
*
* More info on Informix errors can be found at:
* http://www.informix.com/answers/english/ierrors.htm
*
* TODO:
* - set needed env Informix vars on connect
* - implement native prepare/execute
*
* @category Database
* @package DB
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_ifx extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'ifx';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'ifx';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => 'emulate',
'new_link' => false,
'numrows' => 'emulate',
'pconnect' => true,
'prepare' => false,
'ssl' => false,
'transactions' => true,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
'-201' => DB_ERROR_SYNTAX,
'-206' => DB_ERROR_NOSUCHTABLE,
'-217' => DB_ERROR_NOSUCHFIELD,
'-236' => DB_ERROR_VALUE_COUNT_ON_ROW,
'-239' => DB_ERROR_CONSTRAINT,
'-253' => DB_ERROR_SYNTAX,
'-292' => DB_ERROR_CONSTRAINT_NOT_NULL,
'-310' => DB_ERROR_ALREADY_EXISTS,
'-316' => DB_ERROR_ALREADY_EXISTS,
'-319' => DB_ERROR_NOT_FOUND,
'-329' => DB_ERROR_NODBSELECTED,
'-346' => DB_ERROR_CONSTRAINT,
'-386' => DB_ERROR_CONSTRAINT_NOT_NULL,
'-391' => DB_ERROR_CONSTRAINT_NOT_NULL,
'-554' => DB_ERROR_SYNTAX,
'-691' => DB_ERROR_CONSTRAINT,
'-692' => DB_ERROR_CONSTRAINT,
'-703' => DB_ERROR_CONSTRAINT_NOT_NULL,
'-1204' => DB_ERROR_INVALID_DATE,
'-1205' => DB_ERROR_INVALID_DATE,
'-1206' => DB_ERROR_INVALID_DATE,
'-1209' => DB_ERROR_INVALID_DATE,
'-1210' => DB_ERROR_INVALID_DATE,
'-1212' => DB_ERROR_INVALID_DATE,
'-1213' => DB_ERROR_INVALID_NUMBER,
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* Should data manipulation queries be committed automatically?
* @var bool
* @access private
*/
var $autocommit = true;
 
/**
* The quantity of transactions begun
*
* {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
* @access private
*/
var $transaction_opcount = 0;
 
/**
* The number of rows affected by a data manipulation query
* @var integer
* @access private
*/
var $affected = 0;
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_ifx()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('informix') &&
!PEAR::loadExtension('Informix'))
{
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
$dbhost = $dsn['hostspec'] ? '@' . $dsn['hostspec'] : '';
$dbname = $dsn['database'] ? $dsn['database'] . $dbhost : '';
$user = $dsn['username'] ? $dsn['username'] : '';
$pw = $dsn['password'] ? $dsn['password'] : '';
 
$connect_function = $persistent ? 'ifx_pconnect' : 'ifx_connect';
 
$this->connection = @$connect_function($dbname, $user, $pw);
if (!is_resource($this->connection)) {
return $this->ifxRaiseError(DB_ERROR_CONNECT_FAILED);
}
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @ifx_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$ismanip = DB::isManip($query);
$this->last_query = $query;
$this->affected = null;
if (preg_match('/(SELECT)/i', $query)) { //TESTME: Use !DB::isManip()?
// the scroll is needed for fetching absolute row numbers
// in a select query result
$result = @ifx_query($query, $this->connection, IFX_SCROLL);
} else {
if (!$this->autocommit && $ismanip) {
if ($this->transaction_opcount == 0) {
$result = @ifx_query('BEGIN WORK', $this->connection);
if (!$result) {
return $this->ifxRaiseError();
}
}
$this->transaction_opcount++;
}
$result = @ifx_query($query, $this->connection);
}
if (!$result) {
return $this->ifxRaiseError();
}
$this->affected = @ifx_affected_rows($result);
// Determine which queries should return data, and which
// should return an error code only.
if (preg_match('/(SELECT)/i', $query)) {
return $result;
}
// XXX Testme: free results inside a transaction
// may cause to stop it and commit the work?
 
// Result has to be freed even with a insert or update
@ifx_free_result($result);
 
return DB_OK;
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal ifx result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
function nextResult($result)
{
return false;
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
if (DB::isManip($this->last_query)) {
return $this->affected;
} else {
return 0;
}
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if (($rownum !== null) && ($rownum < 0)) {
return null;
}
if ($rownum === null) {
/*
* Even though fetch_row() should return the next row if
* $rownum is null, it doesn't in all cases. Bug 598.
*/
$rownum = 'NEXT';
} else {
// Index starts at row 1, unlike most DBMS's starting at 0.
$rownum++;
}
if (!$arr = @ifx_fetch_row($result, $rownum)) {
return null;
}
if ($fetchmode !== DB_FETCHMODE_ASSOC) {
$i=0;
$order = array();
foreach ($arr as $val) {
$order[$i++] = $val;
}
$arr = $order;
} elseif ($fetchmode == DB_FETCHMODE_ASSOC &&
$this->options['portability'] & DB_PORTABILITY_LOWERCASE)
{
$arr = array_change_key_case($arr, CASE_LOWER);
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
if (!$cols = @ifx_num_fields($result)) {
return $this->ifxRaiseError();
}
return $cols;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return @ifx_free_result($result);
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff = true)
{
// XXX if $this->transaction_opcount > 0, we should probably
// issue a warning here.
$this->autocommit = $onoff ? true : false;
return DB_OK;
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
if ($this->transaction_opcount > 0) {
$result = @ifx_query('COMMIT WORK', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->ifxRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
if ($this->transaction_opcount > 0) {
$result = @ifx_query('ROLLBACK WORK', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->ifxRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ ifxRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_ifx::errorNative(), DB_ifx::errorCode()
*/
function ifxRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode(ifx_error());
}
return $this->raiseError($errno, null, null, null,
$this->errorNative());
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error code and message produced by the last query
*
* @return string the DBMS' error code and message
*/
function errorNative()
{
return @ifx_error() . ' ' . @ifx_errormsg();
}
 
// }}}
// {{{ errorCode()
 
/**
* Maps native error codes to DB's portable ones.
*
* Requires that the DB implementation's constructor fills
* in the <var>$errorcode_map</var> property.
*
* @param string $nativecode error code returned by the database
* @return int a portable DB error code, or DB_ERROR if this DB
* implementation has no mapping for the given error code.
*/
function errorCode($nativecode)
{
if (ereg('SQLCODE=(.*)]', $nativecode, $match)) {
$code = $match[1];
if (isset($this->errorcode_map[$code])) {
return $this->errorcode_map[$code];
}
}
return DB_ERROR;
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* NOTE: only supports 'table' if <var>$result</var> is a table name.
*
* If analyzing a query result and the result has duplicate field names,
* an error will be raised saying
* <samp>can't distinguish duplicate field names</samp>.
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
* @since Method available since Release 1.6.0
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @ifx_query("SELECT * FROM $result WHERE 1=0",
$this->connection);
$got_string = true;
} elseif (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$id = $result->result;
$got_string = false;
} else {
/*
* Probably received a result resource identifier.
* Copy it.
*/
$id = $result;
$got_string = false;
}
 
if (!is_resource($id)) {
return $this->ifxRaiseError(DB_ERROR_NEED_MORE_DATA);
}
 
$flds = @ifx_fieldproperties($id);
$count = @ifx_num_fields($id);
 
if (count($flds) != $count) {
return $this->raiseError("can't distinguish duplicate field names");
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$i = 0;
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
foreach ($flds as $key => $value) {
$props = explode(';', $value);
$res[$i] = array(
'table' => $got_string ? $case_func($result) : '',
'name' => $case_func($key),
'type' => $props[0],
'len' => $props[1],
'flags' => $props[4] == 'N' ? 'not_null' : '',
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
$i++;
}
 
// free the result only if we were called on a table
if ($got_string) {
@ifx_free_result($id);
}
return $res;
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'tables':
return 'SELECT tabname FROM systables WHERE tabid >= 100';
default:
return null;
}
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/pgsql.php
New file
0,0 → 1,1097
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's pgsql extension
* for interacting with PostgreSQL databases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Rui Hirokawa <hirokawa@php.net>
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: pgsql.php,v 1.126 2005/03/04 23:12:36 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's pgsql extension
* for interacting with PostgreSQL databases
*
* These methods overload the ones declared in DB_common.
*
* @category Database
* @package DB
* @author Rui Hirokawa <hirokawa@php.net>
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_pgsql extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'pgsql';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'pgsql';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => 'alter',
'new_link' => '4.3.0',
'numrows' => true,
'pconnect' => true,
'prepare' => false,
'ssl' => true,
'transactions' => true,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* Should data manipulation queries be committed automatically?
* @var bool
* @access private
*/
var $autocommit = true;
 
/**
* The quantity of transactions begun
*
* {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
* @access private
*/
var $transaction_opcount = 0;
 
/**
* The number of rows affected by a data manipulation query
* @var integer
*/
var $affected = 0;
 
/**
* The current row being looked at in fetchInto()
* @var array
* @access private
*/
var $row = array();
 
/**
* The number of rows in a given result set
* @var array
* @access private
*/
var $_num_rows = array();
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_pgsql()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* PEAR DB's pgsql driver supports the following extra DSN options:
* + connect_timeout How many seconds to wait for a connection to
* be established. Available since PEAR DB 1.7.0.
* + new_link If set to true, causes subsequent calls to
* connect() to return a new connection link
* instead of the existing one. WARNING: this is
* not portable to other DBMS's. Available only
* if PHP is >= 4.3.0 and PEAR DB is >= 1.7.0.
* + options Command line options to be sent to the server.
* Available since PEAR DB 1.6.4.
* + service Specifies a service name in pg_service.conf that
* holds additional connection parameters.
* Available since PEAR DB 1.7.0.
* + sslmode How should SSL be used when connecting? Values:
* disable, allow, prefer or require.
* Available since PEAR DB 1.7.0.
* + tty This was used to specify where to send server
* debug output. Available since PEAR DB 1.6.4.
*
* Example of connecting to a new link via a socket:
* <code>
* require_once 'DB.php';
*
* $dsn = 'pgsql://user:pass@unix(/tmp)/dbname?new_link=true';
* $options = array(
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
* </code>
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @link http://www.postgresql.org/docs/current/static/libpq.html#LIBPQ-CONNECT
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('pgsql')) {
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
$protocol = $dsn['protocol'] ? $dsn['protocol'] : 'tcp';
 
$params = array('');
if ($protocol == 'tcp') {
if ($dsn['hostspec']) {
$params[0] .= 'host=' . $dsn['hostspec'];
}
if ($dsn['port']) {
$params[0] .= ' port=' . $dsn['port'];
}
} elseif ($protocol == 'unix') {
// Allow for pg socket in non-standard locations.
if ($dsn['socket']) {
$params[0] .= 'host=' . $dsn['socket'];
}
if ($dsn['port']) {
$params[0] .= ' port=' . $dsn['port'];
}
}
if ($dsn['database']) {
$params[0] .= ' dbname=\'' . addslashes($dsn['database']) . '\'';
}
if ($dsn['username']) {
$params[0] .= ' user=\'' . addslashes($dsn['username']) . '\'';
}
if ($dsn['password']) {
$params[0] .= ' password=\'' . addslashes($dsn['password']) . '\'';
}
if (!empty($dsn['options'])) {
$params[0] .= ' options=' . $dsn['options'];
}
if (!empty($dsn['tty'])) {
$params[0] .= ' tty=' . $dsn['tty'];
}
if (!empty($dsn['connect_timeout'])) {
$params[0] .= ' connect_timeout=' . $dsn['connect_timeout'];
}
if (!empty($dsn['sslmode'])) {
$params[0] .= ' sslmode=' . $dsn['sslmode'];
}
if (!empty($dsn['service'])) {
$params[0] .= ' service=' . $dsn['service'];
}
 
if (isset($dsn['new_link'])
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true))
{
if (version_compare(phpversion(), '4.3.0', '>=')) {
$params[] = PGSQL_CONNECT_FORCE_NEW;
}
}
 
$connect_function = $persistent ? 'pg_pconnect' : 'pg_connect';
 
$ini = ini_get('track_errors');
$php_errormsg = '';
if ($ini) {
$this->connection = @call_user_func_array($connect_function,
$params);
} else {
ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function,
$params);
ini_set('track_errors', $ini);
}
 
if (!$this->connection) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$php_errormsg);
}
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @pg_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
if (!$this->autocommit && $ismanip) {
if ($this->transaction_opcount == 0) {
$result = @pg_exec($this->connection, 'begin;');
if (!$result) {
return $this->pgsqlRaiseError();
}
}
$this->transaction_opcount++;
}
$result = @pg_exec($this->connection, $query);
if (!$result) {
return $this->pgsqlRaiseError();
}
// Determine which queries that should return data, and which
// should return an error code only.
if ($ismanip) {
$this->affected = @pg_affected_rows($result);
return DB_OK;
} elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|SHOW)\s/si', $query)) {
/* PostgreSQL commands:
ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY,
CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH,
GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET,
REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW,
UNLISTEN, UPDATE, VACUUM
*/
$this->row[(int)$result] = 0; // reset the row counter.
$numrows = $this->numRows($result);
if (is_object($numrows)) {
return $numrows;
}
$this->_num_rows[(int)$result] = $numrows;
$this->affected = 0;
return $result;
} else {
$this->affected = 0;
return DB_OK;
}
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal pgsql result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
function nextResult($result)
{
return false;
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
$result_int = (int)$result;
$rownum = ($rownum !== null) ? $rownum : $this->row[$result_int];
if ($rownum >= $this->_num_rows[$result_int]) {
return null;
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @pg_fetch_array($result, $rownum, PGSQL_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @pg_fetch_row($result, $rownum);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
$this->row[$result_int] = ++$rownum;
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
if (is_resource($result)) {
unset($this->row[(int)$result]);
unset($this->_num_rows[(int)$result]);
$this->affected = 0;
return @pg_freeresult($result);
}
return false;
}
 
// }}}
// {{{ quote()
 
/**
* @deprecated Deprecated in release 1.6.0
* @internal
*/
function quote($str)
{
return $this->quoteSmart($str);
}
 
// }}}
// {{{ quoteSmart()
 
/**
* Formats input so it can be safely used in a query
*
* @param mixed $in the data to be formatted
*
* @return mixed the formatted data. The format depends on the input's
* PHP type:
* + null = the string <samp>NULL</samp>
* + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp>
* + integer or double = the unquoted number
* + other (including strings and numeric strings) =
* the data escaped according to MySQL's settings
* then encapsulated between single quotes
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
function quoteSmart($in)
{
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
return $in ? 'TRUE' : 'FALSE';
} elseif (is_null($in)) {
return 'NULL';
} else {
return "'" . $this->escapeSimple($in) . "'";
}
}
 
// }}}
// {{{ escapeSimple()
 
/**
* Escapes a string according to the current DBMS's standards
*
* {@internal PostgreSQL treats a backslash as an escape character,
* so they are escaped as well.
*
* Not using pg_escape_string() yet because it requires PostgreSQL
* to be at version 7.2 or greater.}}
*
* @param string $str the string to be escaped
*
* @return string the escaped string
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
function escapeSimple($str)
{
return str_replace("'", "''", str_replace('\\', '\\\\', $str));
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @pg_numfields($result);
if (!$cols) {
return $this->pgsqlRaiseError();
}
return $cols;
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
function numRows($result)
{
$rows = @pg_numrows($result);
if ($rows === null) {
return $this->pgsqlRaiseError();
}
return $rows;
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff = false)
{
// XXX if $this->transaction_opcount > 0, we should probably
// issue a warning here.
$this->autocommit = $onoff ? true : false;
return DB_OK;
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
if ($this->transaction_opcount > 0) {
// (disabled) hack to shut up error messages from libpq.a
//@fclose(@fopen("php://stderr", "w"));
$result = @pg_exec($this->connection, 'end;');
$this->transaction_opcount = 0;
if (!$result) {
return $this->pgsqlRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
if ($this->transaction_opcount > 0) {
$result = @pg_exec($this->connection, 'abort;');
$this->transaction_opcount = 0;
if (!$result) {
return $this->pgsqlRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
return $this->affected;
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_pgsql::createSequence(), DB_pgsql::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
$repeat = false;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result =& $this->query("SELECT NEXTVAL('${seqname}')");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = true;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->createSequence($seq_name);
$this->popErrorHandling();
if (DB::isError($result)) {
return $this->raiseError($result);
}
} else {
$repeat = false;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
$result->free();
return $arr[0];
}
 
// }}}
// {{{ createSequence()
 
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_pgsql::nextID(), DB_pgsql::dropSequence()
*/
function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$result = $this->query("CREATE SEQUENCE ${seqname}");
return $result;
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_pgsql::nextID(), DB_pgsql::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DROP SEQUENCE '
. $this->getSequenceName($seq_name));
}
 
// }}}
// {{{ modifyLimitQuery()
 
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
return "$query LIMIT $count OFFSET $from";
}
 
// }}}
// {{{ pgsqlRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_pgsql::errorNative(), DB_pgsql::errorCode()
*/
function pgsqlRaiseError($errno = null)
{
$native = $this->errorNative();
if ($errno === null) {
$errno = $this->errorCode($native);
}
return $this->raiseError($errno, null, null, null, $native);
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error message produced by the last query
*
* {@internal Error messages are used instead of error codes
* in order to support older versions of PostgreSQL.}}
*
* @return string the DBMS' error message
*/
function errorNative()
{
return @pg_errormessage($this->connection);
}
 
// }}}
// {{{ errorCode()
 
/**
* Determines PEAR::DB error code from the database's text error message.
*
* @param string $errormsg error message returned from the database
* @return integer an error number from a DB error constant
*/
function errorCode($errormsg)
{
static $error_regexps;
if (!isset($error_regexps)) {
$error_regexps = array(
'/(relation|sequence|table).*does not exist|class .* not found/i'
=> DB_ERROR_NOSUCHTABLE,
'/index .* does not exist/'
=> DB_ERROR_NOT_FOUND,
'/column .* does not exist/i'
=> DB_ERROR_NOSUCHFIELD,
'/relation .* already exists/i'
=> DB_ERROR_ALREADY_EXISTS,
'/(divide|division) by zero$/i'
=> DB_ERROR_DIVZERO,
'/pg_atoi: error in .*: can\'t parse /i'
=> DB_ERROR_INVALID_NUMBER,
'/invalid input syntax for( type)? (integer|numeric)/i'
=> DB_ERROR_INVALID_NUMBER,
'/value .* is out of range for type \w*int/i'
=> DB_ERROR_INVALID_NUMBER,
'/integer out of range/i'
=> DB_ERROR_INVALID_NUMBER,
'/value too long for type character/i'
=> DB_ERROR_INVALID,
'/attribute .* not found|relation .* does not have attribute/i'
=> DB_ERROR_NOSUCHFIELD,
'/column .* specified in USING clause does not exist in (left|right) table/i'
=> DB_ERROR_NOSUCHFIELD,
'/parser: parse error at or near/i'
=> DB_ERROR_SYNTAX,
'/syntax error at/'
=> DB_ERROR_SYNTAX,
'/column reference .* is ambiguous/i'
=> DB_ERROR_SYNTAX,
'/permission denied/'
=> DB_ERROR_ACCESS_VIOLATION,
'/violates not-null constraint/'
=> DB_ERROR_CONSTRAINT_NOT_NULL,
'/violates [\w ]+ constraint/'
=> DB_ERROR_CONSTRAINT,
'/referential integrity violation/'
=> DB_ERROR_CONSTRAINT,
'/more expressions than target columns/i'
=> DB_ERROR_VALUE_COUNT_ON_ROW,
);
}
foreach ($error_regexps as $regexp => $code) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
}
// Fall back to DB_ERROR if there was no mapping.
return DB_ERROR;
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
* is a table name.
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @pg_exec($this->connection, "SELECT * FROM $result LIMIT 0");
$got_string = true;
} elseif (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$id = $result->result;
$got_string = false;
} else {
/*
* Probably received a result resource identifier.
* Copy it.
* Deprecated. Here for compatibility only.
*/
$id = $result;
$got_string = false;
}
 
if (!is_resource($id)) {
return $this->pgsqlRaiseError(DB_ERROR_NEED_MORE_DATA);
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$count = @pg_numfields($id);
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
$res[$i] = array(
'table' => $got_string ? $case_func($result) : '',
'name' => $case_func(@pg_fieldname($id, $i)),
'type' => @pg_fieldtype($id, $i),
'len' => @pg_fieldsize($id, $i),
'flags' => $got_string
? $this->_pgFieldFlags($id, $i, $result)
: '',
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
// free the result only if we were called on a table
if ($got_string) {
@pg_freeresult($id);
}
return $res;
}
 
// }}}
// {{{ _pgFieldFlags()
 
/**
* Get a column's flags
*
* Supports "not_null", "default_value", "primary_key", "unique_key"
* and "multiple_key". The default value is passed through
* rawurlencode() in case there are spaces in it.
*
* @param int $resource the PostgreSQL result identifier
* @param int $num_field the field number
*
* @return string the flags
*
* @access private
*/
function _pgFieldFlags($resource, $num_field, $table_name)
{
$field_name = @pg_fieldname($resource, $num_field);
 
$result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef
FROM pg_attribute f, pg_class tab, pg_type typ
WHERE tab.relname = typ.typname
AND typ.typrelid = f.attrelid
AND f.attname = '$field_name'
AND tab.relname = '$table_name'");
if (@pg_numrows($result) > 0) {
$row = @pg_fetch_row($result, 0);
$flags = ($row[0] == 't') ? 'not_null ' : '';
 
if ($row[1] == 't') {
$result = @pg_exec($this->connection, "SELECT a.adsrc
FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a
WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid
AND f.attrelid = a.adrelid AND f.attname = '$field_name'
AND tab.relname = '$table_name' AND f.attnum = a.adnum");
$row = @pg_fetch_row($result, 0);
$num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]);
$flags .= 'default_' . rawurlencode($num) . ' ';
}
} else {
$flags = '';
}
$result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey
FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i
WHERE tab.relname = typ.typname
AND typ.typrelid = f.attrelid
AND f.attrelid = i.indrelid
AND f.attname = '$field_name'
AND tab.relname = '$table_name'");
$count = @pg_numrows($result);
 
for ($i = 0; $i < $count ; $i++) {
$row = @pg_fetch_row($result, $i);
$keys = explode(' ', $row[2]);
 
if (in_array($num_field + 1, $keys)) {
$flags .= ($row[0] == 't' && $row[1] == 'f') ? 'unique_key ' : '';
$flags .= ($row[1] == 't') ? 'primary_key ' : '';
if (count($keys) > 1)
$flags .= 'multiple_key ';
}
}
 
return trim($flags);
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'tables':
return 'SELECT c.relname AS "Name"'
. ' FROM pg_class c, pg_user u'
. ' WHERE c.relowner = u.usesysid'
. " AND c.relkind = 'r'"
. ' AND NOT EXISTS'
. ' (SELECT 1 FROM pg_views'
. ' WHERE viewname = c.relname)'
. " AND c.relname !~ '^(pg_|sql_)'"
. ' UNION'
. ' SELECT c.relname AS "Name"'
. ' FROM pg_class c'
. " WHERE c.relkind = 'r'"
. ' AND NOT EXISTS'
. ' (SELECT 1 FROM pg_views'
. ' WHERE viewname = c.relname)'
. ' AND NOT EXISTS'
. ' (SELECT 1 FROM pg_user'
. ' WHERE usesysid = c.relowner)'
. " AND c.relname !~ '^pg_'";
case 'schema.tables':
return "SELECT schemaname || '.' || tablename"
. ' AS "Name"'
. ' FROM pg_catalog.pg_tables'
. ' WHERE schemaname NOT IN'
. " ('pg_catalog', 'information_schema', 'pg_toast')";
case 'views':
// Table cols: viewname | viewowner | definition
return 'SELECT viewname from pg_views WHERE schemaname'
. " NOT IN ('information_schema', 'pg_catalog')";
case 'users':
// cols: usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd |valuntil
return 'SELECT usename FROM pg_user';
case 'databases':
return 'SELECT datname FROM pg_database';
case 'functions':
case 'procedures':
return 'SELECT proname FROM pg_proc WHERE proowner <> 1';
default:
return null;
}
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/sybase.php
New file
0,0 → 1,907
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's sybase extension
* for interacting with Sybase databases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Antônio Carlos Venâncio Júnior <floripa@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: sybase.php,v 1.78 2005/02/20 00:44:48 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's sybase extension
* for interacting with Sybase databases
*
* These methods overload the ones declared in DB_common.
*
* WARNING: This driver may fail with multiple connections under the
* same user/pass/host and different databases.
*
* @category Database
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Antônio Carlos Venâncio Júnior <floripa@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_sybase extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'sybase';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'sybase';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => 'emulate',
'new_link' => false,
'numrows' => true,
'pconnect' => true,
'prepare' => false,
'ssl' => false,
'transactions' => true,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* Should data manipulation queries be committed automatically?
* @var bool
* @access private
*/
var $autocommit = true;
 
/**
* The quantity of transactions begun
*
* {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
* @access private
*/
var $transaction_opcount = 0;
 
/**
* The database specified in the DSN
*
* It's a fix to allow calls to different databases in the same script.
*
* @var string
* @access private
*/
var $_db = '';
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_sybase()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* PEAR DB's sybase driver supports the following extra DSN options:
* + appname The application name to use on this connection.
* Available since PEAR DB 1.7.0.
* + charset The character set to use on this connection.
* Available since PEAR DB 1.7.0.
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('sybase') &&
!PEAR::loadExtension('sybase_ct'))
{
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
$dsn['hostspec'] = $dsn['hostspec'] ? $dsn['hostspec'] : 'localhost';
$dsn['password'] = !empty($dsn['password']) ? $dsn['password'] : false;
$dsn['charset'] = isset($dsn['charset']) ? $dsn['charset'] : false;
$dsn['appname'] = isset($dsn['appname']) ? $dsn['appname'] : false;
 
$connect_function = $persistent ? 'sybase_pconnect' : 'sybase_connect';
 
if ($dsn['username']) {
$this->connection = @$connect_function($dsn['hostspec'],
$dsn['username'],
$dsn['password'],
$dsn['charset'],
$dsn['appname']);
} else {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
'The DSN did not contain a username.');
}
 
if (!$this->connection) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
@sybase_get_last_message());
}
 
if ($dsn['database']) {
if (!@sybase_select_db($dsn['database'], $this->connection)) {
return $this->raiseError(DB_ERROR_NODBSELECTED,
null, null, null,
@sybase_get_last_message());
}
$this->_db = $dsn['database'];
}
 
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @sybase_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$ismanip = DB::isManip($query);
$this->last_query = $query;
if (!@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$query = $this->modifyQuery($query);
if (!$this->autocommit && $ismanip) {
if ($this->transaction_opcount == 0) {
$result = @sybase_query('BEGIN TRANSACTION', $this->connection);
if (!$result) {
return $this->sybaseRaiseError();
}
}
$this->transaction_opcount++;
}
$result = @sybase_query($query, $this->connection);
if (!$result) {
return $this->sybaseRaiseError();
}
if (is_resource($result)) {
return $result;
}
// Determine which queries that should return data, and which
// should return an error code only.
return $ismanip ? DB_OK : $result;
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal sybase result pointer to the next available result
*
* @param a valid sybase result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
function nextResult($result)
{
return false;
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@sybase_data_seek($result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
if (function_exists('sybase_fetch_assoc')) {
$arr = @sybase_fetch_assoc($result);
} else {
if ($arr = @sybase_fetch_array($result)) {
foreach ($arr as $key => $value) {
if (is_int($key)) {
unset($arr[$key]);
}
}
}
}
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @sybase_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return @sybase_free_result($result);
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @sybase_num_fields($result);
if (!$cols) {
return $this->sybaseRaiseError();
}
return $cols;
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
function numRows($result)
{
$rows = @sybase_num_rows($result);
if ($rows === false) {
return $this->sybaseRaiseError();
}
return $rows;
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
if (DB::isManip($this->last_query)) {
$result = @sybase_affected_rows($this->connection);
} else {
$result = 0;
}
return $result;
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_sybase::createSequence(), DB_sybase::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
if (!@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$repeat = 0;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE))
{
$repeat = 1;
$result = $this->createSequence($seq_name);
if (DB::isError($result)) {
return $this->raiseError($result);
}
} elseif (!DB::isError($result)) {
$result =& $this->query("SELECT @@IDENTITY FROM $seqname");
$repeat = 0;
} else {
$repeat = false;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$result = $result->fetchRow(DB_FETCHMODE_ORDERED);
return $result[0];
}
 
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_sybase::nextID(), DB_sybase::dropSequence()
*/
function createSequence($seq_name)
{
return $this->query('CREATE TABLE '
. $this->getSequenceName($seq_name)
. ' (id numeric(10, 0) IDENTITY NOT NULL,'
. ' vapor int NULL)');
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_sybase::nextID(), DB_sybase::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff = false)
{
// XXX if $this->transaction_opcount > 0, we should probably
// issue a warning here.
$this->autocommit = $onoff ? true : false;
return DB_OK;
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
if ($this->transaction_opcount > 0) {
if (!@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$result = @sybase_query('COMMIT', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->sybaseRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
if ($this->transaction_opcount > 0) {
if (!@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$result = @sybase_query('ROLLBACK', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->sybaseRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ sybaseRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_sybase::errorNative(), DB_sybase::errorCode()
*/
function sybaseRaiseError($errno = null)
{
$native = $this->errorNative();
if ($errno === null) {
$errno = $this->errorCode($native);
}
return $this->raiseError($errno, null, null, null, $native);
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error message produced by the last query
*
* @return string the DBMS' error message
*/
function errorNative()
{
return @sybase_get_last_message();
}
 
// }}}
// {{{ errorCode()
 
/**
* Determines PEAR::DB error code from the database's text error message.
*
* @param string $errormsg error message returned from the database
* @return integer an error number from a DB error constant
*/
function errorCode($errormsg)
{
static $error_regexps;
if (!isset($error_regexps)) {
$error_regexps = array(
'/Incorrect syntax near/'
=> DB_ERROR_SYNTAX,
'/^Unclosed quote before the character string [\"\'].*[\"\']\./'
=> DB_ERROR_SYNTAX,
'/Implicit conversion (from datatype|of NUMERIC value)/i'
=> DB_ERROR_INVALID_NUMBER,
'/Cannot drop the table [\"\'].+[\"\'], because it doesn\'t exist in the system catalogs\./'
=> DB_ERROR_NOSUCHTABLE,
'/Only the owner of object [\"\'].+[\"\'] or a user with System Administrator \(SA\) role can run this command\./'
=> DB_ERROR_ACCESS_VIOLATION,
'/^.+ permission denied on object .+, database .+, owner .+/'
=> DB_ERROR_ACCESS_VIOLATION,
'/^.* permission denied, database .+, owner .+/'
=> DB_ERROR_ACCESS_VIOLATION,
'/[^.*] not found\./'
=> DB_ERROR_NOSUCHTABLE,
'/There is already an object named/'
=> DB_ERROR_ALREADY_EXISTS,
'/Invalid column name/'
=> DB_ERROR_NOSUCHFIELD,
'/does not allow null values/'
=> DB_ERROR_CONSTRAINT_NOT_NULL,
'/Command has been aborted/'
=> DB_ERROR_CONSTRAINT,
'/^Cannot drop the index .* because it doesn\'t exist/i'
=> DB_ERROR_NOT_FOUND,
'/^There is already an index/i'
=> DB_ERROR_ALREADY_EXISTS,
'/^There are fewer columns in the INSERT statement than values specified/i'
=> DB_ERROR_VALUE_COUNT_ON_ROW,
);
}
 
foreach ($error_regexps as $regexp => $code) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
}
return DB_ERROR;
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
* is a table name.
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
* @since Method available since Release 1.6.0
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
if (!@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$id = @sybase_query("SELECT * FROM $result WHERE 1=0",
$this->connection);
$got_string = true;
} elseif (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$id = $result->result;
$got_string = false;
} else {
/*
* Probably received a result resource identifier.
* Copy it.
* Deprecated. Here for compatibility only.
*/
$id = $result;
$got_string = false;
}
 
if (!is_resource($id)) {
return $this->sybaseRaiseError(DB_ERROR_NEED_MORE_DATA);
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$count = @sybase_num_fields($id);
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
$f = @sybase_fetch_field($id, $i);
// column_source is often blank
$res[$i] = array(
'table' => $got_string
? $case_func($result)
: $case_func($f->column_source),
'name' => $case_func($f->name),
'type' => $f->type,
'len' => $f->max_length,
'flags' => '',
);
if ($res[$i]['table']) {
$res[$i]['flags'] = $this->_sybase_field_flags(
$res[$i]['table'], $res[$i]['name']);
}
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
// free the result only if we were called on a table
if ($got_string) {
@sybase_free_result($id);
}
return $res;
}
 
// }}}
// {{{ _sybase_field_flags()
 
/**
* Get the flags for a field
*
* Currently supports:
* + <samp>unique_key</samp> (unique index, unique check or primary_key)
* + <samp>multiple_key</samp> (multi-key index)
*
* @param string $table the table name
* @param string $column the field name
*
* @return string space delimited string of flags. Empty string if none.
*
* @access private
*/
function _sybase_field_flags($table, $column)
{
static $tableName = null;
static $flags = array();
 
if ($table != $tableName) {
$flags = array();
$tableName = $table;
 
// get unique/primary keys
$res = $this->getAll("sp_helpindex $table", DB_FETCHMODE_ASSOC);
 
if (!isset($res[0]['index_description'])) {
return '';
}
 
foreach ($res as $val) {
$keys = explode(', ', trim($val['index_keys']));
 
if (sizeof($keys) > 1) {
foreach ($keys as $key) {
$this->_add_flag($flags[$key], 'multiple_key');
}
}
 
if (strpos($val['index_description'], 'unique')) {
foreach ($keys as $key) {
$this->_add_flag($flags[$key], 'unique_key');
}
}
}
 
}
 
if (array_key_exists($column, $flags)) {
return(implode(' ', $flags[$column]));
}
 
return '';
}
 
// }}}
// {{{ _add_flag()
 
/**
* Adds a string to the flags array if the flag is not yet in there
* - if there is no flag present the array is created
*
* @param array $array reference of flags array to add a value to
* @param mixed $value value to add to the flag array
*
* @return void
*
* @access private
*/
function _add_flag(&$array, $value)
{
if (!is_array($array)) {
$array = array($value);
} elseif (!in_array($value, $array)) {
array_push($array, $value);
}
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'tables':
return "SELECT name FROM sysobjects WHERE type = 'U'"
. ' ORDER BY name';
case 'views':
return "SELECT name FROM sysobjects WHERE type = 'V'";
default:
return null;
}
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/common.php
New file
0,0 → 1,2157
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the DB_common base class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: common.php,v 1.137 2005/04/07 14:27:35 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the PEAR class so it can be extended from
*/
require_once 'PEAR.php';
 
/**
* DB_common is the base class from which each database driver class extends
*
* All common methods are declared here. If a given DBMS driver contains
* a particular method, that method will overload the one here.
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_common extends PEAR
{
// {{{ properties
 
/**
* The current default fetch mode
* @var integer
*/
var $fetchmode = DB_FETCHMODE_ORDERED;
 
/**
* The name of the class into which results should be fetched when
* DB_FETCHMODE_OBJECT is in effect
*
* @var string
*/
var $fetchmode_object_class = 'stdClass';
 
/**
* Was a connection present when the object was serialized()?
* @var bool
* @see DB_common::__sleep(), DB_common::__wake()
*/
var $was_connected = null;
 
/**
* The most recently executed query
* @var string
*/
var $last_query = '';
 
/**
* Run-time configuration options
*
* The 'optimize' option has been deprecated. Use the 'portability'
* option instead.
*
* @var array
* @see DB_common::setOption()
*/
var $options = array(
'result_buffering' => 500,
'persistent' => false,
'ssl' => false,
'debug' => 0,
'seqname_format' => '%s_seq',
'autofree' => false,
'portability' => DB_PORTABILITY_NONE,
'optimize' => 'performance', // Deprecated. Use 'portability'.
);
 
/**
* The parameters from the most recently executed query
* @var array
* @since Property available since Release 1.7.0
*/
var $last_parameters = array();
 
/**
* The elements from each prepared statement
* @var array
*/
var $prepare_tokens = array();
 
/**
* The data types of the various elements in each prepared statement
* @var array
*/
var $prepare_types = array();
 
/**
* The prepared queries
* @var array
*/
var $prepared_queries = array();
 
 
// }}}
// {{{ DB_common
 
/**
* This constructor calls <kbd>$this->PEAR('DB_Error')</kbd>
*
* @return void
*/
function DB_common()
{
$this->PEAR('DB_Error');
}
 
// }}}
// {{{ __sleep()
 
/**
* Automatically indicates which properties should be saved
* when PHP's serialize() function is called
*
* @return array the array of properties names that should be saved
*/
function __sleep()
{
if ($this->connection) {
// Don't disconnect(), people use serialize() for many reasons
$this->was_connected = true;
} else {
$this->was_connected = false;
}
if (isset($this->autocommit)) {
return array('autocommit',
'dbsyntax',
'dsn',
'features',
'fetchmode',
'fetchmode_object_class',
'options',
'was_connected',
);
} else {
return array('dbsyntax',
'dsn',
'features',
'fetchmode',
'fetchmode_object_class',
'options',
'was_connected',
);
}
}
 
// }}}
// {{{ __wakeup()
 
/**
* Automatically reconnects to the database when PHP's unserialize()
* function is called
*
* The reconnection attempt is only performed if the object was connected
* at the time PHP's serialize() function was run.
*
* @return void
*/
function __wakeup()
{
if ($this->was_connected) {
$this->connect($this->dsn, $this->options);
}
}
 
// }}}
// {{{ __toString()
 
/**
* Automatic string conversion for PHP 5
*
* @return string a string describing the current PEAR DB object
*
* @since Method available since Release 1.7.0
*/
function __toString()
{
$info = strtolower(get_class($this));
$info .= ': (phptype=' . $this->phptype .
', dbsyntax=' . $this->dbsyntax .
')';
if ($this->connection) {
$info .= ' [connected]';
}
return $info;
}
 
// }}}
// {{{ toString()
 
/**
* DEPRECATED: String conversion method
*
* @return string a string describing the current PEAR DB object
*
* @deprecated Method deprecated in Release 1.7.0
*/
function toString()
{
return $this->__toString();
}
 
// }}}
// {{{ quoteString()
 
/**
* DEPRECATED: Quotes a string so it can be safely used within string
* delimiters in a query
*
* @param string $string the string to be quoted
*
* @return string the quoted string
*
* @see DB_common::quoteSmart(), DB_common::escapeSimple()
* @deprecated Method deprecated some time before Release 1.2
*/
function quoteString($string)
{
$string = $this->quote($string);
if ($string{0} == "'") {
return substr($string, 1, -1);
}
return $string;
}
 
// }}}
// {{{ quote()
 
/**
* DEPRECATED: Quotes a string so it can be safely used in a query
*
* @param string $string the string to quote
*
* @return string the quoted string or the string <samp>NULL</samp>
* if the value submitted is <kbd>null</kbd>.
*
* @see DB_common::quoteSmart(), DB_common::escapeSimple()
* @deprecated Deprecated in release 1.6.0
*/
function quote($string = null)
{
return ($string === null) ? 'NULL'
: "'" . str_replace("'", "''", $string) . "'";
}
 
// }}}
// {{{ quoteIdentifier()
 
/**
* Quotes a string so it can be safely used as a table or column name
*
* Delimiting style depends on which database driver is being used.
*
* NOTE: just because you CAN use delimited identifiers doesn't mean
* you SHOULD use them. In general, they end up causing way more
* problems than they solve.
*
* Portability is broken by using the following characters inside
* delimited identifiers:
* + backtick (<kbd>`</kbd>) -- due to MySQL
* + double quote (<kbd>"</kbd>) -- due to Oracle
* + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
*
* Delimited identifiers are known to generally work correctly under
* the following drivers:
* + mssql
* + mysql
* + mysqli
* + oci8
* + odbc(access)
* + odbc(db2)
* + pgsql
* + sqlite
* + sybase (must execute <kbd>set quoted_identifier on</kbd> sometime
* prior to use)
*
* InterBase doesn't seem to be able to use delimited identifiers
* via PHP 4. They work fine under PHP 5.
*
* @param string $str the identifier name to be quoted
*
* @return string the quoted identifier
*
* @since Method available since Release 1.6.0
*/
function quoteIdentifier($str)
{
return '"' . str_replace('"', '""', $str) . '"';
}
 
// }}}
// {{{ quoteSmart()
 
/**
* Formats input so it can be safely used in a query
*
* The output depends on the PHP data type of input and the database
* type being used.
*
* @param mixed $in the data to be formatted
*
* @return mixed the formatted data. The format depends on the input's
* PHP type:
* <ul>
* <li>
* <kbd>input</kbd> -> <samp>returns</samp>
* </li>
* <li>
* <kbd>null</kbd> -> the string <samp>NULL</samp>
* </li>
* <li>
* <kbd>integer</kbd> or <kbd>double</kbd> -> the unquoted number
* </li>
* <li>
* <kbd>bool</kbd> -> output depends on the driver in use
* Most drivers return integers: <samp>1</samp> if
* <kbd>true</kbd> or <samp>0</samp> if
* <kbd>false</kbd>.
* Some return strings: <samp>TRUE</samp> if
* <kbd>true</kbd> or <samp>FALSE</samp> if
* <kbd>false</kbd>.
* Finally one returns strings: <samp>T</samp> if
* <kbd>true</kbd> or <samp>F</samp> if
* <kbd>false</kbd>. Here is a list of each DBMS,
* the values returned and the suggested column type:
* <ul>
* <li>
* <kbd>dbase</kbd> -> <samp>T/F</samp>
* (<kbd>Logical</kbd>)
* </li>
* <li>
* <kbd>fbase</kbd> -> <samp>TRUE/FALSE</samp>
* (<kbd>BOOLEAN</kbd>)
* </li>
* <li>
* <kbd>ibase</kbd> -> <samp>1/0</samp>
* (<kbd>SMALLINT</kbd>) [1]
* </li>
* <li>
* <kbd>ifx</kbd> -> <samp>1/0</samp>
* (<kbd>SMALLINT</kbd>) [1]
* </li>
* <li>
* <kbd>msql</kbd> -> <samp>1/0</samp>
* (<kbd>INTEGER</kbd>)
* </li>
* <li>
* <kbd>mssql</kbd> -> <samp>1/0</samp>
* (<kbd>BIT</kbd>)
* </li>
* <li>
* <kbd>mysql</kbd> -> <samp>1/0</samp>
* (<kbd>TINYINT(1)</kbd>)
* </li>
* <li>
* <kbd>mysqli</kbd> -> <samp>1/0</samp>
* (<kbd>TINYINT(1)</kbd>)
* </li>
* <li>
* <kbd>oci8</kbd> -> <samp>1/0</samp>
* (<kbd>NUMBER(1)</kbd>)
* </li>
* <li>
* <kbd>odbc</kbd> -> <samp>1/0</samp>
* (<kbd>SMALLINT</kbd>) [1]
* </li>
* <li>
* <kbd>pgsql</kbd> -> <samp>TRUE/FALSE</samp>
* (<kbd>BOOLEAN</kbd>)
* </li>
* <li>
* <kbd>sqlite</kbd> -> <samp>1/0</samp>
* (<kbd>INTEGER</kbd>)
* </li>
* <li>
* <kbd>sybase</kbd> -> <samp>1/0</samp>
* (<kbd>TINYINT(1)</kbd>)
* </li>
* </ul>
* [1] Accommodate the lowest common denominator because not all
* versions of have <kbd>BOOLEAN</kbd>.
* </li>
* <li>
* other (including strings and numeric strings) ->
* the data with single quotes escaped by preceeding
* single quotes, backslashes are escaped by preceeding
* backslashes, then the whole string is encapsulated
* between single quotes
* </li>
* </ul>
*
* @see DB_common::escapeSimple()
* @since Method available since Release 1.6.0
*/
function quoteSmart($in)
{
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
return $in ? 1 : 0;
} elseif (is_null($in)) {
return 'NULL';
} else {
return "'" . $this->escapeSimple($in) . "'";
}
}
 
// }}}
// {{{ escapeSimple()
 
/**
* Escapes a string according to the current DBMS's standards
*
* In SQLite, this makes things safe for inserts/updates, but may
* cause problems when performing text comparisons against columns
* containing binary data. See the
* {@link http://php.net/sqlite_escape_string PHP manual} for more info.
*
* @param string $str the string to be escaped
*
* @return string the escaped string
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
function escapeSimple($str)
{
return str_replace("'", "''", $str);
}
 
// }}}
// {{{ provides()
 
/**
* Tells whether the present driver supports a given feature
*
* @param string $feature the feature you're curious about
*
* @return bool whether this driver supports $feature
*/
function provides($feature)
{
return $this->features[$feature];
}
 
// }}}
// {{{ setFetchMode()
 
/**
* Sets the fetch mode that should be used by default for query results
*
* @param integer $fetchmode DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC
* or DB_FETCHMODE_OBJECT
* @param string $object_class the class name of the object to be returned
* by the fetch methods when the
* DB_FETCHMODE_OBJECT mode is selected.
* If no class is specified by default a cast
* to object from the assoc array row will be
* done. There is also the posibility to use
* and extend the 'DB_row' class.
*
* @see DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT
*/
function setFetchMode($fetchmode, $object_class = 'stdClass')
{
switch ($fetchmode) {
case DB_FETCHMODE_OBJECT:
$this->fetchmode_object_class = $object_class;
case DB_FETCHMODE_ORDERED:
case DB_FETCHMODE_ASSOC:
$this->fetchmode = $fetchmode;
break;
default:
return $this->raiseError('invalid fetchmode mode');
}
}
 
// }}}
// {{{ setOption()
 
/**
* Sets run-time configuration options for PEAR DB
*
* Options, their data types, default values and description:
* <ul>
* <li>
* <var>autofree</var> <kbd>boolean</kbd> = <samp>false</samp>
* <br />should results be freed automatically when there are no
* more rows?
* </li><li>
* <var>result_buffering</var> <kbd>integer</kbd> = <samp>500</samp>
* <br />how many rows of the result set should be buffered?
* <br />In mysql: mysql_unbuffered_query() is used instead of
* mysql_query() if this value is 0. (Release 1.7.0)
* <br />In oci8: this value is passed to ocisetprefetch().
* (Release 1.7.0)
* </li><li>
* <var>debug</var> <kbd>integer</kbd> = <samp>0</samp>
* <br />debug level
* </li><li>
* <var>persistent</var> <kbd>boolean</kbd> = <samp>false</samp>
* <br />should the connection be persistent?
* </li><li>
* <var>portability</var> <kbd>integer</kbd> = <samp>DB_PORTABILITY_NONE</samp>
* <br />portability mode constant (see below)
* </li><li>
* <var>seqname_format</var> <kbd>string</kbd> = <samp>%s_seq</samp>
* <br />the sprintf() format string used on sequence names. This
* format is applied to sequence names passed to
* createSequence(), nextID() and dropSequence().
* </li><li>
* <var>ssl</var> <kbd>boolean</kbd> = <samp>false</samp>
* <br />use ssl to connect?
* </li>
* </ul>
*
* -----------------------------------------
*
* PORTABILITY MODES
*
* These modes are bitwised, so they can be combined using <kbd>|</kbd>
* and removed using <kbd>^</kbd>. See the examples section below on how
* to do this.
*
* <samp>DB_PORTABILITY_NONE</samp>
* turn off all portability features
*
* This mode gets automatically turned on if the deprecated
* <var>optimize</var> option gets set to <samp>performance</samp>.
*
*
* <samp>DB_PORTABILITY_LOWERCASE</samp>
* convert names of tables and fields to lower case when using
* <kbd>get*()</kbd>, <kbd>fetch*()</kbd> and <kbd>tableInfo()</kbd>
*
* This mode gets automatically turned on in the following databases
* if the deprecated option <var>optimize</var> gets set to
* <samp>portability</samp>:
* + oci8
*
*
* <samp>DB_PORTABILITY_RTRIM</samp>
* right trim the data output by <kbd>get*()</kbd> <kbd>fetch*()</kbd>
*
*
* <samp>DB_PORTABILITY_DELETE_COUNT</samp>
* force reporting the number of rows deleted
*
* Some DBMS's don't count the number of rows deleted when performing
* simple <kbd>DELETE FROM tablename</kbd> queries. This portability
* mode tricks such DBMS's into telling the count by adding
* <samp>WHERE 1=1</samp> to the end of <kbd>DELETE</kbd> queries.
*
* This mode gets automatically turned on in the following databases
* if the deprecated option <var>optimize</var> gets set to
* <samp>portability</samp>:
* + fbsql
* + mysql
* + mysqli
* + sqlite
*
*
* <samp>DB_PORTABILITY_NUMROWS</samp>
* enable hack that makes <kbd>numRows()</kbd> work in Oracle
*
* This mode gets automatically turned on in the following databases
* if the deprecated option <var>optimize</var> gets set to
* <samp>portability</samp>:
* + oci8
*
*
* <samp>DB_PORTABILITY_ERRORS</samp>
* makes certain error messages in certain drivers compatible
* with those from other DBMS's
*
* + mysql, mysqli: change unique/primary key constraints
* DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
*
* + odbc(access): MS's ODBC driver reports 'no such field' as code
* 07001, which means 'too few parameters.' When this option is on
* that code gets mapped to DB_ERROR_NOSUCHFIELD.
* DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD
*
* <samp>DB_PORTABILITY_NULL_TO_EMPTY</samp>
* convert null values to empty strings in data output by get*() and
* fetch*(). Needed because Oracle considers empty strings to be null,
* while most other DBMS's know the difference between empty and null.
*
*
* <samp>DB_PORTABILITY_ALL</samp>
* turn on all portability features
*
* -----------------------------------------
*
* Example 1. Simple setOption() example
* <code>
* $db->setOption('autofree', true);
* </code>
*
* Example 2. Portability for lowercasing and trimming
* <code>
* $db->setOption('portability',
* DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM);
* </code>
*
* Example 3. All portability options except trimming
* <code>
* $db->setOption('portability',
* DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM);
* </code>
*
* @param string $option option name
* @param mixed $value value for the option
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::$options
*/
function setOption($option, $value)
{
if (isset($this->options[$option])) {
$this->options[$option] = $value;
 
/*
* Backwards compatibility check for the deprecated 'optimize'
* option. Done here in case settings change after connecting.
*/
if ($option == 'optimize') {
if ($value == 'portability') {
switch ($this->phptype) {
case 'oci8':
$this->options['portability'] =
DB_PORTABILITY_LOWERCASE |
DB_PORTABILITY_NUMROWS;
break;
case 'fbsql':
case 'mysql':
case 'mysqli':
case 'sqlite':
$this->options['portability'] =
DB_PORTABILITY_DELETE_COUNT;
break;
}
} else {
$this->options['portability'] = DB_PORTABILITY_NONE;
}
}
 
return DB_OK;
}
return $this->raiseError("unknown option $option");
}
 
// }}}
// {{{ getOption()
 
/**
* Returns the value of an option
*
* @param string $option the option name you're curious about
*
* @return mixed the option's value
*/
function getOption($option)
{
if (isset($this->options[$option])) {
return $this->options[$option];
}
return $this->raiseError("unknown option $option");
}
 
// }}}
// {{{ prepare()
 
/**
* Prepares a query for multiple execution with execute()
*
* Creates a query that can be run multiple times. Each time it is run,
* the placeholders, if any, will be replaced by the contents of
* execute()'s $data argument.
*
* Three types of placeholders can be used:
* + <kbd>?</kbd> scalar value (i.e. strings, integers). The system
* will automatically quote and escape the data.
* + <kbd>!</kbd> value is inserted 'as is'
* + <kbd>&</kbd> requires a file name. The file's contents get
* inserted into the query (i.e. saving binary
* data in a db)
*
* Example 1.
* <code>
* $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
* $data = array(
* "John's text",
* "'it''s good'",
* 'filename.txt'
* );
* $res = $db->execute($sth, $data);
* </code>
*
* Use backslashes to escape placeholder characters if you don't want
* them to be interpreted as placeholders:
* <pre>
* "UPDATE foo SET col=? WHERE col='over \& under'"
* </pre>
*
* With some database backends, this is emulated.
*
* {@internal ibase and oci8 have their own prepare() methods.}}
*
* @param string $query the query to be prepared
*
* @return mixed DB statement resource on success. A DB_Error object
* on failure.
*
* @see DB_common::execute()
*/
function prepare($query)
{
$tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1,
PREG_SPLIT_DELIM_CAPTURE);
$token = 0;
$types = array();
$newtokens = array();
 
foreach ($tokens as $val) {
switch ($val) {
case '?':
$types[$token++] = DB_PARAM_SCALAR;
break;
case '&':
$types[$token++] = DB_PARAM_OPAQUE;
break;
case '!':
$types[$token++] = DB_PARAM_MISC;
break;
default:
$newtokens[] = preg_replace('/\\\([&?!])/', "\\1", $val);
}
}
 
$this->prepare_tokens[] = &$newtokens;
end($this->prepare_tokens);
 
$k = key($this->prepare_tokens);
$this->prepare_types[$k] = $types;
$this->prepared_queries[$k] = implode(' ', $newtokens);
 
return $k;
}
 
// }}}
// {{{ autoPrepare()
 
/**
* Automaticaly generates an insert or update query and pass it to prepare()
*
* @param string $table the table name
* @param array $table_fields the array of field names
* @param int $mode a type of query to make:
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
* @param string $where for update queries: the WHERE clause to
* append to the SQL statement. Don't
* include the "WHERE" keyword.
*
* @return resource the query handle
*
* @uses DB_common::prepare(), DB_common::buildManipSQL()
*/
function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT,
$where = false)
{
$query = $this->buildManipSQL($table, $table_fields, $mode, $where);
if (DB::isError($query)) {
return $query;
}
return $this->prepare($query);
}
 
// }}}
// {{{ autoExecute()
 
/**
* Automaticaly generates an insert or update query and call prepare()
* and execute() with it
*
* @param string $table the table name
* @param array $fields_values the associative array where $key is a
* field name and $value its value
* @param int $mode a type of query to make:
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
* @param string $where for update queries: the WHERE clause to
* append to the SQL statement. Don't
* include the "WHERE" keyword.
*
* @return mixed a new DB_result object for successful SELECT queries
* or DB_OK for successul data manipulation queries.
* A DB_Error object on failure.
*
* @uses DB_common::autoPrepare(), DB_common::execute()
*/
function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT,
$where = false)
{
$sth = $this->autoPrepare($table, array_keys($fields_values), $mode,
$where);
if (DB::isError($sth)) {
return $sth;
}
$ret =& $this->execute($sth, array_values($fields_values));
$this->freePrepared($sth);
return $ret;
 
}
 
// }}}
// {{{ buildManipSQL()
 
/**
* Produces an SQL query string for autoPrepare()
*
* Example:
* <pre>
* buildManipSQL('table_sql', array('field1', 'field2', 'field3'),
* DB_AUTOQUERY_INSERT);
* </pre>
*
* That returns
* <samp>
* INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
* </samp>
*
* NOTES:
* - This belongs more to a SQL Builder class, but this is a simple
* facility.
* - Be carefull! If you don't give a $where param with an UPDATE
* query, all the records of the table will be updated!
*
* @param string $table the table name
* @param array $table_fields the array of field names
* @param int $mode a type of query to make:
* DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
* @param string $where for update queries: the WHERE clause to
* append to the SQL statement. Don't
* include the "WHERE" keyword.
*
* @return string the sql query for autoPrepare()
*/
function buildManipSQL($table, $table_fields, $mode, $where = false)
{
if (count($table_fields) == 0) {
return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
}
$first = true;
switch ($mode) {
case DB_AUTOQUERY_INSERT:
$values = '';
$names = '';
foreach ($table_fields as $value) {
if ($first) {
$first = false;
} else {
$names .= ',';
$values .= ',';
}
$names .= $value;
$values .= '?';
}
return "INSERT INTO $table ($names) VALUES ($values)";
case DB_AUTOQUERY_UPDATE:
$set = '';
foreach ($table_fields as $value) {
if ($first) {
$first = false;
} else {
$set .= ',';
}
$set .= "$value = ?";
}
$sql = "UPDATE $table SET $set";
if ($where) {
$sql .= " WHERE $where";
}
return $sql;
default:
return $this->raiseError(DB_ERROR_SYNTAX);
}
}
 
// }}}
// {{{ execute()
 
/**
* Executes a DB statement prepared with prepare()
*
* Example 1.
* <code>
* $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
* $data = array(
* "John's text",
* "'it''s good'",
* 'filename.txt'
* );
* $res =& $db->execute($sth, $data);
* </code>
*
* @param resource $stmt a DB statement resource returned from prepare()
* @param mixed $data array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return mixed a new DB_result object for successful SELECT queries
* or DB_OK for successul data manipulation queries.
* A DB_Error object on failure.
*
* {@internal ibase and oci8 have their own execute() methods.}}
*
* @see DB_common::prepare()
*/
function &execute($stmt, $data = array())
{
$realquery = $this->executeEmulateQuery($stmt, $data);
if (DB::isError($realquery)) {
return $realquery;
}
$result = $this->simpleQuery($realquery);
 
if ($result === DB_OK || DB::isError($result)) {
return $result;
} else {
$tmp =& new DB_result($this, $result);
return $tmp;
}
}
 
// }}}
// {{{ executeEmulateQuery()
 
/**
* Emulates executing prepared statements if the DBMS not support them
*
* @param resource $stmt a DB statement resource returned from execute()
* @param mixed $data array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return mixed a string containing the real query run when emulating
* prepare/execute. A DB_Error object on failure.
*
* @access protected
* @see DB_common::execute()
*/
function executeEmulateQuery($stmt, $data = array())
{
$stmt = (int)$stmt;
$data = (array)$data;
$this->last_parameters = $data;
 
if (count($this->prepare_types[$stmt]) != count($data)) {
$this->last_query = $this->prepared_queries[$stmt];
return $this->raiseError(DB_ERROR_MISMATCH);
}
 
$realquery = $this->prepare_tokens[$stmt][0];
 
$i = 0;
foreach ($data as $value) {
if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) {
$realquery .= $this->quoteSmart($value);
} elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) {
$fp = @fopen($value, 'rb');
if (!$fp) {
return $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
}
$realquery .= $this->quoteSmart(fread($fp, filesize($value)));
fclose($fp);
} else {
$realquery .= $value;
}
 
$realquery .= $this->prepare_tokens[$stmt][++$i];
}
 
return $realquery;
}
 
// }}}
// {{{ executeMultiple()
 
/**
* Performs several execute() calls on the same statement handle
*
* $data must be an array indexed numerically
* from 0, one execute call is done for every "row" in the array.
*
* If an error occurs during execute(), executeMultiple() does not
* execute the unfinished rows, but rather returns that error.
*
* @param resource $stmt query handle from prepare()
* @param array $data numeric array containing the
* data to insert into the query
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::prepare(), DB_common::execute()
*/
function executeMultiple($stmt, $data)
{
foreach ($data as $value) {
$res =& $this->execute($stmt, $value);
if (DB::isError($res)) {
return $res;
}
}
return DB_OK;
}
 
// }}}
// {{{ freePrepared()
 
/**
* Frees the internal resources associated with a prepared query
*
* @param resource $stmt the prepared statement's PHP resource
* @param bool $free_resource should the PHP resource be freed too?
* Use false if you need to get data
* from the result set later.
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_common::prepare()
*/
function freePrepared($stmt, $free_resource = true)
{
$stmt = (int)$stmt;
if (isset($this->prepare_tokens[$stmt])) {
unset($this->prepare_tokens[$stmt]);
unset($this->prepare_types[$stmt]);
unset($this->prepared_queries[$stmt]);
return true;
}
return false;
}
 
// }}}
// {{{ modifyQuery()
 
/**
* Changes a query string for various DBMS specific reasons
*
* It is defined here to ensure all drivers have this method available.
*
* @param string $query the query string to modify
*
* @return string the modified query string
*
* @access protected
* @see DB_mysql::modifyQuery(), DB_oci8::modifyQuery(),
* DB_sqlite::modifyQuery()
*/
function modifyQuery($query)
{
return $query;
}
 
// }}}
// {{{ modifyLimitQuery()
 
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* It is defined here to assure that all implementations
* have this method defined.
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
return $query;
}
 
// }}}
// {{{ query()
 
/**
* Sends a query to the database server
*
* The query string can be either a normal statement to be sent directly
* to the server OR if <var>$params</var> are passed the query can have
* placeholders and it will be passed through prepare() and execute().
*
* @param string $query the SQL query or the statement to prepare
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return mixed a new DB_result object for successful SELECT queries
* or DB_OK for successul data manipulation queries.
* A DB_Error object on failure.
*
* @see DB_result, DB_common::prepare(), DB_common::execute()
*/
function &query($query, $params = array())
{
if (sizeof($params) > 0) {
$sth = $this->prepare($query);
if (DB::isError($sth)) {
return $sth;
}
$ret =& $this->execute($sth, $params);
$this->freePrepared($sth, false);
return $ret;
} else {
$this->last_parameters = array();
$result = $this->simpleQuery($query);
if ($result === DB_OK || DB::isError($result)) {
return $result;
} else {
$tmp =& new DB_result($this, $result);
return $tmp;
}
}
}
 
// }}}
// {{{ limitQuery()
 
/**
* Generates and executes a LIMIT query
*
* @param string $query the query
* @param intr $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return mixed a new DB_result object for successful SELECT queries
* or DB_OK for successul data manipulation queries.
* A DB_Error object on failure.
*/
function &limitQuery($query, $from, $count, $params = array())
{
$query = $this->modifyLimitQuery($query, $from, $count, $params);
if (DB::isError($query)){
return $query;
}
$result =& $this->query($query, $params);
if (is_a($result, 'DB_result')) {
$result->setOption('limit_from', $from);
$result->setOption('limit_count', $count);
}
return $result;
}
 
// }}}
// {{{ getOne()
 
/**
* Fetches the first column of the first row from a query result
*
* Takes care of doing the query and freeing the results when finished.
*
* @param string $query the SQL query
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return mixed the returned value of the query.
* A DB_Error object on failure.
*/
function &getOne($query, $params = array())
{
$params = (array)$params;
// modifyLimitQuery() would be nice here, but it causes BC issues
if (sizeof($params) > 0) {
$sth = $this->prepare($query);
if (DB::isError($sth)) {
return $sth;
}
$res =& $this->execute($sth, $params);
$this->freePrepared($sth);
} else {
$res =& $this->query($query);
}
 
if (DB::isError($res)) {
return $res;
}
 
$err = $res->fetchInto($row, DB_FETCHMODE_ORDERED);
$res->free();
 
if ($err !== DB_OK) {
return $err;
}
 
return $row[0];
}
 
// }}}
// {{{ getRow()
 
/**
* Fetches the first row of data returned from a query result
*
* Takes care of doing the query and freeing the results when finished.
*
* @param string $query the SQL query
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
* @param int $fetchmode the fetch mode to use
*
* @return array the first row of results as an array.
* A DB_Error object on failure.
*/
function &getRow($query, $params = array(),
$fetchmode = DB_FETCHMODE_DEFAULT)
{
// compat check, the params and fetchmode parameters used to
// have the opposite order
if (!is_array($params)) {
if (is_array($fetchmode)) {
if ($params === null) {
$tmp = DB_FETCHMODE_DEFAULT;
} else {
$tmp = $params;
}
$params = $fetchmode;
$fetchmode = $tmp;
} elseif ($params !== null) {
$fetchmode = $params;
$params = array();
}
}
// modifyLimitQuery() would be nice here, but it causes BC issues
if (sizeof($params) > 0) {
$sth = $this->prepare($query);
if (DB::isError($sth)) {
return $sth;
}
$res =& $this->execute($sth, $params);
$this->freePrepared($sth);
} else {
$res =& $this->query($query);
}
 
if (DB::isError($res)) {
return $res;
}
 
$err = $res->fetchInto($row, $fetchmode);
 
$res->free();
 
if ($err !== DB_OK) {
return $err;
}
 
return $row;
}
 
// }}}
// {{{ getCol()
 
/**
* Fetches a single column from a query result and returns it as an
* indexed array
*
* @param string $query the SQL query
* @param mixed $col which column to return (integer [column number,
* starting at 0] or string [column name])
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return array the results as an array. A DB_Error object on failure.
*
* @see DB_common::query()
*/
function &getCol($query, $col = 0, $params = array())
{
$params = (array)$params;
if (sizeof($params) > 0) {
$sth = $this->prepare($query);
 
if (DB::isError($sth)) {
return $sth;
}
 
$res =& $this->execute($sth, $params);
$this->freePrepared($sth);
} else {
$res =& $this->query($query);
}
 
if (DB::isError($res)) {
return $res;
}
 
$fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC;
 
if (!is_array($row = $res->fetchRow($fetchmode))) {
$ret = array();
} else {
if (!array_key_exists($col, $row)) {
$ret =& $this->raiseError(DB_ERROR_NOSUCHFIELD);
} else {
$ret = array($row[$col]);
while (is_array($row = $res->fetchRow($fetchmode))) {
$ret[] = $row[$col];
}
}
}
 
$res->free();
 
if (DB::isError($row)) {
$ret = $row;
}
 
return $ret;
}
 
// }}}
// {{{ getAssoc()
 
/**
* Fetches an entire query result and returns it as an
* associative array using the first column as the key
*
* If the result set contains more than two columns, the value
* will be an array of the values from column 2-n. If the result
* set contains only two columns, the returned value will be a
* scalar with the value of the second column (unless forced to an
* array with the $force_array parameter). A DB error code is
* returned on errors. If the result set contains fewer than two
* columns, a DB_ERROR_TRUNCATED error is returned.
*
* For example, if the table "mytable" contains:
*
* <pre>
* ID TEXT DATE
* --------------------------------
* 1 'one' 944679408
* 2 'two' 944679408
* 3 'three' 944679408
* </pre>
*
* Then the call getAssoc('SELECT id,text FROM mytable') returns:
* <pre>
* array(
* '1' => 'one',
* '2' => 'two',
* '3' => 'three',
* )
* </pre>
*
* ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
* <pre>
* array(
* '1' => array('one', '944679408'),
* '2' => array('two', '944679408'),
* '3' => array('three', '944679408')
* )
* </pre>
*
* If the more than one row occurs with the same value in the
* first column, the last row overwrites all previous ones by
* default. Use the $group parameter if you don't want to
* overwrite like this. Example:
*
* <pre>
* getAssoc('SELECT category,id,name FROM mytable', false, null,
* DB_FETCHMODE_ASSOC, true) returns:
*
* array(
* '1' => array(array('id' => '4', 'name' => 'number four'),
* array('id' => '6', 'name' => 'number six')
* ),
* '9' => array(array('id' => '4', 'name' => 'number four'),
* array('id' => '6', 'name' => 'number six')
* )
* )
* </pre>
*
* Keep in mind that database functions in PHP usually return string
* values for results regardless of the database's internal type.
*
* @param string $query the SQL query
* @param bool $force_array used only when the query returns
* exactly two columns. If true, the values
* of the returned array will be one-element
* arrays instead of scalars.
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of
* items passed must match quantity of
* placeholders in query: meaning 1
* placeholder for non-array parameters or
* 1 placeholder per array element.
* @param int $fetchmode the fetch mode to use
* @param bool $group if true, the values of the returned array
* is wrapped in another array. If the same
* key value (in the first column) repeats
* itself, the values will be appended to
* this array instead of overwriting the
* existing values.
*
* @return array the associative array containing the query results.
* A DB_Error object on failure.
*/
function &getAssoc($query, $force_array = false, $params = array(),
$fetchmode = DB_FETCHMODE_DEFAULT, $group = false)
{
$params = (array)$params;
if (sizeof($params) > 0) {
$sth = $this->prepare($query);
 
if (DB::isError($sth)) {
return $sth;
}
 
$res =& $this->execute($sth, $params);
$this->freePrepared($sth);
} else {
$res =& $this->query($query);
}
 
if (DB::isError($res)) {
return $res;
}
if ($fetchmode == DB_FETCHMODE_DEFAULT) {
$fetchmode = $this->fetchmode;
}
$cols = $res->numCols();
 
if ($cols < 2) {
$tmp =& $this->raiseError(DB_ERROR_TRUNCATED);
return $tmp;
}
 
$results = array();
 
if ($cols > 2 || $force_array) {
// return array values
// XXX this part can be optimized
if ($fetchmode == DB_FETCHMODE_ASSOC) {
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) {
reset($row);
$key = current($row);
unset($row[key($row)]);
if ($group) {
$results[$key][] = $row;
} else {
$results[$key] = $row;
}
}
} elseif ($fetchmode == DB_FETCHMODE_OBJECT) {
while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) {
$arr = get_object_vars($row);
$key = current($arr);
if ($group) {
$results[$key][] = $row;
} else {
$results[$key] = $row;
}
}
} else {
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
// we shift away the first element to get
// indices running from 0 again
$key = array_shift($row);
if ($group) {
$results[$key][] = $row;
} else {
$results[$key] = $row;
}
}
}
if (DB::isError($row)) {
$results = $row;
}
} else {
// return scalar values
while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
if ($group) {
$results[$row[0]][] = $row[1];
} else {
$results[$row[0]] = $row[1];
}
}
if (DB::isError($row)) {
$results = $row;
}
}
 
$res->free();
 
return $results;
}
 
// }}}
// {{{ getAll()
 
/**
* Fetches all of the rows from a query result
*
* @param string $query the SQL query
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of
* items passed must match quantity of
* placeholders in query: meaning 1
* placeholder for non-array parameters or
* 1 placeholder per array element.
* @param int $fetchmode the fetch mode to use:
* + DB_FETCHMODE_ORDERED
* + DB_FETCHMODE_ASSOC
* + DB_FETCHMODE_ORDERED | DB_FETCHMODE_FLIPPED
* + DB_FETCHMODE_ASSOC | DB_FETCHMODE_FLIPPED
*
* @return array the nested array. A DB_Error object on failure.
*/
function &getAll($query, $params = array(),
$fetchmode = DB_FETCHMODE_DEFAULT)
{
// compat check, the params and fetchmode parameters used to
// have the opposite order
if (!is_array($params)) {
if (is_array($fetchmode)) {
if ($params === null) {
$tmp = DB_FETCHMODE_DEFAULT;
} else {
$tmp = $params;
}
$params = $fetchmode;
$fetchmode = $tmp;
} elseif ($params !== null) {
$fetchmode = $params;
$params = array();
}
}
 
if (sizeof($params) > 0) {
$sth = $this->prepare($query);
 
if (DB::isError($sth)) {
return $sth;
}
 
$res =& $this->execute($sth, $params);
$this->freePrepared($sth);
} else {
$res =& $this->query($query);
}
 
if ($res === DB_OK || DB::isError($res)) {
return $res;
}
 
$results = array();
while (DB_OK === $res->fetchInto($row, $fetchmode)) {
if ($fetchmode & DB_FETCHMODE_FLIPPED) {
foreach ($row as $key => $val) {
$results[$key][] = $val;
}
} else {
$results[] = $row;
}
}
 
$res->free();
 
if (DB::isError($row)) {
$tmp =& $this->raiseError($row);
return $tmp;
}
return $results;
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff = false)
{
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ numRows()
 
/**
* Determines the number of rows in a query result
*
* @param resource $result the query result idenifier produced by PHP
*
* @return int the number of rows. A DB_Error object on failure.
*/
function numRows($result)
{
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ getSequenceName()
 
/**
* Generates the name used inside the database for a sequence
*
* The createSequence() docblock contains notes about storing sequence
* names.
*
* @param string $sqn the sequence's public name
*
* @return string the sequence's name in the backend
*
* @access protected
* @see DB_common::createSequence(), DB_common::dropSequence(),
* DB_common::nextID(), DB_common::setOption()
*/
function getSequenceName($sqn)
{
return sprintf($this->getOption('seqname_format'),
preg_replace('/[^a-z0-9_.]/i', '_', $sqn));
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::dropSequence(),
* DB_common::getSequenceName()
*/
function nextId($seq_name, $ondemand = true)
{
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ createSequence()
 
/**
* Creates a new sequence
*
* The name of a given sequence is determined by passing the string
* provided in the <var>$seq_name</var> argument through PHP's sprintf()
* function using the value from the <var>seqname_format</var> option as
* the sprintf()'s format argument.
*
* <var>seqname_format</var> is set via setOption().
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_common::nextID()
*/
function createSequence($seq_name)
{
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_common::nextID()
*/
function dropSequence($seq_name)
{
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ raiseError()
 
/**
* Communicates an error and invoke error callbacks, etc
*
* Basically a wrapper for PEAR::raiseError without the message string.
*
* @param mixed integer error code, or a PEAR error object (all
* other parameters are ignored if this parameter is
* an object
* @param int error mode, see PEAR_Error docs
* @param mixed if error mode is PEAR_ERROR_TRIGGER, this is the
* error level (E_USER_NOTICE etc). If error mode is
* PEAR_ERROR_CALLBACK, this is the callback function,
* either as a function name, or as an array of an
* object and method name. For other error modes this
* parameter is ignored.
* @param string extra debug information. Defaults to the last
* query and native error code.
* @param mixed native error code, integer or string depending the
* backend
*
* @return object the PEAR_Error object
*
* @see PEAR_Error
*/
function &raiseError($code = DB_ERROR, $mode = null, $options = null,
$userinfo = null, $nativecode = null)
{
// The error is yet a DB error object
if (is_object($code)) {
// because we the static PEAR::raiseError, our global
// handler should be used if it is set
if ($mode === null && !empty($this->_default_error_mode)) {
$mode = $this->_default_error_mode;
$options = $this->_default_error_options;
}
$tmp = PEAR::raiseError($code, null, $mode, $options,
null, null, true);
return $tmp;
}
 
if ($userinfo === null) {
$userinfo = $this->last_query;
}
 
if ($nativecode) {
$userinfo .= ' [nativecode=' . trim($nativecode) . ']';
} else {
$userinfo .= ' [DB Error: ' . DB::errorMessage($code) . ']';
}
 
$tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo,
'DB_Error', true);
return $tmp;
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error code produced by the last query
*
* @return mixed the DBMS' error code. A DB_Error object on failure.
*/
function errorNative()
{
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ errorCode()
 
/**
* Maps native error codes to DB's portable ones
*
* Uses the <var>$errorcode_map</var> property defined in each driver.
*
* @param string|int $nativecode the error code returned by the DBMS
*
* @return int the portable DB error code. Return DB_ERROR if the
* current driver doesn't have a mapping for the
* $nativecode submitted.
*/
function errorCode($nativecode)
{
if (isset($this->errorcode_map[$nativecode])) {
return $this->errorcode_map[$nativecode];
}
// Fall back to DB_ERROR if there was no mapping.
return DB_ERROR;
}
 
// }}}
// {{{ errorMessage()
 
/**
* Maps a DB error code to a textual message
*
* @param integer $dbcode the DB error code
*
* @return string the error message corresponding to the error code
* submitted. FALSE if the error code is unknown.
*
* @see DB::errorMessage()
*/
function errorMessage($dbcode)
{
return DB::errorMessage($this->errorcode_map[$dbcode]);
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* The format of the resulting array depends on which <var>$mode</var>
* you select. The sample output below is based on this query:
* <pre>
* SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
* FROM tblFoo
* JOIN tblBar ON tblFoo.fldId = tblBar.fldId
* </pre>
*
* <ul>
* <li>
*
* <kbd>null</kbd> (default)
* <pre>
* [0] => Array (
* [table] => tblFoo
* [name] => fldId
* [type] => int
* [len] => 11
* [flags] => primary_key not_null
* )
* [1] => Array (
* [table] => tblFoo
* [name] => fldPhone
* [type] => string
* [len] => 20
* [flags] =>
* )
* [2] => Array (
* [table] => tblBar
* [name] => fldId
* [type] => int
* [len] => 11
* [flags] => primary_key not_null
* )
* </pre>
*
* </li><li>
*
* <kbd>DB_TABLEINFO_ORDER</kbd>
*
* <p>In addition to the information found in the default output,
* a notation of the number of columns is provided by the
* <samp>num_fields</samp> element while the <samp>order</samp>
* element provides an array with the column names as the keys and
* their location index number (corresponding to the keys in the
* the default output) as the values.</p>
*
* <p>If a result set has identical field names, the last one is
* used.</p>
*
* <pre>
* [num_fields] => 3
* [order] => Array (
* [fldId] => 2
* [fldTrans] => 1
* )
* </pre>
*
* </li><li>
*
* <kbd>DB_TABLEINFO_ORDERTABLE</kbd>
*
* <p>Similar to <kbd>DB_TABLEINFO_ORDER</kbd> but adds more
* dimensions to the array in which the table names are keys and
* the field names are sub-keys. This is helpful for queries that
* join tables which have identical field names.</p>
*
* <pre>
* [num_fields] => 3
* [ordertable] => Array (
* [tblFoo] => Array (
* [fldId] => 0
* [fldPhone] => 1
* )
* [tblBar] => Array (
* [fldId] => 2
* )
* )
* </pre>
*
* </li>
* </ul>
*
* The <samp>flags</samp> element contains a space separated list
* of extra information about the field. This data is inconsistent
* between DBMS's due to the way each DBMS works.
* + <samp>primary_key</samp>
* + <samp>unique_key</samp>
* + <samp>multiple_key</samp>
* + <samp>not_null</samp>
*
* Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
* elements if <var>$result</var> is a table name. The following DBMS's
* provide full information from queries:
* + fbsql
* + mysql
*
* If the 'portability' option has <samp>DB_PORTABILITY_LOWERCASE</samp>
* turned on, the names of tables and fields will be lowercased.
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode either unused or one of the tableInfo modes:
* <kbd>DB_TABLEINFO_ORDERTABLE</kbd>,
* <kbd>DB_TABLEINFO_ORDER</kbd> or
* <kbd>DB_TABLEINFO_FULL</kbd> (which does both).
* These are bitwise, so the first two can be
* combined using <kbd>|</kbd>.
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::setOption()
*/
function tableInfo($result, $mode = null)
{
/*
* If the DB_<driver> class has a tableInfo() method, that one
* overrides this one. But, if the driver doesn't have one,
* this method runs and tells users about that fact.
*/
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ getTables()
 
/**
* Lists the tables in the current database
*
* @return array the list of tables. A DB_Error object on failure.
*
* @deprecated Method deprecated some time before Release 1.2
*/
function getTables()
{
return $this->getListOf('tables');
}
 
// }}}
// {{{ getListOf()
 
/**
* Lists internal database information
*
* @param string $type type of information being sought.
* Common items being sought are:
* tables, databases, users, views, functions
* Each DBMS's has its own capabilities.
*
* @return array an array listing the items sought.
* A DB DB_Error object on failure.
*/
function getListOf($type)
{
$sql = $this->getSpecialQuery($type);
if ($sql === null) {
$this->last_query = '';
return $this->raiseError(DB_ERROR_UNSUPPORTED);
} elseif (is_int($sql) || DB::isError($sql)) {
// Previous error
return $this->raiseError($sql);
} elseif (is_array($sql)) {
// Already the result
return $sql;
}
// Launch this query
return $this->getCol($sql);
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
return $this->raiseError(DB_ERROR_UNSUPPORTED);
}
 
// }}}
// {{{ _rtrimArrayValues()
 
/**
* Right-trims all strings in an array
*
* @param array $array the array to be trimmed (passed by reference)
*
* @return void
*
* @access protected
*/
function _rtrimArrayValues(&$array)
{
foreach ($array as $key => $value) {
if (is_string($value)) {
$array[$key] = rtrim($value);
}
}
}
 
// }}}
// {{{ _convertNullArrayValuesToEmpty()
 
/**
* Converts all null values in an array to empty strings
*
* @param array $array the array to be de-nullified (passed by reference)
*
* @return void
*
* @access protected
*/
function _convertNullArrayValuesToEmpty(&$array)
{
foreach ($array as $key => $value) {
if (is_null($value)) {
$array[$key] = '';
}
}
}
 
// }}}
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/NestedSet.php
New file
0,0 → 1,2747
<?php
//
// +----------------------------------------------------------------------+
// | PEAR :: DB_NestedSet |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |f
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Daniel Khan <dk@webcluster.at> |
// | Jason Rust <jason@rustyparts.com> |
// +----------------------------------------------------------------------+
// $Id: NestedSet.php,v 1.56 2003/10/07 00:11:26 datenpunk Exp $
//
 
// CREDITS:
// --------
// - Thanks to Kristian Koehntopp for publishing an explanation of the Nested Set
// technique and for the great work he did and does for the php community
// - Thanks to Daniel T. Gorski for his great tutorial on www.develnet.org
//
// - Thanks to my parents for ... just kidding :]
 
require_once 'PEAR.php';
 
// {{{ constants
 
// Error and message codes
define('NESE_ERROR_RECURSION', 'E100');
define('NESE_ERROR_NODRIVER', 'E200');
define('NESE_ERROR_NOHANDLER', 'E300');
define('NESE_ERROR_TBLOCKED', 'E010');
define('NESE_MESSAGE_UNKNOWN', 'E0');
define('NESE_ERROR_NOTSUPPORTED', 'E1');
define('NESE_ERROR_PARAM_MISSING','E400');
define('NESE_ERROR_NOT_FOUND', 'E500');
define('NESE_ERROR_WRONG_MPARAM', 'E2');
 
// for moving a node before another
define('NESE_MOVE_BEFORE', 'BE');
// for moving a node after another
define('NESE_MOVE_AFTER', 'AF');
// for moving a node below another
define('NESE_MOVE_BELOW', 'SUB');
 
 
// Sortorders
define('NESE_SORT_LEVEL', 'SLV');
define('NESE_SORT_PREORDER', 'SPO');
 
// }}}
// {{{ DB_NestedSet:: class
/**
* DB_NestedSet is a class for handling nested sets
*
* @author Daniel Khan <dk@webcluster.at>
* @package DB_NestedSet
* @version $Revision: 1.56 $
* @access public
*/
 
// }}}
class DB_NestedSet {
// {{{ properties
 
/**
* @var array The field parameters of the table with the nested set. Format: 'realFieldName' => 'fieldId'
* @access public
*/
var $params = array(
'STRID' => 'id',
'ROOTID'=> 'rootid',
'l' => 'l',
'r' => 'r',
'STREH' => 'norder',
'LEVEL' => 'level',
// 'parent'=>'parent', // Optional but very useful
'STRNA' => 'name'
);
 
// To be used with 2.0 - would be an api break atm
// var $quotedParams = array('name');
 
/**
* @var string The table with the actual tree data
* @access public
*/
var $node_table = 'tb_nodes';
 
/**
* @var string The table to handle locking
* @access public
*/
var $lock_table = 'tb_locks';
 
/**
* @var string The table used for sequences
* @access public
*/
var $sequence_table;
 
/**
* Secondary order field. Normally this is the order field, but can be changed to
* something else (i.e. the name field so that the tree can be shown alphabetically)
*
* @var string
* @access public
*/
var $secondarySort;
 
/**
* Used to store the secondary sort method set by the user while doing manipulative queries
*
* @var string
* @access private
*/
var $_userSecondarySort = false;
 
/**
* The default sorting field - will be set to the table column inside the constructor
*
* @var string
* @access private
*/
var $_defaultSecondarySort = 'norder';
 
/**
* @var int The time to live of the lock
* @access public
*/
var $lockTTL = 1;
 
/**
* @var bool Enable debugging statements?
* @access public
*/
var $debug = 0;
 
/**
* @var bool Lock the structure of the table?
* @access private
*/
var $_structureTableLock = false;
 
 
/**
* @var bool Don't allow unlocking (used inside of moves)
* @access private
*/
var $_lockExclusive = false;
 
/**
* @var object cache Optional PEAR::Cache object
* @access public
*/
var $cache = false;
 
/**
* Specify the sortMode of the query methods
* NESE_SORT_LEVEL is the 'old' sorting method and sorts a tree by level
* all nodes of level 1, all nodes of level 2,...
* NESE_SORT_PREORDER will sort doing a preorder walk.
* So all children of node x will come right after it
* Note that moving a node within it's siblings will obviously not change the output
* in this mode
*
* @var constant Order method (NESE_SORT_LEVEL|NESE_SORT_PREORDER)
* @access private
*/
var $_sortMode = NESE_SORT_LEVEL;
 
/**
* @var array Available sortModes
* @access private
*/
var $_sortModes = array(NESE_SORT_LEVEL, NESE_SORT_PREORDER);
 
/**
* @var array An array of field ids that must exist in the table
* @access private
*/
var $_requiredParams = array('id', 'rootid', 'l', 'r', 'norder', 'level');
 
/**
* @var bool Skip the callback events?
* @access private
*/
var $_skipCallbacks = false;
 
/**
* @var bool Do we want to use caching
* @access private
*/
var $_caching = false;
 
/**
* @var array The above parameters flipped for easy access
* @access private
*/
var $_flparams = array();
 
/**
*
* @var bool Temporary switch for cache
* @access private
*/
var $_restcache = false;
 
/**
* Used to determine the presence of listeners for an event in triggerEvent()
*
* If any event listeners are registered for an event, the event name will
* have a key set in this array, otherwise, it will not be set.
* @see triggerEvent()
* @var arrayg
* @access private
*/
var $_hasListeners = array();
 
 
/**
* @var string packagename
* @access private
*/
var $_packagename = 'DB_NestedSet';
 
/**
* @var int Majorversion
* @access private
*/
var $_majorversion = 1;
 
/**
* @var string Minorversion
* @access private
*/
var $_minorversion = '3';
 
/**
* @var array Used for mapping a cloned tree to the real tree for move_* operations
* @access private
*/
var $_relations = array();
 
/**
* Used for _internal_ tree conversion
* @var bool Turn off user param verification and id generation
* @access private
*/
var $_dumbmode = false;
 
/**
* @var array Map of error messages to their descriptions
*/
var $messages = array(
NESE_ERROR_RECURSION => '%s: This operation would lead to a recursion',
NESE_ERROR_TBLOCKED => 'The structure Table is locked for another database operation, please retry.',
NESE_ERROR_NODRIVER => 'The selected database driver %s wasn\'t found',
NESE_ERROR_NOTSUPPORTED => 'Method not supported yet',
NESE_ERROR_NOHANDLER => 'Event handler not found',
NESE_ERROR_PARAM_MISSING=> 'Parameter missing',
NESE_MESSAGE_UNKNOWN => 'Unknown error or message',
NESE_ERROR_NOT_FOUND => '%s: Node %s not found',
NESE_ERROR_WRONG_MPARAM => '%s: %s'
);
 
/**
* @var array The array of event listeners
* @access private
*/
var $eventListeners = array();
 
 
// }}}
// +---------------------------------------+
// | Base methods |
// +---------------------------------------+
// {{{ constructor
 
/**
* Constructor
*
* @param array $params Database column fields which should be returned
*
* @access private
* @return void
*/
function DB_NestedSet($params) {
 
if ($this->debug) {
$this->_debugMessage('DB_NestedSet()');
}
if (is_array($params) && count($params) > 0) {
$this->params = $params;
}
 
$this->_flparams = array_flip($this->params);
$this->sequence_table = $this->node_table . '_' . $this->_flparams['id'];
$this->secondarySort = $this->_flparams[$this->_defaultSecondarySort];
register_shutdown_function(array(&$this,'_DB_NestedSet'));
}
 
// }}}
// {{{ destructor
 
/**
* PEAR Destructor
* Releases all locks
* Closes open database connections
*
* @access private
* @return void
*/
function _DB_NestedSet() {
if ($this->debug) {
$this->_debugMessage('_DB_NestedSet()');
}
$this->_releaseLock(true);
}
 
// }}}
// {{{ factory
 
/**
* Handles the returning of a concrete instance of DB_NestedSet based on the driver.
* If the class given by $driver allready exists it will be used.
* If not the driver will be searched inside the default path ./NestedSet/
*
* @param string $driver The driver, such as DB or MDB
* @param string $dsn The dsn for connecting to the database
* @param array $params The field name params for the node table
*
* @static
* @access public
* @return object The DB_NestedSet object
*/
function & factory($driver, $dsn, $params = array()) {
 
$classname = 'DB_NestedSet_' . $driver;
if (!class_exists($classname)) {
$driverpath = dirname(__FILE__).'/NestedSet/'.$driver.'.php';
if(!file_exists($driverpath) || !$driver) {
return PEAR::raiseError("factory(): The database driver '$driver' wasn't found", NESE_ERROR_NODRIVER, PEAR_ERROR_TRIGGER, E_USER_ERROR);
}
include_once($driverpath);
}
return new $classname($dsn, $params);
}
 
// }}}
 
 
// }}}
// +----------------------------------------------+
// | NestedSet manipulation and query methods |
// |----------------------------------------------+
// | Querying the tree |
// +----------------------------------------------+
 
// {{{ getAllNodes()
 
/**
* Fetch the whole NestedSet
*
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @access public
* @return mixed False on error, or an array of nodes
*/
function getAllNodes($keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getAllNodes()');
}
 
if($this->_sortMode == NESE_SORT_LEVEL) {
$sql = sprintf('SELECT %s %s FROM %s %s %s ORDER BY %s.%s, %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$this->_flparams['level'],
$this->node_table,
$this->secondarySort);
} elseif ($this->_sortMode == NESE_SORT_PREORDER) {
$nodeSet = array();
$rootnodes = $this->getRootNodes(true);
foreach($rootnodes AS $rid=>$rootnode) {
$nodeSet = $nodeSet+$this->getBranch($rootnode, true);
}
return $nodeSet;
}
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
return $nodeSet;
}
 
// }}}
// {{{ getRootNodes()
 
/**
* Fetches the first level (the rootnodes) of the NestedSet
*
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function getRootNodes($keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getRootNodes()');
}
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s=%s.%s %s ORDER BY %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['id'],
$this->node_table,
$this->_flparams['rootid'],
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$this->secondarySort);
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
return $nodeSet;
}
 
// }}}
 
// {{{ getBranch()
 
/**
* Fetch the whole branch where a given node id is in
*
* @param int $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function getBranch($id, $keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getBranch($id)');
}
if (!($thisnode = $this->pickNode($id, true))) {
$epr = array('getBranch()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_NOTICE, $epr);
}
if($this->_sortMode == NESE_SORT_LEVEL) {
$firstsort = $this->_flparams['level'];
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s=%s %s ORDER BY %s.%s, %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$firstsort,
$this->node_table,
$this->secondarySort);
} elseif($this->_sortMode == NESE_SORT_PREORDER) {
$firstsort = $this->_flparams['l'];
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s=%s %s ORDER BY %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$firstsort);
}
 
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
if($this->_sortMode == NESE_SORT_PREORDER && ($this->params[$this->secondarySort] != $this->_defaultSecondarySort)) {
uasort($nodeSet, array($this, '_secSort'));
}
return $nodeSet;
}
 
// }}}
// {{{ getParents()
 
/**
* Fetch the parents of a node given by id
*
* @param int $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function getParents($id, $keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getParents($id)');
}
if (!($child = $this->pickNode($id, true))) {
$epr = array('getParents()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_NOTICE, $epr);
}
 
$sql = sprintf('SELECT %s %s FROM %s %s
WHERE %s.%s=%s AND %s.%s<%s AND %s.%s<%s AND %s.%s>%s %s
ORDER BY %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['rootid'],
$child['rootid'],
$this->node_table,
$this->_flparams['level'],
$child['level'],
$this->node_table,
$this->_flparams['l'],
$child['l'],
$this->node_table,
$this->_flparams['r'],
$child['r'],
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$this->_flparams['level']);
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
return $nodeSet;
}
 
// }}}
// {{{ getParent()
 
/**
* Fetch the immediate parent of a node given by id
*
* @param int $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or the parent node
*/
function getParent($id, $keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getParent($id)');
}
if (!($child = $this->pickNode($id, true))) {
$epr = array('getParent()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_NOTICE, $epr);
}
 
if($child['id'] == $child['rootid']) {
return false;
}
 
// If parent node is set inside the db simply return it
if(isset($child['parent']) && !empty($child['parent'])) {
return $this->pickNode($child['parent'], $keepAsArray, $aliasFields, 'id', $addSQL);
}
 
$addSQL['append'] = sprintf('AND %s.%s = %s',
$this->node_table,
$this->_flparams['level'],
$child['level']-1);
 
$nodeSet = $this->getParents($id, $keepAsArray, $aliasFields, $addSQL);
 
if(!empty($nodeSet)) {
$keys = array_keys($nodeSet);
return $nodeSet[$keys[0]];
} else {
return false;
}
}
 
// }}}
// {{{ getSiblings)
 
/**
* Fetch all siblings of the node given by id
* Important: The node given by ID will also be returned
* Do a unset($array[$id]) on the result if you don't want that
*
* @param int $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or the parent node
*/
function getSiblings($id, $keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getParents($id)');
}
 
if (!($sibling = $this->pickNode($id, true))) {
$epr = array('getSibling()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_NOTICE, $epr);
}
 
$parent = $this->getParent($sibling, true);
 
return $this->getChildren($parent, $keepAsArray, $aliasFields, $addSQL);
}
 
// }}}
// {{{ getChildren()
 
/**
* Fetch the children _one level_ after of a node given by id
*
* @param int $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param bool $forceNorder (optional) Force the result to be ordered by the norder
* param (as opposed to the value of secondary sort). Used by the move and
* add methods.
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function getChildren($id, $keepAsArray = false, $aliasFields = true, $forceNorder = false, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getChildren($id)');
}
 
if (!($parent = $this->pickNode($id, true))) {
$epr = array('getChildren()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_NOTICE, $epr);
}
if (!$parent || $parent['l'] == ($parent['r'] - 1)) {
return false;
}
 
$sql = sprintf('SELECT %s %s FROM %s %s
WHERE %s.%s=%s AND %s.%s=%s+1 AND %s.%s BETWEEN %s AND %s %s
ORDER BY %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['rootid'],
$parent['rootid'],
$this->node_table,
$this->_flparams['level'],
$parent['level'],
$this->node_table,
$this->_flparams['l'],
$parent['l'],
$parent['r'],
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$this->secondarySort);
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
return $nodeSet;
}
 
// }}}
// {{{ getSubBranch()
 
/**
* Fetch all the children of a node given by id
*
* getChildren only queries the immediate children
* getSubBranch returns all nodes below the given node
*
* @param string $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function getSubBranch($id, $keepAsArray = false, $aliasFields = true, $addSQL = array()) {
 
if ($this->debug) {
$this->_debugMessage('getSubBranch($id)');
}
if (!($parent = $this->pickNode($id, true))) {
$epr = array('getSubBranch()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, E_USER_NOTICE, $epr);
}
if($this->_sortMode == NESE_SORT_LEVEL) {
$firstsort = $this->_flparams['level'];
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s BETWEEN %s AND %s AND %s.%s=%s AND %s.%s!=%s %s ORDER BY %s.%s, %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['l'],
$parent['l'],
$parent['r'],
$this->node_table,
$this->_flparams['rootid'],
$parent['rootid'],
$this->node_table,
$this->_flparams['id'],
$this->_addSQL($addSQL, 'append'),
$id,
$this->node_table,
$firstsort,
$this->node_table,
$this->secondarySort
);
} elseif($this->_sortMode == NESE_SORT_PREORDER) {
$firstsort = $this->_flparams['l'];
$firstsort = $this->_flparams['level'];
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s BETWEEN %s AND %s AND %s.%s=%s AND %s.%s!=%s %s ORDER BY %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['l'],
$parent['l'],
$parent['r'],
$this->node_table,
$this->_flparams['rootid'],
$parent['rootid'],
$this->node_table,
$this->_flparams['id'],
$this->_addSQL($addSQL, 'append'),
$id,
$this->node_table,
$firstsort
);
}
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
if($this->params[$this->secondarySort] != $this->_defaultSecondarySort) {
uasort($nodeSet, array($this, '_secSort'));
}
return $nodeSet;
}
 
// }}}
// {{{ pickNode()
 
/**
* Fetch the data of a node with the given id
*
* @param int $id The node id of the node to fetch
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param string $idfield (optional) Which field has to be compared with $id?
* This is can be used to pick a node by other values (e.g. it's name).
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function pickNode($id, $keepAsArray = false, $aliasFields = true, $idfield = 'id', $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('pickNode($id)');
}
 
if (is_object($id) && $id->id) {
return $id;
} elseif (is_array($id) && isset($id['id'])) {
return $id;
}
 
if(!$id) {
return false;
}
 
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s=%s %s',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams[$idfield],
$id,
$this->_addSQL($addSQL, 'append'));
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
$nsKey = false;
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
$nsKey = $key;
}
} else {
foreach (array_keys($nodeSet) as $key) {
$nsKey = $key;
}
}
 
if (is_array($nodeSet) && $idfield != 'id') {
$id = $nsKey;
}
 
return isset($nodeSet[$id]) ? $nodeSet[$id] : false;
}
 
// }}}
// {{{ isParent()
 
/**
* See if a given node is a parent of another given node
*
* A node is considered to be a parent if it resides above the child
* So it doesn't mean that the node has to be an immediate parent.
* To get this information simply compare the levels of the two nodes
* after you know that you have a parent relation.
*
* @param mixed $parent The parent node as array or object
* @param mixed $child The child node as array or object
*
* @access public
* @return bool True if it's a parent
*/
function isParent($parent, $child) {
 
if ($this->debug) {
$this->_debugMessage('isParent($parent, $child)');
}
 
if (!isset($parent)|| !isset($child)) {
return false;
}
 
if (is_array($parent)) {
$p_rootid = $parent['rootid'];
$p_l = $parent['l'];
$p_r = $parent['r'];
 
} elseif (is_object($parent)) {
$p_rootid = $parent->rootid;
$p_l = $parent->l;
$p_r = $parent->r;
}
 
if (is_array($child)) {
$c_rootid = $child['rootid'];
$c_l = $child['l'];
$c_r = $child['r'];
} elseif (is_object($child)) {
$c_rootid = $child->rootid;
$c_l = $child->l;
$c_r = $child->r;
}
 
if (($p_rootid == $c_rootid) && ($p_l < $c_l && $p_r > $c_r)) {
return true;
}
 
return false;
}
 
 
// }}}
// +----------------------------------------------+
// | NestedSet manipulation and query methods |
// |----------------------------------------------+
// | insert / delete / update of nodes |
// +----------------------------------------------+
// | [PUBLIC] |
// +----------------------------------------------+
// {{{ createRootNode()
 
/**
* Creates a new root node
* Optionally it deletes the whole tree and creates one initial rootnode
*
* <pre>
* +-- root1 [target]
* |
* +-- root2 [new]
* |
* +-- root3
* </pre>
*
* @param array $values Hash with param => value pairs of the node (see $this->params)
* @param integer $id ID of target node (the rootnode after which the node should be inserted)
* @param bool $first Danger: Deletes and (re)init's the hole tree - sequences are reset
*
* @access public
* @return mixed The node id or false on error
*/
function createRootNode($values, $id = false, $first = false, $_pos = 'AF') {
 
if ($this->debug) {
$this->_debugMessage('createRootNode($values, $id = false, $first = false, $_pos = \'AF\')');
}
 
$this->_verifyUserValues('createRootNode()', $values);
 
if(!$first && (!$id || !$parent = $this->pickNode($id, true))) {
$epr = array('createRootNode()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
} elseif($first && $id) {
 
// No notice for now.
// But tehese 2 params don't make sense together
$epr = array(
'createRootNode()',
'[id] AND [first] were passed - that doesn\'t make sense');
//$this->_raiseError(NESE_ERROR_WRONG_MPARAM, E_USER_WARNING, $epr);
}
 
// Try to aquire a table lock
if(PEAR::isError($lock=$this->_setLock())) {
return $lock;
}
 
$sql = array();
$addval = array();
$addval[$this->_flparams['level']] = 1;
 
// Shall we delete the existing tree (reinit)
if ($first) {
$dsql = sprintf('DELETE FROM %s',
$this->node_table);
$this->db->query($dsql);
$this->db->dropSequence($this->sequence_table);
// New order of the new node will be 1
$addval[$this->_flparams['norder']] = 1;
} else {
// Let's open a gap for the new node
if($_pos == NESE_MOVE_AFTER) {
$addval[$this->_flparams['norder']] = $parent['norder'] + 1;
$sql[] = sprintf('UPDATE %s SET %s=%s+1 WHERE %s=%s AND %s > %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['id'],
$this->_flparams['rootid'],
$this->_flparams['norder'],
$parent['norder']);
} elseif($_pos == NESE_MOVE_BEFORE) {
$addval[$this->_flparams['norder']] = $parent['norder'];
$sql[] = sprintf('UPDATE %s SET %s=%s+1 WHERE %s=%s AND %s >= %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['id'],
$this->_flparams['rootid'],
$this->_flparams['norder'],
$parent['norder']);
}
}
 
if(isset($this->_flparams['parent'])) {
$addval[$this->_flparams['parent']] = 0;
}
// Sequence of node id (equals to root id in this case
 
if(!$this->_dumbmode || !$node_id=isset($values[$this->_flparams['id']]) || !isset($values[$this->_flparams['rootid']])) {
$addval[$this->_flparams['rootid']] = $node_id = $addval[$this->_flparams['id']] = $this->db->nextId($this->sequence_table);
} else {
$node_id = $values[$this->_flparams['id']];
}
// Left/Right values for rootnodes
$addval[$this->_flparams['l']] = 1;
$addval[$this->_flparams['r']] = 2;
// Transform the node data hash to a query
if (!$qr = $this->_values2Query($values, $addval)) {
$this->_releaseLock();
return false;
}
 
// Insert the new node
$sql[] = sprintf('INSERT INTO %s SET %s',
$this->node_table,
$qr);
 
for($i=0;$i<count($sql);$i++) {
$res = $this->db->query($sql[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
 
// EVENT (nodeCreate)
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeCreate'])) {
$this->triggerEvent('nodeCreate', $this->pickNode($node_id));
}
$this->_releaseLock();
return $node_id;
}
 
// }}}
// {{{ createSubNode()
 
/**
* Creates a subnode
*
* <pre>
* +-- root1
* |
* +-\ root2 [target]
* | |
* | |-- subnode1 [new]
* |
* +-- root3
* </pre>
*
* @param integer $id Parent node ID
* @param array $values Hash with param => value pairs of the node (see $this->params)
*
* @access public
* @return mixed The node id or false on error
*/
function createSubNode($id, $values) {
if ($this->debug) {
$this->_debugMessage('createSubNode($id, $values)');
}
 
// invalid parent id, bail out
if (!($thisnode = $this->pickNode($id, true))) {
$epr = array('createSubNode()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
// Try to aquire a table lock
if(PEAR::isError($lock = $this->_setLock())) {
return $lock;
}
 
$this->_verifyUserValues('createRootNode()', $values);
 
// Get the children of the target node
$children = $this->getChildren($id, true);
 
// We have children here
if ($thisnode['r']-1 != $thisnode['l']) {
// Get the last child
$last = array_pop($children);
// What we have to do is virtually an insert of a node after the last child
// So we don't have to proceed creating a subnode
$newNode = $this->createRightNode($last['id'], $values);
$this->_releaseLock();
return $newNode;
}
 
$sql = array();
$sql[] = sprintf('
UPDATE %s SET
%s=IF(%s>=%s, %s+2, %s),
%s=IF(%s>=%s, %s+2, %s)
WHERE %s=%s',
$this->node_table,
$this->_flparams['l'],
$this->_flparams['l'],
$thisnode['r'],
$this->_flparams['l'],
$this->_flparams['l'],
$this->_flparams['r'],
$this->_flparams['r'],
$thisnode['r'],
$this->_flparams['r'],
$this->_flparams['r'],
$this->_flparams['rootid'],
$thisnode['rootid']
);
 
$addval = array();
if(isset($this->_flparams['parent'])) {
$addval[$this->_flparams['parent']] = $thisnode['id'];
}
 
$addval[$this->_flparams['l']] = $thisnode['r'];
$addval[$this->_flparams['r']] = $thisnode['r'] + 1;
$addval[$this->_flparams['rootid']] = $thisnode['rootid'];
$addval[$this->_flparams['norder']] = 1;
$addval[$this->_flparams['level']] = $thisnode['level'] + 1;
 
if(!$this->_dumbmode || !$node_id=isset($values[$this->_flparams['id']])) {
$node_id = $addval[$this->_flparams['id']] = $this->db->nextId($this->sequence_table);
} else {
$node_id = $values[$this->_flparams['id']];
}
if (!$qr = $this->_values2Query($values, $addval)) {
$this->_releaseLock();
return false;
}
 
$sql[] = sprintf('INSERT INTO %s SET %s',
$this->node_table,
$qr);
for($i=0;$i<count($sql);$i++) {
$res = $this->db->query($sql[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
 
// EVENT (NodeCreate)
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeCreate'])) {
$thisnode = $this->pickNode($node_id);
$this->triggerEvent('nodeCreate', $this->pickNode($id));
}
$this->_releaseLock();
return $node_id;
}
 
// }}}
// {{{ createLeftNode()
/**
* Creates a node before a given node
* <pre>
* +-- root1
* |
* +-\ root2
* | |
* | |-- subnode2 [new]
* | |-- subnode1 [target]
* | |-- subnode3
* |
* +-- root3
* </pre>
*
* @param int $id Target node ID
* @param array $values Hash with param => value pairs of the node (see $this->params)
* @param bool $returnID Tell the method to return a node id instead of an object.
* ATTENTION: That the method defaults to return an object instead of the node id
* has been overseen and is basically a bug. We have to keep this to maintain BC.
* You will have to set $returnID to true to make it behave like the other creation methods.
* This flaw will get fixed with the next major version.
*
* @access public
* @return mixed The node id or false on error
*/
function createLeftNode($id, $values) {
 
if ($this->debug) {
$this->_debugMessage('createLeftNode($target, $values)');
}
 
$this->_verifyUserValues('createLeftode()', $values);
 
// invalid target node, bail out
if (!($thisnode = $this->pickNode($id, true))) {
$epr = array('createLeftNode()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
if(PEAR::isError($lock=$this->_setLock())) {
return $lock;
}
 
 
// If the target node is a rootnode we virtually want to create a new root node
if ($thisnode['rootid'] == $thisnode['id']) {
return $this->createRootNode($values, $id, false, NESE_MOVE_BEFORE);
}
 
 
$addval = array();
$parent = $this->getParent($id, true);
if(isset($this->_flparams['parent'])) {
$addval[$this->_flparams['parent']] = $parent['id'];
}
 
$sql = array();
 
 
$sql[] = sprintf('UPDATE %s SET %s=%s+1
WHERE
%s=%s AND %s>=%s AND %s=%s AND %s BETWEEN %s AND %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_flparams['norder'],
$thisnode['norder'],
$this->_flparams['level'],
$thisnode['level'],
$this->_flparams['l'],
$parent['l'],
$parent['r']);
 
 
// Update all nodes which have dependent left and right values
$sql[] = sprintf('
UPDATE %s SET
%s=IF(%s>=%s, %s+2, %s),
%s=IF(%s>=%s, %s+2, %s)
WHERE %s=%s',
$this->node_table,
$this->_flparams['l'],
$this->_flparams['l'],
$thisnode['l'],
$this->_flparams['l'],
$this->_flparams['l'],
$this->_flparams['r'],
$this->_flparams['r'],
$thisnode['r'],
$this->_flparams['r'],
$this->_flparams['r'],
$this->_flparams['rootid'],
$thisnode['rootid']
);
 
 
 
$addval[$this->_flparams['norder']] = $thisnode['norder'];
$addval[$this->_flparams['l']] = $thisnode['l'];
$addval[$this->_flparams['r']] = $thisnode['l']+1;
$addval[$this->_flparams['rootid']] = $thisnode['rootid'];
$addval[$this->_flparams['level']] = $thisnode['level'];
 
if(!$this->_dumbmode || !$node_id=isset($values[$this->_flparams['id']])) {
$node_id = $addval[$this->_flparams['id']] = $this->db->nextId($this->sequence_table);
} else {
$node_id = $values[$this->_flparams['id']];
}
if (!$qr = $this->_values2Query($values, $addval)) {
$this->_releaseLock();
return false;
}
 
// Insert the new node
$sql[] = sprintf('INSERT INTO %s SET %s',
$this->node_table,
$qr);
 
for($i=0;$i<count($sql);$i++) {
$res = $this->db->query($sql[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
 
// EVENT (NodeCreate)
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeCreate'])) {
$this->triggerEvent('nodeCreate', $this->pickNode($id));
}
$this->_releaseLock();
return $node_id;
}
 
/**
* Creates a node after a given node
* <pre>
* +-- root1
* |
* +-\ root2
* | |
* | |-- subnode1 [target]
* | |-- subnode2 [new]
* | |-- subnode3
* |
* +-- root3
* </pre>
*
* @param int $id Target node ID
* @param array $values Hash with param => value pairs of the node (see $this->params)
* @param bool $returnID Tell the method to return a node id instead of an object.
* ATTENTION: That the method defaults to return an object instead of the node id
* has been overseen and is basically a bug. We have to keep this to maintain BC.
* You will have to set $returnID to true to make it behave like the other creation methods.
* This flaw will get fixed with the next major version.
*
* @access public
* @return mixed The node id or false on error
*/
function createRightNode($id, $values) {
 
if ($this->debug) {
$this->_debugMessage('createRightNode($target, $values)');
}
 
$this->_verifyUserValues('createRootNode()', $values);
 
// invalid target node, bail out
if (!($thisnode = $this->pickNode($id, true))) {
$epr = array('createRightNode()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
if(PEAR::isError($lock=$this->_setLock())) {
return $lock;
}
 
 
// If the target node is a rootnode we virtually want to create a new root node
if ($thisnode['rootid'] == $thisnode['id']) {
 
$nid = $this->createRootNode($values, $id);
$this->_releaseLock();
return $nid;
}
 
 
$addval = array();
$parent = $this->getParent($id, true);
if(isset($this->_flparams['parent'])) {
$addval[$this->_flparams['parent']] = $parent['id'];
}
 
$sql = array();
 
$sql[] = sprintf('UPDATE %s SET %s=%s+1
WHERE
%s=%s AND %s>%s AND %s=%s AND %s BETWEEN %s AND %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_flparams['norder'],
$thisnode['norder'],
$this->_flparams['level'],
$thisnode['level'],
$this->_flparams['l'],
$parent['l'],
$parent['r']);
 
 
// Update all nodes which have dependent left and right values
 
 
$sql[] = sprintf('
UPDATE %s SET
%s=IF(%s>%s, %s+2, %s),
%s=IF(%s>%s, %s+2, %s)
WHERE %s=%s',
$this->node_table,
$this->_flparams['l'],
$this->_flparams['l'],
$thisnode['r'],
$this->_flparams['l'],
$this->_flparams['l'],
$this->_flparams['r'],
$this->_flparams['r'],
$thisnode['r'],
$this->_flparams['r'],
$this->_flparams['r'],
$this->_flparams['rootid'],
$thisnode['rootid']
);
 
$addval[$this->_flparams['norder']] = $thisnode['norder'] + 1;
$addval[$this->_flparams['l']] = $thisnode['r'] + 1;
$addval[$this->_flparams['r']] = $thisnode['r'] + 2;
$addval[$this->_flparams['rootid']] = $thisnode['rootid'];
$addval[$this->_flparams['level']] = $thisnode['level'];
 
if(!$this->_dumbmode || !isset($values[$this->_flparams['id']])) {
$node_id = $addval[$this->_flparams['id']] = $this->db->nextId($this->sequence_table);
} else {
$node_id = $values[$this->_flparams['id']];
}
if (!$qr = $this->_values2Query($values, $addval)) {
$this->_releaseLock();
return false;
}
 
// Insert the new node
$sql[] = sprintf('INSERT INTO %s SET %s', $this->node_table, $qr);
 
for($i=0;$i<count($sql);$i++) {
$res = $this->db->query($sql[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
 
// EVENT (NodeCreate)
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeCreate'])) {
$this->triggerEvent('nodeCreate', $this->pickNode($id));
}
$this->_releaseLock();
return $node_id;
}
 
// }}}
// {{{ deleteNode()
 
/**
* Deletes a node
*
* @param int $id ID of the node to be deleted
*
* @access public
* @return bool True if the delete succeeds
*/
function deleteNode($id) {
 
if ($this->debug) {
$this->_debugMessage("deleteNode($id)");
}
 
// invalid target node, bail out
if (!($thisnode = $this->pickNode($id, true))) {
$epr = array('deleteNode()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
if (PEAR::isError($lock = $this->_setLock())) {
return $lock;
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeDelete'])) {
// EVENT (NodeDelete)
$this->triggerEvent('nodeDelete', $this->pickNode($id));
}
 
$parent = $this->getParent($id, true);
$len = $thisnode['r'] - $thisnode['l'] + 1;
 
 
$sql = array();
 
// Delete the node
$sql[] = sprintf('DELETE FROM %s WHERE %s BETWEEN %s AND %s AND %s=%s',
$this->node_table,
$this->_flparams['l'],
$thisnode['l'],
$thisnode['r'],
$this->_flparams['rootid'],
$thisnode['rootid']
);
 
if ($thisnode['id'] != $thisnode['rootid']) {
 
// The node isn't a rootnode so close the gap
$sql[] = sprintf('UPDATE %s SET
%s=IF(%s>%s, %s-%s, %s),
%s=IF(%s>%s, %s-%s, %s)
WHERE %s=%s AND
(%s>%s OR %s>%s)',
$this->node_table,
$this->_flparams['l'],
$this->_flparams['l'],
$thisnode['l'],
$this->_flparams['l'],
$len,
$this->_flparams['l'],
$this->_flparams['r'],
$this->_flparams['r'],
$thisnode['l'],
$this->_flparams['r'],
$len,
$this->_flparams['r'],
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_flparams['l'],
$thisnode['l'],
$this->_flparams['r'],
$thisnode['r']
);
 
// Re-order
 
$sql[] = sprintf('UPDATE %s SET %s=%s-1 WHERE %s=%s AND %s=%s AND %s>%s AND %s BETWEEN %s AND %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_flparams['level'],
$thisnode['level'],
$this->_flparams['norder'],
$thisnode['norder'],
$this->_flparams['l'],
$parent['l'],
$parent['r']);
 
} else {
// A rootnode was deleted and we only have to close the gap inside the order
$sql[] = sprintf('UPDATE %s SET %s=%s+1 WHERE %s=%s AND %s > %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['rootid'],
$this->_flparams['id'],
$this->_flparams['norder'],
$thisnode['norder']);
}
for($i=0;$i<count($sql);$i++) {
$res = $this->db->query($sql[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
$this->_releaseLock();
return true;
}
 
// }}}
// {{{ updateNode()
 
/**
* Changes the payload of a node
*
* @param int $id Node ID
* @param array $values Hash with param => value pairs of the node (see $this->params)
* @param bool $_intermal Internal use only. Used to skip value validation. Leave this as it is.
*
* @access public
* @return bool True if the update is successful
*/
function updateNode($id, $values, $_internal=false) {
if ($this->debug) {
$this->_debugMessage('updateNode($id, $values)');
}
 
if (PEAR::isError($lock = $this->_setLock())) {
return $lock;
}
 
if(!$_internal) {
$this->_verifyUserValues('createRootNode()', $values);
}
 
$eparams = array('values' => $values);
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeUpdate'])) {
// EVENT (NodeUpdate)
$this->triggerEvent('nodeUpdate', $this->pickNode($id), $eparams);
}
 
$addvalues = array();
if (!$qr = $this->_values2Query($values, $addvalues)) {
$this->_releaseLock();
return false;
}
 
$sql = sprintf('UPDATE %s SET %s WHERE %s = %s',
$this->node_table,
$qr,
$this->_flparams['id'],
$id);
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
$this->_releaseLock();
return true;
}
 
 
 
// }}}
// +----------------------------------------------+
// | Moving and copying |
// |----------------------------------------------+
// | [PUBLIC] |
// +----------------------------------------------+
// {{{ moveTree()
 
/**
* Wrapper for node moving and copying
*
* @param int $id Source ID
* @param int $target Target ID
* @param constant $pos Position (use one of the NESE_MOVE_* constants)
* @param bool $copy Shall we create a copy
*
* @see _moveInsideLevel
* @see _moveAcross
* @see _moveRoot2Root
* @access public
* @return int ID of the moved node or false on error
*/
function moveTree($id, $targetid, $pos, $copy = false) {
 
if ($this->debug) {
$this->_debugMessage('moveTree($id, $target, $pos, $copy = false)');
}
if($id == $targetid && !$copy) {
// TRIGGER BOGUS MESSAGE
return false;
}
 
// Get information about source and target
if (!($source = $this->pickNode($id, true))) {
$epr = array('moveTree()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
if (!($target = $this->pickNode($targetid, true))) {
$epr = array('moveTree()', $targetid);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
if (PEAR::isError($lock = $this->_setLock(true))) {
return $lock;
}
 
$this->_relations = array();
// This operations don't need callbacks except the copy handler
// which ignores this setting
$this->_skipCallbacks = true;
 
if(!$copy) {
// We have a recursion - let's stop
if (($target['rootid'] == $source['rootid']) &&
(($source['l'] <= $target['l']) &&
($source['r'] >= $target['r']))) {
$this->_releaseLock(true);
$epr = array('moveTree()');
return $this->_raiseError(NESE_ERROR_RECURSION, PEAR_ERROR_RETURN, E_USER_NOTICE, $epr);
}
 
// Insert/move before or after
 
if (($source['rootid'] == $source['id']) &&
($target['rootid'] == $target['id'])) {
// We have to move a rootnode which is different from moving inside a tree
$nid = $this->_moveRoot2Root($source, $target, $pos, $copy);
$this->_releaseLock(true);
return $nid;
}
} elseif(($target['rootid'] == $source['rootid']) &&
(($source['l'] < $target['l']) &&
($source['r'] > $target['r']))) {
$this->_releaseLock(true);
$epr = array('moveTree()');
return $this->_raiseError(NESE_ERROR_RECURSION, PEAR_ERROR_RETURN, E_USER_NOTICE, $epr);
}
 
 
// We have to move between different levels and maybe subtrees - let's rock ;)
$this->_moveAcross($source, $target, $pos);
$this->_moveCleanup($copy);
$this->_releaseLock(true);
}
 
// }}}
// {{{ _moveAcross()
 
/**
* Moves nodes and trees to other subtrees or levels
*
* <pre>
* [+] <--------------------------------+
* +-[\] root1 [target] |
* <-------------------------+ |p
* +-\ root2 | |
* | | | |
* | |-- subnode1 [target] | |B
* | |-- subnode2 [new] |S |E
* | |-- subnode3 |U |F
* | |B |O
* +-\ root3 | |R
* |-- subnode 3.1 | |E
* |-\ subnode 3.2 [source] >--+------+
* |-- subnode 3.2.1
*</pre>
*
* @param object NodeCT $source Source node
* @param object NodeCT $target Target node
* @param string $pos Position [SUBnode/BEfore]
* @param bool $copy Shall we create a copy
*
* @access private
* @see moveTree
* @see _r_moveAcross
* @see _moveCleanup
*/
function _moveAcross($source, $target, $pos) {
if ($this->debug) {
$this->_debugMessage('_moveAcross($source, $target, $pos, $copy = false)');
}
 
// Get the current data from a node and exclude the id params which will be changed
// because of the node move
$values = array();
foreach($this->params as $key => $val) {
if ($source[$val] && !in_array($val, $this->_requiredParams)) {
$values[$key] = trim($source[$val]);
}
}
 
switch($pos) {
 
case NESE_MOVE_BEFORE:
$clone_id = $this->createLeftNode($target['id'], $values);
break;
 
case NESE_MOVE_AFTER:
$clone_id = $this->createRightNode($target['id'], $values);
break;
 
case NESE_MOVE_BELOW:
$clone_id = $this->createSubNode($target['id'], $values);
break;
}
 
 
$children = $this->getChildren($source['id'], true, true, true);
 
 
if ($children) {
$pos = NESE_MOVE_BELOW;
$sclone_id = $clone_id;
// Recurse through the child nodes
foreach($children AS $cid => $child) {
$sclone = $this->pickNode($sclone_id, true);
$sclone_id = $this->_moveAcross($child, $sclone, $pos);
 
$pos = NESE_MOVE_AFTER;
}
}
 
$this->_relations[$source['id']] = $clone_id;
return $clone_id;
}
 
// }}}
// {{{ _moveCleanup()
 
/**
* Deletes the old subtree (node) and writes the node id's into the cloned tree
*
*
* @param array $relations Hash in der Form $h[alteid]=neueid
* @param array $copy Are we in copy mode?
* @access private
*/
function _moveCleanup($copy = false) {
 
$relations = $this->_relations;
if ($this->debug) {
$this->_debugMessage('_moveCleanup($relations, $copy = false)');
}
 
$deletes = array();
$updates = array();
$tb = $this->node_table;
$fid = $this->_flparams['id'];
$froot = $this->_flparams['rootid'];
foreach($relations AS $key => $val) {
$clone = $this->pickNode($val);
if ($copy) {
// EVENT (NodeCopy)
 
$eparams = array('clone' => $clone);
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeCopy'])) {
$this->triggerEvent('nodeCopy', $this->pickNode($key), $eparams);
}
continue;
}
 
// No callbacks here because the node itself doesn't get changed
// Only it's position
// If one needs a callback here please let me know
 
$deletes[] = $key;
// It's isn't a rootnode
if ($clone->id != $clone->rootid) {
 
 
$sql = sprintf('UPDATE %s SET %s=%s WHERE %s = %s',
$this->node_table,
$fid,
$key,
$fid,
$val);
$updates[] = $sql;
} else {
$sql = sprintf('UPDATE %s SET %s=%s, %s=%s WHERE %s=%s',
$tb,
$fid,
$key,
$froot,
$val,
$fid,
$val);
 
$updates[] = $sql;
$orootid = $clone->rootid;
 
$sql = sprintf('UPDATE %s SET %s=%s WHERE %s=%s',
$tb,
$froot,
$key,
$froot,
$orootid);
$updates[] = $sql;
}
$this->_skipCallbacks = false;
}
 
if(!empty($deletes)) {
for($i=0;$i<count($deletes);$i++) {
$this->deleteNode($deletes[$i]);
}
}
 
if(!empty($updates)) {
for($i=0;$i<count($updates);$i++) {
$res = $this->db->query($updates[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
}
 
return true;
}
 
// }}}
// {{{ _moveRoot2Root()
 
/**
* Moves rootnodes
*
* <pre>
* +-- root1
* |
* +-\ root2
* | |
* | |-- subnode1 [target]
* | |-- subnode2 [new]
* | |-- subnode3
* |
* +-\ root3
* [|] <-----------------------+
* |-- subnode 3.1 [target] |
* |-\ subnode 3.2 [source] >--+
* |-- subnode 3.2.1
* </pre>
*
* @param object NodeCT $source Source
* @param object NodeCT $target Target
* @param string $pos BEfore | AFter
* @access private
* @see moveTree
*/
function _moveRoot2Root($source, $target, $pos) {
 
if ($this->debug) {
$this->_debugMessage('_moveRoot2Root($source, $target, $pos, $copy)');
}
if(PEAR::isError($lock=$this->_setLock())) {
return $lock;
}
 
$tb = $this->node_table;
$fid = $this->_flparams['id'];
$froot = $this->_flparams['rootid'];
$freh = $this->_flparams['norder'];
$s_order = $source['norder'];
$t_order = $target['norder'];
$s_id = $source['id'];
$t_id = $target['id'];
 
 
if ($s_order < $t_order) {
if ($pos == NESE_MOVE_BEFORE) {
$sql = "UPDATE $tb SET $freh=$freh-1
WHERE $freh BETWEEN $s_order AND $t_order AND
$fid!=$t_id AND
$fid!=$s_id AND
$froot=$fid";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
$sql = "UPDATE $tb SET $freh=$t_order -1 WHERE $fid=$s_id";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
elseif($pos == NESE_MOVE_AFTER) {
 
$sql = "UPDATE $tb SET $freh=$freh-1
WHERE $freh BETWEEN $s_order AND $t_order AND
$fid!=$s_id AND
$froot=$fid";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
 
$sql = "UPDATE $tb SET $freh=$t_order WHERE $fid=$s_id";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
}
 
if ($s_order > $t_order) {
if ($pos == NESE_MOVE_BEFORE) {
$sql = "UPDATE $tb SET $freh=$freh+1
WHERE $freh BETWEEN $t_order AND $s_order AND
$fid != $s_id AND
$froot=$fid";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
 
$sql = "UPDATE $tb SET $freh=$t_order WHERE $fid=$s_id";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
elseif ($pos == NESE_MOVE_AFTER) {
$sql = "UPDATE $tb SET $freh=$freh+1
WHERE $freh BETWEEN $t_order AND $s_order AND
$fid!=$t_id AND
$fid!=$s_id AND
$froot=$fid";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
 
$sql = "UPDATE $tb SET $freh=$t_order+1 WHERE $fid = $s_id";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
}
$this->_releaseLock();
return $source->id;
}
 
// }}}
// +-----------------------+
// | Helper methods |
// +-----------------------+
 
// }}}
// {{{ _secSort()
 
/**
* Callback for uasort used to sort siblings
*
* @access private
*/
function _secSort($node1, $node2) {
// Within the same level?
if($node1['level'] != $node2['level']) {
return strnatcmp($node1['l'], $node2['l']);
}
 
// Are they siblings?
$p1 = $this->getParent($node1);
$p2 = $this->getParent($node2);
if($p1['id'] != $p2['id']) {
return strnatcmp($node1['l'], $node2['l']);
}
 
// Same field value? Use the lft value then
$field = $this->params[$this->secondarySort];
if($node1[$field] == $node2[$field]) {
return strnatcmp($node1['l'], $node2[l]);
}
 
// Compare between siblings with different field value
return strnatcmp($node1[$field], $node2[$field]);
}
 
// }}}
// {{{ _addSQL()
 
/**
* Adds a specific type of SQL to a query string
*
* @param array $addSQL The array of SQL strings to add. Example value:
* $addSQL = array(
* 'cols' => 'tb2.col2, tb2.col3', // Additional tables/columns
* 'join' => 'LEFT JOIN tb1 USING(STRID)', // Join statement
* 'append' => 'GROUP by tb1.STRID'); // Group condition
* @param string $type The type of SQL. Can be 'cols', 'join', or 'append'.
*
* @access private
* @return string The SQL, properly formatted
*/
function _addSQL($addSQL, $type) {
if (!isset($addSQL[$type])) {
return '';
}
 
switch($type) {
case 'cols':
return ', ' . $addSQL[$type];
default:
return $addSQL[$type];
}
}
 
// }}}
// {{{ _getSelectFields()
 
/**
* Gets the select fields based on the params
*
* @param bool $aliasFields Should we alias the fields so they are the names of the
* parameter keys, or leave them as is?
*
* @access private
* @return string A string of query fields to select
*/
function _getSelectFields($aliasFields) {
$queryFields = array();
foreach ($this->params as $key => $val) {
$tmp_field = $this->node_table . '.' . $key;
if ($aliasFields) {
$tmp_field .= ' AS ' . $val;
}
$queryFields[] = $tmp_field;
}
 
$fields = implode(', ', $queryFields);
return $fields;
}
 
// }}}
// {{{ _processResultSet()
 
/**
* Processes a DB result set by checking for a DB error and then transforming the result
* into a set of DB_NestedSet_Node objects or leaving it as an array.
*
* @param string $sql The sql query to be done
* @param bool $keepAsArray Keep the result as an array or transform it into a set of
* DB_NestedSet_Node objects?
* @param bool $fieldsAreAliased Are the fields aliased?
*
* @access private
* @return mixed False on error or the transformed node set.
*/
function _processResultSet($sql, $keepAsArray, $fieldsAreAliased) {
$result = $this->db->getAll($sql);
if ($this->_testFatalAbort($result, __FILE__, __LINE__)) {
return false;
}
 
$nodes = array();
$idKey = $fieldsAreAliased ? 'id' : $this->_flparams['id'];
foreach ($result as $row) {
$node_id = $row[$idKey];
if ($keepAsArray) {
$nodes[$node_id] = $row;
} else {
// Create an instance of the node container
$nodes[$node_id] =& new DB_NestedSet_Node($row);
}
 
}
return $nodes;
}
 
// }}}
// {{{ _testFatalAbort()
 
/**
* Error Handler
*
* Tests if a given ressource is a PEAR error object
* ans raises a fatal error in case of an error object
*
* @param object PEAR::Error $errobj The object to test
* @param string $file The filename wher the error occured
* @param int $line The line number of the error
* @return void
* @access private
*/
function _testFatalAbort($errobj, $file, $line) {
if (!$this->_isDBError($errobj)) {
return false;
}
 
if ($this->debug) {
$this->_debugMessage('_testFatalAbort($errobj, $file, $line)');
}
if ($this->debug) {
$message = $errobj->getUserInfo();
$code = $errobj->getCode();
$msg = "$message ($code) in file $file at line $line";
} else {
$msg = $errobj->getMessage();
$code = $errobj->getCode(); }
 
PEAR::raiseError($msg, $code, PEAR_ERROR_TRIGGER, E_USER_ERROR);
}
 
// {{{ __raiseError()
 
/**
* @access private
*/
function _raiseError($code, $mode, $option, $epr=array()) {
$message = vsprintf($this->_getMessage($code), $epr);
return PEAR::raiseError($message, $code, $mode, $option);
}
 
// }}}
 
// {{{ addListener()
 
/**
* Add an event listener
*
* Adds an event listener and returns an ID for it
*
* @param string $event The ivent name
* @param string $listener The listener object
* @return string
* @access public
*/
function addListener($event, &$listener) {
$listenerID = uniqid('el');
$this->eventListeners[$event][$listenerID] =& $listener;
$this->_hasListeners[$event] = true;
return $listenerID;
}
 
// }}}
// {{{ removeListener()
 
/**
* Removes an event listener
*
* Removes the event listener with the given ID
*
* @param string $event The ivent name
* @param string $listenerID The listener's ID
* @return bool
* @access public
*/
function removeListener($event, $listenerID) {
unset($this->eventListeners[$event][$listenerID]);
if (!isset($this->eventListeners[$event]) ||
!is_array($this->eventListeners[$event]) ||
count($this->eventListeners[$event]) == 0) {
unset($this->_hasListeners[$event]);
}
return true;
}
 
// }}}
// {{{ triggerEvent()
 
/**
* Triggers and event an calls the event listeners
*
* @param string $event The Event that occured
* @param object node $node A Reference to the node object which was subject to changes
* @param array $eparams A associative array of params which may be needed by the handler
* @return bool
* @access public
*/
function triggerEvent($event, &$node, $eparams = false) {
if ($this->_skipCallbacks || !isset($this->_hasListeners[$event])) {
return false;
}
 
foreach($this->eventListeners[$event] as $key => $val) {
if (!method_exists($val, 'callEvent')) {
return new PEAR_Error($this->_getMessage(NESE_ERROR_NOHANDLER), NESE_ERROR_NOHANDLER);
}
 
$val->callEvent($event, $node, $eparams);
}
 
return true;
}
 
// }}}
// {{{ apiVersion()
 
function apiVersion() {
return array(
'package:'=>$this->_packagename,
'majorversion'=>$this->_majorversion,
'minorversion'=>$this->_minorversion,
'version'=>sprintf('%s.%s',$this->_majorversion, $this->_minorversion),
'revision'=>str_replace('$', '',"$Revision: 1.56 $")
);
}
 
// }}}
// {{{ setAttr()
 
/**
* Sets an object attribute
*
* @param array $attr An associative array with attributes
*
* @return bool
* @access public
*/
function setAttr($attr) {
static $hasSetSequence;
if (!isset($hasSetSequence)) {
$hasSetSequence = false;
}
 
if (!is_array($attr) || count($attr) == 0) {
return false;
}
 
foreach ($attr as $key => $val) {
$this->$key = $val;
if ($key == 'sequence_table') {
$hasSetSequence = true;
}
 
// only update sequence to reflect new table if they haven't set it manually
if (!$hasSetSequence && $key == 'node_table') {
$this->sequence_table = $this->node_table . '_' . $this->_flparams['id'];
}
if($key == 'cache' && is_object($val)) {
$this->_caching = true;
$GLOBALS['DB_NestedSet'] = & $this;
}
}
 
return true;
}
 
// }}}
// {{{ setsortMode()
/**
* This enables you to set specific options for each output method
*
* @param constant $sortMode
*
* @access public
* @return Current sortMode
*/
function setsortMode($sortMode=false) {
if($sortMode && in_array($sortMode, $this->_sortModes)) {
$this->_sortMode = $sortMode;
} else {
return $this->_sortMode;
}
return $this->_sortMode;
}
// }}}
// {{{ setDbOption()
 
/**
* Sets a db option. Example, setting the sequence table format
*
* @var string $option The option to set
* @var string $val The value of the option
*
* @access public
* @return void
*/
function setDbOption($option, $val) {
$this->db->setOption($option, $val);
}
 
// }}}
// {{{ testLock()
 
/**
* Tests if a database lock is set
*
* @access public
*/
function testLock() {
if ($this->debug) {
$this->_debugMessage('testLock()');
}
 
if($lockID = $this->_structureTableLock) {
return $lockID;
}
$this->_lockGC();
$sql = sprintf('SELECT lockID FROM %s WHERE lockTable=%s',
$this->lock_table,
$this->_quote($this->node_table)) ;
 
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
 
if ($this->_numRows($res)) {
return new PEAR_Error($this->_getMessage(NESE_ERROR_TBLOCKED),NESE_ERROR_TBLOCKED);
}
 
return false;
}
 
// }}}
// {{{ _setLock()
 
/**
* @access private
*/
function _setLock($exclusive=false) {
$lock = $this->testLock();
if(PEAR::isError($lock)) {
return $lock;
}
 
if ($this->debug) {
$this->_debugMessage('_setLock()');
}
if($this->_caching) {
@$this->cache->flush('function_cache');
$this->_caching = false;
$this->_restcache = true;
}
 
if (!$lockID = $this->_structureTableLock) {
$lockID = $this->_structureTableLock = uniqid('lck-');
 
$sql = sprintf('INSERT INTO %s SET lockID=%s, lockTable=%s, lockStamp=%s',
$this->lock_table,
$this->_quote($lockID),
$this->_quote($this->node_table),
time());
 
} else {
$sql = sprintf('UPDATE %s set lockStamp=%s WHERE lockID=%s AND lockTable=%s',
$this->lock_table,
time(),
$this->_quote($lockID),
$this->_quote($this->node_table));
}
if($exclusive) {
$this->_lockExclusive = true;
}
 
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
return $lockID;
}
 
// }}}
// {{{ _releaseLock()
 
/**
* @access private
*/
function _releaseLock($exclusive=false) {
if ($this->debug) {
$this->_debugMessage('_releaseLock()');
}
 
if($exclusive) {
$this->_lockExclusive = false;
}
 
if ((!$lockID = $this->_structureTableLock) || $this->_lockExclusive) {
return false;
}
 
$tb = $this->lock_table;
$stb = $this->node_table;
$sql = "DELETE FROM $tb
WHERE lockTable=" . $this->_quote($stb) . " AND
lockID=" . $this->_quote($lockID);
 
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
$this->_structureTableLock = false;
if($this->_restcache) {
$this->_caching = true;
$this->_restcache = false;
}
return true;
}
 
// }}}
// {{{ _lockGC()
 
/**
* @access private
*/
function _lockGC() {
if ($this->debug) {
$this->_debugMessage('_lockGC()');
}
$tb = $this->lock_table;
$stb = $this->node_table;
$lockTTL = time() - $this->lockTTL;
$sql = "DELETE FROM $tb
WHERE lockTable=" . $this->_quote($stb) . " AND
lockStamp < $lockTTL";
 
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
 
// }}}
// {{{ _values2Query()
 
/**
* @access private
*/
function _values2Query($values, $addval = false) {
 
if ($this->debug) {
$this->_debugMessage('_values2Query($values, $addval = false)');
}
if (is_array($addval)) {
$values = $values + $addval;
}
 
$arq = array();
foreach($values AS $key => $val) {
$k = trim($key);
$v = trim($val);
if ($k) {
// To be used with the next mahor version
// $iv = in_array($this->params[$k], $this->_quotedParams) ? $this->_quote($v) : $v;
$iv = $this->_quote($v);
$arq[] = "$k=$iv";
}
}
 
if (!is_array($arq) || count($arq) == 0) {
return false;
}
 
$query = implode(', ', $arq);
return $query;
}
 
// }}}
// {{{ _verifyUserValues()
 
/**
* Clean values from protected or unknown columns
*
* @var string $caller The calling method
* @var string $values The values array
*
* @access private
* @return void
*/
function _verifyUserValues($caller, &$values) {
 
if($this->_dumbmode) {
return true;
}
foreach($values AS $field=>$value) {
if(!isset($this->params[$field])) {
$epr = array(
$caller,
sprintf('Unknown column/param \'%s\'', $field));
$this->_raiseError(NESE_ERROR_WRONG_MPARAM, PEAR_ERROR_RETURN, E_USER_NOTICE, $epr);
unset($values[$field]);
} else {
$flip = $this->params[$field];
if(in_array($flip, $this->_requiredParams)) {
$epr = array(
$caller,
sprintf('\'%s\' is autogenerated and can\'t be passed - it will be ignored', $field));
$this->_raiseError(NESE_ERROR_WRONG_MPARAM, PEAR_ERROR_RETURN, E_USER_NOTICE, $epr);
unset($values[$field]);
}
}
}
}
 
// }}}
// {{{ _debugMessage()
 
/**
* @access private
*/
function _debugMessage($msg) {
if ($this->debug) {
$time = $this->_getmicrotime();
echo "$time::Debug:: $msg<br />\n";
}
}
 
// }}}
// {{{ _getMessage()
 
/**
* @access private
*/
function _getMessage($code) {
if ($this->debug) {
$this->_debugMessage('_getMessage($code)');
}
return isset($this->messages[$code]) ? $this->messages[$code] : $this->messages[NESE_MESSAGE_UNKNOWN];
 
}
 
// }}}
// {{{ _getmicrotime()
 
/**
* @access private
*/
function _getmicrotime() {
list($usec, $sec) = explode(' ', microtime());
return ((float)$usec + (float)$sec);
}
 
// }}}
// {{{ convertTreeModel()
 
/**
* Convert a <1.3 tree into a 1.3 tree format
*
* This will convert the tree into a format needed for some new features in
* 1.3. Your <1.3 tree will still work without converting but some new features
* like preorder sorting won't work as expected.
*
* <pre>
* Usage:
* - Create a new node table (tb_nodes2) from the current node table (tb_nodes1) (only copy the structure).
* - Create a nested set instance of the 'old' set (NeSe1) and one of the new set (NeSe2)
* - Now you have 2 identical objects where only node_table differs
* - Call DB_NestedSet::convertTreeModel(&$orig, &$copy);
* - After that you have a cleaned up copy of tb_nodes1 inside tb_nodes2
* </pre>
*
* @param object DB_NestedSet $orig Nested set we want to copy
* @param object DB_NestedSet $copy Object where the new tree is copied to
* @param integer $_parent ID of the parent node (private)
*
* @static
* @access public
* @return bool True uns success
*/
function convertTreeModel(&$orig, &$copy, $_parent=false) {
 
static $firstSet;
 
$isRoot = false;
if(!$_parent) {
if(!is_object($orig) || !is_object($copy)) {
return false;
}
if($orig->node_table == $copy->node_table) {
return false;
}
$copy->_dumbmode = true;
$orig->sortMode = NESE_SORT_LEVEL;
$copy->sortMode = NESE_SORT_LEVEL;
$sibl = $orig->getRootNodes(true);
$isRoot = true;
} else {
$sibl = $orig->getChildren($_parent, true);
}
 
if(empty($sibl)) {
return false;
}
 
foreach($sibl AS $sid=>$sibling) {
unset($sibling['l']);
unset($sibling['r']);
unset($sibling['norder']);
 
$values = array();
foreach($sibling AS $key=>$val) {
if(!isset($copy->_flparams[$key])) {
continue;
}
$values[$copy->_flparams[$key]] = $val;
}
 
if(!$firstSet) {
$psid = $copy->createRootNode($values, false, true);
$firstSet = true;
} elseif($isRoot) {
$psid = $copy->createRightNode($psid, $values);
} else {
$copy->createSubNode($_parent, $values);
}
 
DB_NestedSet::convertTreeModel($orig, $copy, $sid);
}
return true;
}
// }}}
// {{{ _numRows()
/**
* Fetches the number of rows the last query returned
* @access private
* @abstract
*/
function _numRows($res) {
}
// }}}
// {{{ _isDBError()
/**
* Returns true if a db return value is an error object
* @access private
* @abstract
*/
function _isDBError($err) {
}
// }}}
// {{{ quote()
/**
* Quotes a string to use it inside queries
* @access private
* @abstract
*/
function _quote($str) {
}
 
}
 
// {{{ DB_NestedSet_Node:: class
 
/**
* Generic class for node objects
*
* @autor Daniel Khan <dk@webcluster.at>;
* @version $Revision: 1.56 $
* @package DB_NestedSet
*
* @access private
*/
 
class DB_NestedSet_Node {
// {{{ constructor
 
/**
* Constructor
*/
function DB_NestedSet_Node($data) {
if (!is_array($data) || count($data) == 0) {
return new PEAR_ERROR($data, NESE_ERROR_PARAM_MISSING);
}
 
$this->setAttr($data);
return true;
}
 
// }}}
// {{{ setAttr()
 
function setAttr($data) {
if(!is_array($data) || count($data) == 0) {
return false;
}
 
foreach ($data as $key => $val) {
$this->$key = $val;
}
}
 
// }}}
 
}
// }}}
 
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/Pager.php
New file
0,0 → 1,250
<?php
//
// Pear DB Pager - Retrieve and return information of databases
// result sets
//
// Copyright (C) 2001 Tomas Von Veschler Cox <cox@idecnet.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
// $Id: Pager.php,v 1.3 2002/05/12 13:59:40 cox Exp $
 
require_once 'PEAR.php';
require_once 'DB.php';
 
/**
* This class handles all the stuff needed for displaying paginated results
* from a database query of Pear DB, in a very easy way.
* Documentation and examples of use, can be found in:
* http://vulcanonet.com/soft/pager/ (could be outdated)
*
* IMPORTANT!
* Since PEAR DB already support native row limit (more fast and avaible in
* all the drivers), there is no more need to use $pager->build() or
* the $pager->fetch*() methods.
*
* Usage example:
*
*< ?php
* require_once 'DB/Pager.php';
* $db = DB::connect('your DSN string');
* $from = 0; // The row to start to fetch from (you might want to get this
* // param from the $_GET array
* $limit = 10; // The number of results per page
* $maxpages = 10; // The number of pages for displaying in the pager (optional)
* $res = $db->limitQuery($sql, $from, $limit);
* $nrows = 0; // Alternative you could use $res->numRows()
* while ($row = $res->fetchrow()) {
* // XXX code for building the page here
* $nrows++;
* }
* $data = DB_Pager::getData($from, $limit, $nrows, $maxpages);
* // XXX code for building the pager here
* ? >
*
* @version 0.7
* @author Tomas V.V.Cox <cox@idecnet.com>
* @see http://vulcanonet.com/soft/pager/
*/
 
class DB_Pager extends PEAR
{
 
/**
* Constructor
*
* @param object $res A DB_result object from Pear_DB
* @param int $from The row to start fetching
* @param int $limit How many results per page
* @param int $numrows Pager will automatically
* find this param if is not given. If your Pear_DB backend extension
* doesn't support numrows(), you can manually calculate it
* and supply later to the constructor
* @deprecated
*/
function DB_Pager (&$res, $from, $limit, $numrows = null)
{
$this->res = $res;
$this->from = $from;
$this->limit = $limit;
$this->numrows = $numrows;
}
 
/**
* Calculates all the data needed by Pager to work
*
* @return mixed An assoc array with all the data (see getData)
* or DB_Error on error
* @see DB_Pager::getData
* @deprecated
*/
function build()
{
// if there is no numrows given, calculate it
if ($this->numrows === null) {
$this->numrows = $this->res->numrows();
if (DB::isError($this->numrows)) {
return $this->numrows;
}
}
$data = $this->getData($this->from, $this->limit, $this->numrows);
if (DB::isError($data)) {
return $data;
}
$this->current = $this->from - 1;
$this->top = $data['to'];
return $data;
}
 
/**
* @deprecated
*/
function fetchRow($mode=DB_FETCHMODE_DEFAULT)
{
$this->current++;
if ($this->current >= $this->top) {
return null;
}
return $this->res->fetchRow($mode, $this->current);
}
 
/**
* @deprecated
*/
function fetchInto(&$arr, $mode=DB_FETCHMODE_DEFAULT)
{
$this->current++;
if ($this->current >= $this->top) {
return null;
}
return $this->res->fetchInto($arr, $mode, $this->current);
}
 
/*
* Gets all the data needed to paginate results
* This is an associative array with the following
* values filled in:
*
* array(
* 'current' => X, // current page you are
* 'numrows' => X, // total number of results
* 'next' => X, // row number where next page starts
* 'prev' => X, // row number where prev page starts
* 'remain' => X, // number of results remaning *in next page*
* 'numpages'=> X, // total number of pages
* 'from' => X, // the row to start fetching
* 'to' => X, // the row to stop fetching
* 'limit' => X, // how many results per page
* 'maxpages' => X, // how many pages to show (google style)
* 'firstpage' => X, // the row number of the first page
* 'lastpage' => X, // the row number where the last page starts
* 'pages' => array( // assoc with page "number => start row"
* 1 => X,
* 2 => X,
* 3 => X
* )
* );
* @param int $from The row to start fetching
* @param int $limit How many results per page
* @param int $numrows Number of results from query
*
* @return array associative array with data or DB_error on error
*
*/
function &getData($from, $limit, $numrows, $maxpages = false)
{
if (empty($numrows) || ($numrows < 0)) {
return null;
}
$from = (empty($from)) ? 0 : $from;
 
if ($limit <= 0) {
return PEAR::raiseError (null, 'wrong "limit" param', null,
null, null, 'DB_Error', true);
}
 
// Total number of pages
$pages = ceil($numrows/$limit);
$data['numpages'] = $pages;
 
// first & last page
$data['firstpage'] = 1;
$data['lastpage'] = $pages;
 
// Build pages array
$data['pages'] = array();
for ($i=1; $i <= $pages; $i++) {
$offset = $limit * ($i-1);
$data['pages'][$i] = $offset;
// $from must point to one page
if ($from == $offset) {
// The current page we are
$data['current'] = $i;
}
}
if (!isset($data['current'])) {
return PEAR::raiseError (null, 'wrong "from" param', null,
null, null, 'DB_Error', true);
}
 
// Limit number of pages (goole algoritm)
if ($maxpages) {
$radio = floor($maxpages/2);
$minpage = $data['current'] - $radio;
if ($minpage < 1) {
$minpage = 1;
}
$maxpage = $data['current'] + $radio - 1;
if ($maxpage > $data['numpages']) {
$maxpage = $data['numpages'];
}
foreach (range($minpage, $maxpage) as $page) {
$tmp[$page] = $data['pages'][$page];
}
$data['pages'] = $tmp;
$data['maxpages'] = $maxpages;
} else {
$data['maxpages'] = null;
}
 
// Prev link
$prev = $from - $limit;
$data['prev'] = ($prev >= 0) ? $prev : null;
 
// Next link
$next = $from + $limit;
$data['next'] = ($next < $numrows) ? $next : null;
 
// Results remaining in next page & Last row to fetch
if ($data['current'] == $pages) {
$data['remain'] = 0;
$data['to'] = $numrows;
} else {
if ($data['current'] == ($pages - 1)) {
$data['remain'] = $numrows - ($limit*($pages-1));
} else {
$data['remain'] = $limit;
}
$data['to'] = $data['current'] * $limit;
}
$data['numrows'] = $numrows;
$data['from'] = $from + 1;
$data['limit'] = $limit;
 
return $data;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/mssql.php
New file
0,0 → 1,914
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's mssql extension
* for interacting with Microsoft SQL Server databases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: mssql.php,v 1.83 2005/03/07 18:24:51 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's mssql extension
* for interacting with Microsoft SQL Server databases
*
* These methods overload the ones declared in DB_common.
*
* @category Database
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_mssql extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'mssql';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'mssql';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => 'emulate',
'new_link' => false,
'numrows' => true,
'pconnect' => true,
'prepare' => false,
'ssl' => false,
'transactions' => true,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
// XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX
var $errorcode_map = array(
110 => DB_ERROR_VALUE_COUNT_ON_ROW,
155 => DB_ERROR_NOSUCHFIELD,
170 => DB_ERROR_SYNTAX,
207 => DB_ERROR_NOSUCHFIELD,
208 => DB_ERROR_NOSUCHTABLE,
245 => DB_ERROR_INVALID_NUMBER,
515 => DB_ERROR_CONSTRAINT_NOT_NULL,
547 => DB_ERROR_CONSTRAINT,
1913 => DB_ERROR_ALREADY_EXISTS,
2627 => DB_ERROR_CONSTRAINT,
2714 => DB_ERROR_ALREADY_EXISTS,
3701 => DB_ERROR_NOSUCHTABLE,
8134 => DB_ERROR_DIVZERO,
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* Should data manipulation queries be committed automatically?
* @var bool
* @access private
*/
var $autocommit = true;
 
/**
* The quantity of transactions begun
*
* {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
* @access private
*/
var $transaction_opcount = 0;
 
/**
* The database specified in the DSN
*
* It's a fix to allow calls to different databases in the same script.
*
* @var string
* @access private
*/
var $_db = null;
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_mssql()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('mssql') && !PEAR::loadExtension('sybase')
&& !PEAR::loadExtension('sybase_ct'))
{
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
$params = array(
$dsn['hostspec'] ? $dsn['hostspec'] : 'localhost',
$dsn['username'] ? $dsn['username'] : null,
$dsn['password'] ? $dsn['password'] : null,
);
if ($dsn['port']) {
$params[0] .= ((substr(PHP_OS, 0, 3) == 'WIN') ? ',' : ':')
. $dsn['port'];
}
 
$connect_function = $persistent ? 'mssql_pconnect' : 'mssql_connect';
 
$this->connection = @call_user_func_array($connect_function, $params);
 
if (!$this->connection) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
@mssql_get_last_message());
}
if ($dsn['database']) {
if (!@mssql_select_db($dsn['database'], $this->connection)) {
return $this->raiseError(DB_ERROR_NODBSELECTED,
null, null, null,
@mssql_get_last_message());
}
$this->_db = $dsn['database'];
}
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @mssql_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$ismanip = DB::isManip($query);
$this->last_query = $query;
if (!@mssql_select_db($this->_db, $this->connection)) {
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
}
$query = $this->modifyQuery($query);
if (!$this->autocommit && $ismanip) {
if ($this->transaction_opcount == 0) {
$result = @mssql_query('BEGIN TRAN', $this->connection);
if (!$result) {
return $this->mssqlRaiseError();
}
}
$this->transaction_opcount++;
}
$result = @mssql_query($query, $this->connection);
if (!$result) {
return $this->mssqlRaiseError();
}
// Determine which queries that should return data, and which
// should return an error code only.
return $ismanip ? DB_OK : $result;
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal mssql result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
function nextResult($result)
{
return @mssql_next_result($result);
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@mssql_data_seek($result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @mssql_fetch_array($result, MSSQL_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @mssql_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return @mssql_free_result($result);
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @mssql_num_fields($result);
if (!$cols) {
return $this->mssqlRaiseError();
}
return $cols;
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
function numRows($result)
{
$rows = @mssql_num_rows($result);
if ($rows === false) {
return $this->mssqlRaiseError();
}
return $rows;
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff = false)
{
// XXX if $this->transaction_opcount > 0, we should probably
// issue a warning here.
$this->autocommit = $onoff ? true : false;
return DB_OK;
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
if ($this->transaction_opcount > 0) {
if (!@mssql_select_db($this->_db, $this->connection)) {
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
}
$result = @mssql_query('COMMIT TRAN', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->mssqlRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
if ($this->transaction_opcount > 0) {
if (!@mssql_select_db($this->_db, $this->connection)) {
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
}
$result = @mssql_query('ROLLBACK TRAN', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->mssqlRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
if (DB::isManip($this->last_query)) {
$res = @mssql_query('select @@rowcount', $this->connection);
if (!$res) {
return $this->mssqlRaiseError();
}
$ar = @mssql_fetch_row($res);
if (!$ar) {
$result = 0;
} else {
@mssql_free_result($res);
$result = $ar[0];
}
} else {
$result = 0;
}
return $result;
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_mssql::createSequence(), DB_mssql::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
if (!@mssql_select_db($this->_db, $this->connection)) {
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
}
$repeat = 0;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE))
{
$repeat = 1;
$result = $this->createSequence($seq_name);
if (DB::isError($result)) {
return $this->raiseError($result);
}
} elseif (!DB::isError($result)) {
$result =& $this->query("SELECT @@IDENTITY FROM $seqname");
$repeat = 0;
} else {
$repeat = false;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$result = $result->fetchRow(DB_FETCHMODE_ORDERED);
return $result[0];
}
 
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_mssql::nextID(), DB_mssql::dropSequence()
*/
function createSequence($seq_name)
{
return $this->query('CREATE TABLE '
. $this->getSequenceName($seq_name)
. ' ([id] [int] IDENTITY (1, 1) NOT NULL,'
. ' [vapor] [int] NULL)');
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_mssql::nextID(), DB_mssql::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
 
// }}}
// {{{ quoteIdentifier()
 
/**
* Quotes a string so it can be safely used as a table or column name
*
* @param string $str identifier name to be quoted
*
* @return string quoted identifier string
*
* @see DB_common::quoteIdentifier()
* @since Method available since Release 1.6.0
*/
function quoteIdentifier($str)
{
return '[' . str_replace(']', ']]', $str) . ']';
}
 
// }}}
// {{{ mssqlRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_mssql::errorNative(), DB_mssql::errorCode()
*/
function mssqlRaiseError($code = null)
{
$message = @mssql_get_last_message();
if (!$code) {
$code = $this->errorNative();
}
return $this->raiseError($this->errorCode($code, $message),
null, null, null, "$code - $message");
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error code produced by the last query
*
* @return int the DBMS' error code
*/
function errorNative()
{
$res = @mssql_query('select @@ERROR as ErrorCode', $this->connection);
if (!$res) {
return DB_ERROR;
}
$row = @mssql_fetch_row($res);
return $row[0];
}
 
// }}}
// {{{ errorCode()
 
/**
* Determines PEAR::DB error code from mssql's native codes.
*
* If <var>$nativecode</var> isn't known yet, it will be looked up.
*
* @param mixed $nativecode mssql error code, if known
* @return integer an error number from a DB error constant
* @see errorNative()
*/
function errorCode($nativecode = null, $msg = '')
{
if (!$nativecode) {
$nativecode = $this->errorNative();
}
if (isset($this->errorcode_map[$nativecode])) {
if ($nativecode == 3701
&& preg_match('/Cannot drop the index/i', $msg))
{
return DB_ERROR_NOT_FOUND;
}
return $this->errorcode_map[$nativecode];
} else {
return DB_ERROR;
}
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
* is a table name.
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
if (!@mssql_select_db($this->_db, $this->connection)) {
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
}
$id = @mssql_query("SELECT * FROM $result WHERE 1=0",
$this->connection);
$got_string = true;
} elseif (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$id = $result->result;
$got_string = false;
} else {
/*
* Probably received a result resource identifier.
* Copy it.
* Deprecated. Here for compatibility only.
*/
$id = $result;
$got_string = false;
}
 
if (!is_resource($id)) {
return $this->mssqlRaiseError(DB_ERROR_NEED_MORE_DATA);
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$count = @mssql_num_fields($id);
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
$res[$i] = array(
'table' => $got_string ? $case_func($result) : '',
'name' => $case_func(@mssql_field_name($id, $i)),
'type' => @mssql_field_type($id, $i),
'len' => @mssql_field_length($id, $i),
// We only support flags for table
'flags' => $got_string
? $this->_mssql_field_flags($result,
@mssql_field_name($id, $i))
: '',
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
// free the result only if we were called on a table
if ($got_string) {
@mssql_free_result($id);
}
return $res;
}
 
// }}}
// {{{ _mssql_field_flags()
 
/**
* Get a column's flags
*
* Supports "not_null", "primary_key",
* "auto_increment" (mssql identity), "timestamp" (mssql timestamp),
* "unique_key" (mssql unique index, unique check or primary_key) and
* "multiple_key" (multikey index)
*
* mssql timestamp is NOT similar to the mysql timestamp so this is maybe
* not useful at all - is the behaviour of mysql_field_flags that primary
* keys are alway unique? is the interpretation of multiple_key correct?
*
* @param string $table the table name
* @param string $column the field name
*
* @return string the flags
*
* @access private
* @author Joern Barthel <j_barthel@web.de>
*/
function _mssql_field_flags($table, $column)
{
static $tableName = null;
static $flags = array();
 
if ($table != $tableName) {
 
$flags = array();
$tableName = $table;
 
// get unique and primary keys
$res = $this->getAll("EXEC SP_HELPINDEX[$table]", DB_FETCHMODE_ASSOC);
 
foreach ($res as $val) {
$keys = explode(', ', $val['index_keys']);
 
if (sizeof($keys) > 1) {
foreach ($keys as $key) {
$this->_add_flag($flags[$key], 'multiple_key');
}
}
 
if (strpos($val['index_description'], 'primary key')) {
foreach ($keys as $key) {
$this->_add_flag($flags[$key], 'primary_key');
}
} elseif (strpos($val['index_description'], 'unique')) {
foreach ($keys as $key) {
$this->_add_flag($flags[$key], 'unique_key');
}
}
}
 
// get auto_increment, not_null and timestamp
$res = $this->getAll("EXEC SP_COLUMNS[$table]", DB_FETCHMODE_ASSOC);
 
foreach ($res as $val) {
$val = array_change_key_case($val, CASE_LOWER);
if ($val['nullable'] == '0') {
$this->_add_flag($flags[$val['column_name']], 'not_null');
}
if (strpos($val['type_name'], 'identity')) {
$this->_add_flag($flags[$val['column_name']], 'auto_increment');
}
if (strpos($val['type_name'], 'timestamp')) {
$this->_add_flag($flags[$val['column_name']], 'timestamp');
}
}
}
 
if (array_key_exists($column, $flags)) {
return(implode(' ', $flags[$column]));
}
return '';
}
 
// }}}
// {{{ _add_flag()
 
/**
* Adds a string to the flags array if the flag is not yet in there
* - if there is no flag present the array is created
*
* @param array &$array the reference to the flag-array
* @param string $value the flag value
*
* @return void
*
* @access private
* @author Joern Barthel <j_barthel@web.de>
*/
function _add_flag(&$array, $value)
{
if (!is_array($array)) {
$array = array($value);
} elseif (!in_array($value, $array)) {
array_push($array, $value);
}
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'tables':
return "SELECT name FROM sysobjects WHERE type = 'U'"
. ' ORDER BY name';
case 'views':
return "SELECT name FROM sysobjects WHERE type = 'V'";
default:
return null;
}
}
 
// }}}
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/DataObject.php
New file
0,0 → 1,3827
<?php
/**
* Object Based Database Query Builder and data store
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_DataObject
* @author Alan Knowles <alan@akbkhome.com>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: DataObject.php,v 1.361 2005/07/06 06:13:09 alan_k Exp $
* @link http://pear.php.net/package/DB_DataObject
*/
 
/* ===========================================================================
*
* !!!!!!!!!!!!! W A R N I N G !!!!!!!!!!!
*
* THIS MAY SEGFAULT PHP IF YOU ARE USING THE ZEND OPTIMIZER (to fix it,
* just add "define('DB_DATAOBJECT_NO_OVERLOAD',true);" before you include
* this file. reducing the optimization level may also solve the segfault.
* ===========================================================================
*/
 
/**
* The main "DB_DataObject" class is really a base class for your own tables classes
*
* // Set up the class by creating an ini file (refer to the manual for more details
* [DB_DataObject]
* database = mysql:/username:password@host/database
* schema_location = /home/myapplication/database
* class_location = /home/myapplication/DBTables/
* clase_prefix = DBTables_
*
*
* //Start and initialize...................... - dont forget the &
* $config = parse_ini_file('example.ini',true);
* $options = &PEAR::getStaticProperty('DB_DataObject','options');
* $options = $config['DB_DataObject'];
*
* // example of a class (that does not use the 'auto generated tables data')
* class mytable extends DB_DataObject {
* // mandatory - set the table
* var $_database_dsn = "mysql://username:password@localhost/database";
* var $__table = "mytable";
* function table() {
* return array(
* 'id' => 1, // integer or number
* 'name' => 2, // string
* );
* }
* function keys() {
* return array('id');
* }
* }
*
* // use in the application
*
*
* Simple get one row
*
* $instance = new mytable;
* $instance->get("id",12);
* echo $instance->somedata;
*
*
* Get multiple rows
*
* $instance = new mytable;
* $instance->whereAdd("ID > 12");
* $instance->whereAdd("ID < 14");
* $instance->find();
* while ($instance->fetch()) {
* echo $instance->somedata;
* }
 
 
/**
* Needed classes
* - we use getStaticProperty from PEAR pretty extensively (cant remove it ATM)
*/
 
require_once 'PEAR.php';
 
/**
* We are setting a global fetchmode assoc constant of 2 to be compatible with
* both DB and MDB2
*/
define('DB_DATAOBJECT_FETCHMODE_ASSOC',2);
 
 
 
 
 
/**
* these are constants for the get_table array
* user to determine what type of escaping is required around the object vars.
*/
define('DB_DATAOBJECT_INT', 1); // does not require ''
define('DB_DATAOBJECT_STR', 2); // requires ''
 
define('DB_DATAOBJECT_DATE', 4); // is date #TODO
define('DB_DATAOBJECT_TIME', 8); // is time #TODO
define('DB_DATAOBJECT_BOOL', 16); // is boolean #TODO
define('DB_DATAOBJECT_TXT', 32); // is long text #TODO
define('DB_DATAOBJECT_BLOB', 64); // is blob type
 
 
define('DB_DATAOBJECT_NOTNULL', 128); // not null col.
define('DB_DATAOBJECT_MYSQLTIMESTAMP' , 256); // mysql timestamps (ignored by update/insert)
/*
* Define this before you include DataObjects.php to disable overload - if it segfaults due to Zend optimizer..
*/
//define('DB_DATAOBJECT_NO_OVERLOAD',true)
 
 
/**
* Theses are the standard error codes, most methods will fail silently - and return false
* to access the error message either use $table->_lastError
* or $last_error = PEAR::getStaticProperty('DB_DataObject','lastError');
* the code is $last_error->code, and the message is $last_error->message (a standard PEAR error)
*/
 
define('DB_DATAOBJECT_ERROR_INVALIDARGS', -1); // wrong args to function
define('DB_DATAOBJECT_ERROR_NODATA', -2); // no data available
define('DB_DATAOBJECT_ERROR_INVALIDCONFIG', -3); // something wrong with the config
define('DB_DATAOBJECT_ERROR_NOCLASS', -4); // no class exists
define('DB_DATAOBJECT_ERROR_INVALID_CALL' ,-7); // overlad getter/setter failure
 
/**
* Used in methods like delete() and count() to specify that the method should
* build the condition only out of the whereAdd's and not the object parameters.
*/
define('DB_DATAOBJECT_WHEREADD_ONLY', true);
 
/**
*
* storage for connection and result objects,
* it is done this way so that print_r()'ing the is smaller, and
* it reduces the memory size of the object.
* -- future versions may use $this->_connection = & PEAR object..
* although will need speed tests to see how this affects it.
* - includes sub arrays
* - connections = md5 sum mapp to pear db object
* - results = [id] => map to pear db object
* - resultseq = sequence id for results & results field
* - resultfields = [id] => list of fields return from query (for use with toArray())
* - ini = mapping of database to ini file results
* - links = mapping of database to links file
* - lasterror = pear error objects for last error event.
* - config = aliased view of PEAR::getStaticPropery('DB_DataObject','options') * done for performance.
* - array of loaded classes by autoload method - to stop it doing file access request over and over again!
*/
$GLOBALS['_DB_DATAOBJECT']['RESULTS'] = array();
$GLOBALS['_DB_DATAOBJECT']['RESULTSEQ'] = 1;
$GLOBALS['_DB_DATAOBJECT']['RESULTFIELDS'] = array();
$GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'] = array();
$GLOBALS['_DB_DATAOBJECT']['INI'] = array();
$GLOBALS['_DB_DATAOBJECT']['LINKS'] = array();
$GLOBALS['_DB_DATAOBJECT']['SEQUENCE'] = array();
$GLOBALS['_DB_DATAOBJECT']['LASTERROR'] = null;
$GLOBALS['_DB_DATAOBJECT']['CONFIG'] = array();
$GLOBALS['_DB_DATAOBJECT']['CACHE'] = array();
$GLOBALS['_DB_DATAOBJECT']['OVERLOADED'] = false;
$GLOBALS['_DB_DATAOBJECT']['QUERYENDTIME'] = 0;
 
 
// this will be horrifically slow!!!!
// NOTE: Overload SEGFAULTS ON PHP4 + Zend Optimizer (see define before..)
// these two are BC/FC handlers for call in PHP4/5
 
if ( substr(phpversion(),0,1) == 5) {
class DB_DataObject_Overload
{
function __call($method,$args)
{
$return = null;
$this->_call($method,$args,$return);
return $return;
}
function __sleep()
{
return array_keys(get_object_vars($this)) ;
}
}
} else {
if (version_compare(phpversion(),'4.3.10','eq') && !defined('DB_DATAOBJECT_NO_OVERLOAD')) {
trigger_error(
"overload does not work with PHP4.3.10, either upgrade
(snaps.php.net) or more recent version
or define DB_DATAOBJECT_NO_OVERLOAD as per the manual.
",E_USER_ERROR);
}
 
if (!function_exists('clone')) {
// emulate clone - as per php_compact, slow but really the correct behaviour..
eval('function clone($t) { $r = $t; if (method_exists($r,"__clone")) { $r->__clone(); } return $r; }');
}
eval('
class DB_DataObject_Overload {
function __call($method,$args,&$return) {
return $this->_call($method,$args,$return);
}
}
');
}
 
 
 
 
/*
*
* @package DB_DataObject
* @author Alan Knowles <alan@akbkhome.com>
* @since PHP 4.0
*/
class DB_DataObject extends DB_DataObject_Overload
{
/**
* The Version - use this to check feature changes
*
* @access private
* @var string
*/
var $_DB_DataObject_version = "1.7.15";
 
/**
* The Database table (used by table extends)
*
* @access private
* @var string
*/
var $__table = ''; // database table
 
/**
* The Number of rows returned from a query
*
* @access public
* @var int
*/
var $N = 0; // Number of rows returned from a query
 
 
/* ============================================================= */
/* Major Public Methods */
/* (designed to be optionally then called with parent::method()) */
/* ============================================================= */
 
 
/**
* Get a result using key, value.
*
* for example
* $object->get("ID",1234);
* Returns Number of rows located (usually 1) for success,
* and puts all the table columns into this classes variables
*
* see the fetch example on how to extend this.
*
* if no value is entered, it is assumed that $key is a value
* and get will then use the first key in keys()
* to obtain the key.
*
* @param string $k column
* @param string $v value
* @access public
* @return int No. of rows
*/
function get($k = null, $v = null)
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
$keys = array();
if ($v === null) {
$v = $k;
$keys = $this->keys();
if (!$keys) {
$this->raiseError("No Keys available for {$this->__table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
$k = $keys[0];
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("$k $v " .print_r($keys,true), "GET");
}
if ($v === null) {
$this->raiseError("No Value specified for get", DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
$this->$k = $v;
return $this->find(1);
}
 
/**
* An autoloading, caching static get method using key, value (based on get)
*
* Usage:
* $object = DB_DataObject::staticGet("DbTable_mytable",12);
* or
* $object = DB_DataObject::staticGet("DbTable_mytable","name","fred");
*
* or write it into your extended class:
* function &staticGet($k,$v=NULL) { return DB_DataObject::staticGet("This_Class",$k,$v); }
*
* @param string $class class name
* @param string $k column (or value if using keys)
* @param string $v value (optional)
* @access public
* @return object
*/
function &staticGet($class, $k, $v = null)
{
$lclass = strtolower($class);
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
 
 
$key = "$k:$v";
if ($v === null) {
$key = $k;
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
DB_DataObject::debug("$class $key","STATIC GET - TRY CACHE");
}
if (!empty($_DB_DATAOBJECT['CACHE'][$lclass][$key])) {
return $_DB_DATAOBJECT['CACHE'][$lclass][$key];
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
DB_DataObject::debug("$class $key","STATIC GET - NOT IN CACHE");
}
 
$obj = DB_DataObject::factory(substr($class,strlen($_DB_DATAOBJECT['CONFIG']['class_prefix'])));
if (PEAR::isError($obj)) {
DB_DataObject::raiseError("could not autoload $class", DB_DATAOBJECT_ERROR_NOCLASS);
return false;
}
if (!isset($_DB_DATAOBJECT['CACHE'][$lclass])) {
$_DB_DATAOBJECT['CACHE'][$lclass] = array();
}
if (!$obj->get($k,$v)) {
DB_DataObject::raiseError("No Data return from get $k $v", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
$_DB_DATAOBJECT['CACHE'][$lclass][$key] = $obj;
return $_DB_DATAOBJECT['CACHE'][$lclass][$key];
}
 
/**
* find results, either normal or crosstable
*
* for example
*
* $object = new mytable();
* $object->ID = 1;
* $object->find();
*
*
* will set $object->N to number of rows, and expects next command to fetch rows
* will return $object->N
*
* @param boolean $n Fetch first result
* @access public
* @return mixed (number of rows returned, or true if numRows fetching is not supported)
*/
function find($n = false)
{
global $_DB_DATAOBJECT;
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
 
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug($n, "__find",1);
}
if (!$this->__table) {
// xdebug can backtrace this!
php_error("NO \$__table SPECIFIED in class definition",E_USER_ERROR);
}
$this->N = 0;
$query_before = $this->_query;
$this->_build_condition($this->table()) ;
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
/* We are checking for method modifyLimitQuery as it is PEAR DB specific */
$sql = 'SELECT ' .
$this->_query['data_select'] .
' FROM ' . ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table) . " " .
$this->_join .
$this->_query['condition'] . ' '.
$this->_query['group_by'] . ' '.
$this->_query['having'] . ' '.
$this->_query['order_by'] . ' ';
if ((!isset($_DB_DATAOBJECT['CONFIG']['db_driver'])) ||
($_DB_DATAOBJECT['CONFIG']['db_driver'] == 'DB')) {
/* PEAR DB specific */
if (isset($this->_query['limit_start']) && strlen($this->_query['limit_start'] . $this->_query['limit_count'])) {
$sql = $DB->modifyLimitQuery($sql,$this->_query['limit_start'], $this->_query['limit_count']);
}
} else {
/* theoretically MDB! */
if (isset($this->_query['limit_start']) && strlen($this->_query['limit_start'] . $this->_query['limit_count'])) {
$DB->setLimit($this->_query['limit_count'],$this->_query['limit_start']);
}
}
$this->_query($sql);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("CHECK autofetchd $n", "__find", 1);
}
// unset the
if ($n && $this->N > 0 ) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("ABOUT TO AUTOFETCH", "__find", 1);
}
$this->fetch() ;
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("DONE", "__find", 1);
}
$this->_query = $query_before;
return $this->N;
}
 
/**
* fetches next row into this objects var's
*
* returns 1 on success 0 on failure
*
*
*
* Example
* $object = new mytable();
* $object->name = "fred";
* $object->find();
* $store = array();
* while ($object->fetch()) {
* echo $this->ID;
* $store[] = $object; // builds an array of object lines.
* }
*
* to add features to a fetch
* function fetch () {
* $ret = parent::fetch();
* $this->date_formated = date('dmY',$this->date);
* return $ret;
* }
*
* @access public
* @return boolean on success
*/
function fetch()
{
 
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
if (empty($this->N)) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("No data returned from FIND (eg. N is 0)","FETCH", 3);
}
return false;
}
if (empty($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]) ||
!is_object($result = &$_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]))
{
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug('fetched on object after fetch completed (no results found)');
}
return false;
}
$array = $result->fetchRow(DB_DATAOBJECT_FETCHMODE_ASSOC);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug(serialize($array),"FETCH");
}
 
if ($array === null) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$t= explode(' ',microtime());
$this->debug("Last Data Fetch'ed after " .
($t[0]+$t[1]- $_DB_DATAOBJECT['QUERYENDTIME'] ) .
" seconds",
"FETCH", 1);
}
// reduce the memory usage a bit... (but leave the id in, so count() works ok on it)
unset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]);
// this is probably end of data!!
//DB_DataObject::raiseError("fetch: no data returned", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
if (!isset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid])) {
// note: we dont declare this to keep the print_r size down.
$_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid]= array_flip(array_keys($array));
}
foreach($array as $k=>$v) {
$kk = str_replace(".", "_", $k);
$kk = str_replace(" ", "_", $kk);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("$kk = ". $array[$k], "fetchrow LINE", 3);
}
$this->$kk = $array[$k];
}
// set link flag
$this->_link_loaded=false;
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("{$this->__table} DONE", "fetchrow",2);
}
if (isset($this->_query) && empty($_DB_DATAOBJECT['CONFIG']['keep_query_after_fetch'])) {
unset($this->_query);
}
return true;
}
 
/**
* Adds a condition to the WHERE statement, defaults to AND
*
* $object->whereAdd(); //reset or cleaer ewhwer
* $object->whereAdd("ID > 20");
* $object->whereAdd("age > 20","OR");
*
* @param string $cond condition
* @param string $logic optional logic "OR" (defaults to "AND")
* @access public
* @return string|PEAR::Error - previous condition or Error when invalid args found
*/
function whereAdd($cond = false, $logic = 'AND')
{
if (!isset($this->_query)) {
return $this->raiseError(
"You cannot do two queries on the same object (clone it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
}
if ($cond === false) {
$r = $this->_query['condition'];
$this->_query['condition'] = '';
return $r;
}
// check input...= 0 or ' ' == error!
if (!trim($cond)) {
return $this->raiseError("WhereAdd: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
$r = $this->_query['condition'];
if ($this->_query['condition']) {
$this->_query['condition'] .= " {$logic} {$cond}";
return $r;
}
$this->_query['condition'] = " WHERE {$cond}";
return $r;
}
 
/**
* Adds a order by condition
*
* $object->orderBy(); //clears order by
* $object->orderBy("ID");
* $object->orderBy("ID,age");
*
* @param string $order Order
* @access public
* @return none|PEAR::Error - invalid args only
*/
function orderBy($order = false)
{
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($order === false) {
$this->_query['order_by'] = '';
return;
}
// check input...= 0 or ' ' == error!
if (!trim($order)) {
return $this->raiseError("orderBy: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
if (!$this->_query['order_by']) {
$this->_query['order_by'] = " ORDER BY {$order} ";
return;
}
$this->_query['order_by'] .= " , {$order}";
}
 
/**
* Adds a group by condition
*
* $object->groupBy(); //reset the grouping
* $object->groupBy("ID DESC");
* $object->groupBy("ID,age");
*
* @param string $group Grouping
* @access public
* @return none|PEAR::Error - invalid args only
*/
function groupBy($group = false)
{
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($group === false) {
$this->_query['group_by'] = '';
return;
}
// check input...= 0 or ' ' == error!
if (!trim($group)) {
return $this->raiseError("groupBy: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
if (!$this->_query['group_by']) {
$this->_query['group_by'] = " GROUP BY {$group} ";
return;
}
$this->_query['group_by'] .= " , {$group}";
}
 
/**
* Adds a having clause
*
* $object->having(); //reset the grouping
* $object->having("sum(value) > 0 ");
*
* @param string $having condition
* @access public
* @return none|PEAR::Error - invalid args only
*/
function having($having = false)
{
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($having === false) {
$this->_query['having'] = '';
return;
}
// check input...= 0 or ' ' == error!
if (!trim($having)) {
return $this->raiseError("Having: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
if (!$this->_query['having']) {
$this->_query['having'] = " HAVING {$having} ";
return;
}
$this->_query['having'] .= " AND {$having}";
}
 
/**
* Sets the Limit
*
* $boject->limit(); // clear limit
* $object->limit(12);
* $object->limit(12,10);
*
* Note this will emit an error on databases other than mysql/postgress
* as there is no 'clean way' to implement it. - you should consider refering to
* your database manual to decide how you want to implement it.
*
* @param string $a limit start (or number), or blank to reset
* @param string $b number
* @access public
* @return none|PEAR::Error - invalid args only
*/
function limit($a = null, $b = null)
{
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($a === null) {
$this->_query['limit_start'] = '';
$this->_query['limit_count'] = '';
return;
}
// check input...= 0 or ' ' == error!
if ((!is_int($a) && ((string)((int)$a) !== (string)$a))
|| (($b !== null) && (!is_int($b) && ((string)((int)$b) !== (string)$b)))) {
return $this->raiseError("limit: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
global $_DB_DATAOBJECT;
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$this->_query['limit_start'] = ($b == null) ? 0 : (int)$a;
$this->_query['limit_count'] = ($b == null) ? (int)$a : (int)$b;
}
 
/**
* Adds a select columns
*
* $object->selectAdd(); // resets select to nothing!
* $object->selectAdd("*"); // default select
* $object->selectAdd("unixtime(DATE) as udate");
* $object->selectAdd("DATE");
*
* to prepend distict:
* $object->selectAdd('distinct ' . $object->selectAdd());
*
* @param string $k
* @access public
* @return mixed null or old string if you reset it.
*/
function selectAdd($k = null)
{
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($k === null) {
$old = $this->_query['data_select'];
$this->_query['data_select'] = '';
return $old;
}
// check input...= 0 or ' ' == error!
if (!trim($k)) {
return $this->raiseError("selectAdd: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
if ($this->_query['data_select']) {
$this->_query['data_select'] .= ', ';
}
$this->_query['data_select'] .= " $k ";
}
/**
* Adds multiple Columns or objects to select with formating.
*
* $object->selectAs(null); // adds "table.colnameA as colnameA,table.colnameB as colnameB,......"
* // note with null it will also clear the '*' default select
* $object->selectAs(array('a','b'),'%s_x'); // adds "a as a_x, b as b_x"
* $object->selectAs(array('a','b'),'ddd_%s','ccc'); // adds "ccc.a as ddd_a, ccc.b as ddd_b"
* $object->selectAdd($object,'prefix_%s'); // calls $object->get_table and adds it all as
* objectTableName.colnameA as prefix_colnameA
*
* @param array|object|null the array or object to take column names from.
* @param string format in sprintf format (use %s for the colname)
* @param string table name eg. if you have joinAdd'd or send $from as an array.
* @access public
* @return void
*/
function selectAs($from = null,$format = '%s',$tableName=false)
{
global $_DB_DATAOBJECT;
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($from === null) {
// blank the '*'
$this->selectAdd();
$from = $this;
}
$table = $this->__table;
if (is_object($from)) {
$table = $from->__table;
$from = array_keys($from->table());
}
if ($tableName !== false) {
$table = $tableName;
}
$s = '%s';
if (!empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers'])) {
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$s = $DB->quoteIdentifier($s);
}
foreach ($from as $k) {
$this->selectAdd(sprintf("{$s}.{$s} as {$format}",$table,$k,$k));
}
$this->_query['data_select'] .= "\n";
}
/**
* Insert the current objects variables into the database
*
* Returns the ID of the inserted element (if auto increment or sequences are used.)
*
* for example
*
* Designed to be extended
*
* $object = new mytable();
* $object->name = "fred";
* echo $object->insert();
*
* @access public
* @return mixed false on failure, int when auto increment or sequence used, otherwise true on success
*/
function insert()
{
global $_DB_DATAOBJECT;
// we need to write to the connection (For nextid) - so us the real
// one not, a copyied on (as ret-by-ref fails with overload!)
if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
$this->_connect();
}
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$items = isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table]) ?
$_DB_DATAOBJECT['INI'][$this->_database][$this->__table] : $this->table();
if (!$items) {
$this->raiseError("insert:No table definition for {$this->__table}",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
$options = &$_DB_DATAOBJECT['CONFIG'];
 
 
$datasaved = 1;
$leftq = '';
$rightq = '';
$seqKeys = isset($_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table]) ?
$_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] :
$this->sequenceKey();
$key = isset($seqKeys[0]) ? $seqKeys[0] : false;
$useNative = isset($seqKeys[1]) ? $seqKeys[1] : false;
$seq = isset($seqKeys[2]) ? $seqKeys[2] : false;
$dbtype = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn["phptype"];
// nativeSequences or Sequences..
 
// big check for using sequences
if (($key !== false) && !$useNative) {
if (!$seq) {
$this->$key = $DB->nextId($this->__table);
} else {
$f = $DB->getOption('seqname_format');
$DB->setOption('seqname_format','%s');
$this->$key = $DB->nextId($seq);
$DB->setOption('seqname_format',$f);
}
}
 
 
 
foreach($items as $k => $v) {
// if we are using autoincrement - skip the column...
if ($key && ($k == $key) && $useNative) {
continue;
}
if (!isset($this->$k)) {
continue;
}
// dont insert data into mysql timestamps
// use query() if you really want to do this!!!!
if ($v & DB_DATAOBJECT_MYSQLTIMESTAMP) {
continue;
}
if ($leftq) {
$leftq .= ', ';
$rightq .= ', ';
}
$leftq .= ($quoteIdentifiers ? ($DB->quoteIdentifier($k) . ' ') : "$k ");
if (is_a($this->$k,'db_dataobject_cast')) {
$value = $this->$k->toString($v,$DB);
if (PEAR::isError($value)) {
$this->raiseError($value->getMessage() ,DB_DATAOBJECT_ERROR_INVALIDARG);
return false;
}
$rightq .= $value;
continue;
}
 
if ((strtolower($this->$k) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) {
$rightq .= " NULL ";
continue;
}
// DATE is empty... on a col. that can be null..
// note: this may be usefull for time as well..
if (!$this->$k &&
(($v & DB_DATAOBJECT_DATE) || ($v & DB_DATAOBJECT_TIME)) &&
!($v & DB_DATAOBJECT_NOTNULL)) {
$rightq .= " NULL ";
continue;
}
if ($v & DB_DATAOBJECT_STR) {
$rightq .= $this->_quote((string) (
($v & DB_DATAOBJECT_BOOL) ?
// this is thanks to the braindead idea of postgres to
// use t/f for boolean.
(($this->$k == 'f') ? 0 : (int)(bool) $this->$k) :
$this->$k
)) . " ";
continue;
}
if (is_numeric($this->$k)) {
$rightq .=" {$this->$k} ";
continue;
}
// at present we only cast to integers
// - V2 may store additional data about float/int
$rightq .= ' ' . intval($this->$k) . ' ';
 
}
// not sure why we let empty insert here.. - I guess to generate a blank row..
if ($leftq || $useNative) {
$table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table);
$r = $this->_query("INSERT INTO {$table} ($leftq) VALUES ($rightq) ");
if (PEAR::isError($r)) {
$this->raiseError($r);
return false;
}
if ($r < 1) {
return 0;
}
// now do we have an integer key!
if ($key && $useNative) {
switch ($dbtype) {
case 'mysql':
case 'mysqli':
$method = "{$dbtype}_insert_id";
$this->$key = $method(
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->connection
);
break;
case 'mssql':
// note this is not really thread safe - you should wrapp it with
// transactions = eg.
// $db->query('BEGIN');
// $db->insert();
// $db->query('COMMIT');
$mssql_key = $DB->getOne("SELECT @@IDENTITY");
if (PEAR::isError($mssql_key)) {
$this->raiseError($r);
return false;
}
$this->$key = $mssql_key;
break;
case 'pgsql':
if (!$seq) {
$seq = $DB->getSequenceName($this->__table );
}
$pgsql_key = $DB->getOne("SELECT last_value FROM ".$seq);
if (PEAR::isError($pgsql_key)) {
$this->raiseError($r);
return false;
}
$this->$key = $pgsql_key;
break;
case 'ifx':
$this->$key = array_shift (
ifx_fetch_row (
ifx_query(
"select DBINFO('sqlca.sqlerrd1') FROM systables where tabid=1",
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->connection,
IFX_SCROLL
),
"FIRST"
)
);
break;
}
}
 
if (isset($_DB_DATAOBJECT['CACHE'][strtolower(get_class($this))])) {
$this->_clear_cache();
}
if ($key) {
return $this->$key;
}
return true;
}
$this->raiseError("insert: No Data specifed for query", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
 
/**
* Updates current objects variables into the database
* uses the keys() to decide how to update
* Returns the true on success
*
* for example
*
* $object = DB_DataObject::factory('mytable');
* $object->get("ID",234);
* $object->email="testing@test.com";
* if(!$object->update())
* echo "UPDATE FAILED";
*
* to only update changed items :
* $dataobject->get(132);
* $original = $dataobject; // clone/copy it..
* $dataobject->setFrom($_POST);
* if ($dataobject->validate()) {
* $dataobject->update($original);
* } // otherwise an error...
*
* performing global updates:
* $object = DB_DataObject::factory('mytable');
* $object->status = "dead";
* $object->whereAdd('age > 150');
* $object->update(DB_DATAOBJECT_WHEREADD_ONLY);
*
* @param object dataobject (optional) | DB_DATAOBJECT_WHEREADD_ONLY - used to only update changed items.
* @access public
* @return int rows affected or false on failure
*/
function update($dataObject = false)
{
global $_DB_DATAOBJECT;
// connect will load the config!
$this->_connect();
$original_query = isset($this->_query) ? $this->_query : null;
$items = isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table]) ?
$_DB_DATAOBJECT['INI'][$this->_database][$this->__table] : $this->table();
// only apply update against sequence key if it is set?????
$seq = $this->sequenceKey();
if ($seq[0] !== false) {
$keys = array($seq[0]);
if (empty($this->{$keys[0]}) && $dataObject !== true) {
$this->raiseError("update: trying to perform an update without
the key set, and argument to update is not
DB_DATAOBJECT_WHEREADD_ONLY
", DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
} else {
$keys = $this->keys();
}
if (!$items) {
$this->raiseError("update:No table definition for {$this->__table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
$datasaved = 1;
$settings = '';
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$dbtype = $DB->dsn["phptype"];
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
foreach($items as $k => $v) {
if (!isset($this->$k)) {
continue;
}
// ignore stuff thats
// dont write things that havent changed..
if (($dataObject !== false) && isset($dataObject->$k) && ($dataObject->$k == $this->$k)) {
continue;
}
// - dont write keys to left.!!!
if (in_array($k,$keys)) {
continue;
}
// dont insert data into mysql timestamps
// use query() if you really want to do this!!!!
if ($v & DB_DATAOBJECT_MYSQLTIMESTAMP) {
continue;
}
if ($settings) {
$settings .= ', ';
}
$kSql = ($quoteIdentifiers ? $DB->quoteIdentifier($k) : $k);
if (is_a($this->$k,'db_dataobject_cast')) {
$value = $this->$k->toString($v,$DB);
if (PEAR::isError($value)) {
$this->raiseError($value->getMessage() ,DB_DATAOBJECT_ERROR_INVALIDARG);
return false;
}
$settings .= "$kSql = $value ";
continue;
}
// special values ... at least null is handled...
if ((strtolower($this->$k) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) {
$settings .= "$kSql = NULL ";
continue;
}
// DATE is empty... on a col. that can be null..
// note: this may be usefull for time as well..
if (!$this->$k &&
(($v & DB_DATAOBJECT_DATE) || ($v & DB_DATAOBJECT_TIME)) &&
!($v & DB_DATAOBJECT_NOTNULL)) {
$settings .= "$kSql = NULL ";
continue;
}
 
if ($v & DB_DATAOBJECT_STR) {
$settings .= "$kSql = ". $this->_quote((string) (
($v & DB_DATAOBJECT_BOOL) ?
// this is thanks to the braindead idea of postgres to
// use t/f for boolean.
(($this->$k == 'f') ? 0 : (int)(bool) $this->$k) :
$this->$k
)) . ' ';
continue;
}
if (is_numeric($this->$k)) {
$settings .= "$kSql = {$this->$k} ";
continue;
}
// at present we only cast to integers
// - V2 may store additional data about float/int
$settings .= "$kSql = " . intval($this->$k) . ' ';
}
 
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("got keys as ".serialize($keys),3);
}
if ($dataObject !== true) {
$this->_build_condition($items,$keys);
} else {
// prevent wiping out of data!
if (empty($this->_query['condition'])) {
$this->raiseError("update: global table update not available
do \$do->whereAdd('1=1'); if you really want to do that.
", DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
}
// echo " $settings, $this->condition ";
if ($settings && isset($this->_query) && $this->_query['condition']) {
$table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table);
$r = $this->_query("UPDATE {$table} SET {$settings} {$this->_query['condition']} ");
// restore original query conditions.
$this->_query = $original_query;
if (PEAR::isError($r)) {
$this->raiseError($r);
return false;
}
if ($r < 1) {
return 0;
}
 
$this->_clear_cache();
return $r;
}
// restore original query conditions.
$this->_query = $original_query;
// if you manually specified a dataobject, and there where no changes - then it's ok..
if ($dataObject !== false) {
return true;
}
$this->raiseError(
"update: No Data specifed for query $settings , {$this->_query['condition']}",
DB_DATAOBJECT_ERROR_NODATA);
return false;
}
 
/**
* Deletes items from table which match current objects variables
*
* Returns the true on success
*
* for example
*
* Designed to be extended
*
* $object = new mytable();
* $object->ID=123;
* echo $object->delete(); // builds a conditon
*
* $object = new mytable();
* $object->whereAdd('age > 12');
* $object->limit(1);
* $object->orderBy('age DESC');
* $object->delete(true); // dont use object vars, use the conditions, limit and order.
*
* @param bool $useWhere (optional) If DB_DATAOBJECT_WHEREADD_ONLY is passed in then
* we will build the condition only using the whereAdd's. Default is to
* build the condition only using the object parameters.
*
* @access public
* @return mixed True on success, false on failure, 0 on no data affected
*/
function delete($useWhere = false)
{
global $_DB_DATAOBJECT;
// connect will load the config!
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
$extra_cond = ' ' . (isset($this->_query['order_by']) ? $this->_query['order_by'] : '');
if (!$useWhere) {
 
$keys = $this->keys();
$this->_query = array(); // as it's probably unset!
$this->_query['condition'] = ''; // default behaviour not to use where condition
$this->_build_condition($this->table(),$keys);
// if primary keys are not set then use data from rest of object.
if (!$this->_query['condition']) {
$this->_build_condition($this->table(),array(),$keys);
}
$extra_cond = '';
}
 
// don't delete without a condition
if (isset($this->_query) && $this->_query['condition']) {
$table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table);
$sql = "DELETE FROM {$table} {$this->_query['condition']}{$extra_cond}";
// add limit..
if (isset($this->_query['limit_start']) && strlen($this->_query['limit_start'] . $this->_query['limit_count'])) {
if (!isset($_DB_DATAOBJECT['CONFIG']['db_driver']) ||
($_DB_DATAOBJECT['CONFIG']['db_driver'] == 'DB')) {
// pear DB
$sql = $DB->modifyLimitQuery($sql,$this->_query['limit_start'], $this->_query['limit_count']);
} else {
// MDB
$DB->setLimit( $this->_query['limit_count'],$this->_query['limit_start']);
}
}
$r = $this->_query($sql);
if (PEAR::isError($r)) {
$this->raiseError($r);
return false;
}
if ($r < 1) {
return 0;
}
$this->_clear_cache();
return $r;
} else {
$this->raiseError("delete: No condition specifed for query", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
}
 
/**
* fetches a specific row into this object variables
*
* Not recommended - better to use fetch()
*
* Returens true on success
*
* @param int $row row
* @access public
* @return boolean true on success
*/
function fetchRow($row = null)
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
$this->_loadConfig();
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("{$this->__table} $row of {$this->N}", "fetchrow",3);
}
if (!$this->__table) {
$this->raiseError("fetchrow: No table", DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
if ($row === null) {
$this->raiseError("fetchrow: No row specified", DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if (!$this->N) {
$this->raiseError("fetchrow: No results avaiable", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("{$this->__table} $row of {$this->N}", "fetchrow",3);
}
 
 
$result = &$_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid];
$array = $result->fetchrow(DB_DATAOBJECT_FETCHMODE_ASSOC,$row);
if (!is_array($array)) {
$this->raiseError("fetchrow: No results available", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
 
foreach($array as $k => $v) {
$kk = str_replace(".", "_", $k);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("$kk = ". $array[$k], "fetchrow LINE", 3);
}
$this->$kk = $array[$k];
}
 
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("{$this->__table} DONE", "fetchrow", 3);
}
return true;
}
 
/**
* Find the number of results from a simple query
*
* for example
*
* $object = new mytable();
* $object->name = "fred";
* echo $object->count();
* echo $object->count(true); // dont use object vars.
* echo $object->count('distinct mycol'); count distinct mycol.
* echo $object->count('distinct mycol',true); // dont use object vars.
* echo $object->count('distinct'); // count distinct id (eg. the primary key)
*
*
* @param bool|string (optional)
* (true|false => see below not on whereAddonly)
* (string)
* "DISTINCT" => does a distinct count on the tables 'key' column
* otherwise => normally it counts primary keys - you can use
* this to do things like $do->count('distinct mycol');
*
* @param bool $whereAddOnly (optional) If DB_DATAOBJECT_WHEREADD_ONLY is passed in then
* we will build the condition only using the whereAdd's. Default is to
* build the condition using the object parameters as well.
*
* @access public
* @return int
*/
function count($countWhat = false,$whereAddOnly = false)
{
global $_DB_DATAOBJECT;
if (is_bool($countWhat)) {
$whereAddOnly = $countWhat;
}
$t = clone($this);
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
$items = $t->table();
if (!isset($t->_query)) {
$this->raiseError(
"You cannot do run count after you have run fetch()",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
 
if (!$whereAddOnly && $items) {
$t->_build_condition($items);
}
$keys = $this->keys();
 
if (!$keys[0] && !is_string($countWhat)) {
$this->raiseError(
"You cannot do run count without keys - use \$do->keys('id');",
DB_DATAOBJECT_ERROR_INVALIDARGS,PEAR_ERROR_DIE);
return false;
}
$table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table);
$key_col = ($quoteIdentifiers ? $DB->quoteIdentifier($keys[0]) : $keys[0]);
$as = ($quoteIdentifiers ? $DB->quoteIdentifier('DATAOBJECT_NUM') : 'DATAOBJECT_NUM');
// support distinct on default keys.
$countWhat = (strtoupper($countWhat) == 'DISTINCT') ?
"DISTINCT {$table}.{$key_col}" : $countWhat;
$countWhat = is_string($countWhat) ? $countWhat : "{$table}.{$key_col}";
$r = $t->_query(
"SELECT count({$countWhat}) as $as
FROM $table {$t->_join} {$t->_query['condition']}");
if (PEAR::isError($r)) {
return false;
}
$result = &$_DB_DATAOBJECT['RESULTS'][$t->_DB_resultid];
$l = $result->fetchRow();
return $l[0];
}
 
/**
* sends raw query to database
*
* Since _query has to be a private 'non overwriteable method', this is a relay
*
* @param string $string SQL Query
* @access public
* @return void or DB_Error
*/
function query($string)
{
return $this->_query($string);
}
 
 
/**
* an escape wrapper around DB->escapeSimple()
* can be used when adding manual queries or clauses
* eg.
* $object->query("select * from xyz where abc like '". $object->escape($_GET['name']) . "'");
*
* @param string $string value to be escaped
* @access public
* @return string
*/
function escape($string)
{
global $_DB_DATAOBJECT;
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
// mdb uses escape...
$dd = empty($_DB_DATAOBJECT['CONFIG']['db_driver']) ? 'DB' : $_DB_DATAOBJECT['CONFIG']['db_driver'];
return ($dd == 'DB') ? $DB->escapeSimple($string) : $DB->escape($string);
}
 
/* ==================================================== */
/* Major Private Vars */
/* ==================================================== */
 
/**
* The Database connection dsn (as described in the PEAR DB)
* only used really if you are writing a very simple application/test..
* try not to use this - it is better stored in configuration files..
*
* @access private
* @var string
*/
var $_database_dsn = '';
 
/**
* The Database connection id (md5 sum of databasedsn)
*
* @access private
* @var string
*/
var $_database_dsn_md5 = '';
 
/**
* The Database name
* created in __connection
*
* @access private
* @var string
*/
var $_database = '';
 
/**
* The QUERY rules
* This replaces alot of the private variables
* used to build a query, it is unset after find() is run.
*
*
*
* @access private
* @var array
*/
var $_query = array(
'condition' => '', // the WHERE condition
'group_by' => '', // the GROUP BY condition
'order_by' => '', // the ORDER BY condition
'having' => '', // the HAVING condition
'limit_start' => '', // the LIMIT condition
'limit_count' => '', // the LIMIT condition
'data_select' => '*', // the columns to be SELECTed
);
 
/**
* Database result id (references global $_DB_DataObject[results]
*
* @access private
* @var integer
*/
var $_DB_resultid; // database result object
 
 
/* ============================================================== */
/* Table definition layer (started of very private but 'came out'*/
/* ============================================================== */
 
/**
* Autoload or manually load the table definitions
*
*
* usage :
* DB_DataObject::databaseStructure( 'databasename',
* parse_ini_file('mydb.ini',true),
* parse_ini_file('mydb.link.ini',true));
*
* obviously you dont have to use ini files.. (just return array similar to ini files..)
*
* It should append to the table structure array
*
*
* @param optional string name of database to assign / read
* @param optional array structure of database, and keys
* @param optional array table links
*
* @access public
* @return true or PEAR:error on wrong paramenters.. or false if no file exists..
* or the array(tablename => array(column_name=>type)) if called with 1 argument.. (databasename)
*/
function databaseStructure()
{
 
global $_DB_DATAOBJECT;
// Assignment code
if ($args = func_get_args()) {
if (count($args) == 1) {
// this returns all the tables and their structure..
$x = new DB_DataObject;
$x->_database = $args[0];
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$tables = $DB->getListOf('tables');
require_once 'DB/DataObject/Generator.php';
foreach($tables as $table) {
$y = new DB_DataObject_Generator;
$y->fillTableSchema($x->_database,$table);
}
return $_DB_DATAOBJECT['INI'][$x->_database];
} else {
$_DB_DATAOBJECT['INI'][$args[0]] = isset($_DB_DATAOBJECT['INI'][$args[0]]) ?
$_DB_DATAOBJECT['INI'][$args[0]] + $args[1] : $args[1];
if (isset($args[1])) {
$_DB_DATAOBJECT['LINKS'][$args[0]] = isset($_DB_DATAOBJECT['LINKS'][$args[0]]) ?
$_DB_DATAOBJECT['LINKS'][$args[0]] + $args[2] : $args[2];
}
return true;
}
}
if (!$this->_database) {
$this->_connect();
}
// loaded already?
if (!empty($_DB_DATAOBJECT['INI'][$this->_database])) {
// database loaded - but this is table is not available..
if (empty($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) {
require_once 'DB/DataObject/Generator.php';
$x = new DB_DataObject_Generator;
$x->fillTableSchema($this->_database,$this->__table);
}
return true;
}
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
// if you supply this with arguments, then it will take those
// as the database and links array...
$schemas = isset($_DB_DATAOBJECT['CONFIG']['schema_location']) ?
array("{$_DB_DATAOBJECT['CONFIG']['schema_location']}/{$this->_database}.ini") :
array() ;
if (isset($_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"])) {
$schemas = is_array($_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"]) ?
$_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"] :
explode(PATH_SEPARATOR,$_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"]);
}
foreach ($schemas as $ini) {
$links =
isset($_DB_DATAOBJECT['CONFIG']["links_{$this->_database}"]) ?
$_DB_DATAOBJECT['CONFIG']["links_{$this->_database}"] :
str_replace('.ini','.links.ini',$ini);
 
if (file_exists($ini) && is_file($ini)) {
$_DB_DATAOBJECT['INI'][$this->_database] = parse_ini_file($ini, true);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Loaded ini file: $ini","databaseStructure",1);
}
} else {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Missing ini file: $ini","databaseStructure",1);
}
}
if (empty($_DB_DATAOBJECT['LINKS'][$this->_database]) && file_exists($links) && is_file($links)) {
/* not sure why $links = ... here - TODO check if that works */
$_DB_DATAOBJECT['LINKS'][$this->_database] = parse_ini_file($links, true);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Loaded links.ini file: $links","databaseStructure",1);
}
} else {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Missing links.ini file: $links","databaseStructure",1);
}
}
}
// now have we loaded the structure.. - if not try building it..
if (empty($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) {
require_once 'DB/DataObject/Generator.php';
$x = new DB_DataObject_Generator;
$x->fillTableSchema($this->_database,$this->__table);
}
return true;
}
 
 
 
 
/**
* Return or assign the name of the current table
*
*
* @param string optinal table name to set
* @access public
* @return string The name of the current table
*/
function tableName()
{
$args = func_get_args();
if (count($args)) {
$this->__table = $args[0];
}
return $this->__table;
}
/**
* Return or assign the name of the current database
*
* @param string optional database name to set
* @access public
* @return string The name of the current database
*/
function database()
{
$args = func_get_args();
if (count($args)) {
$this->_database = $args[0];
}
return $this->_database;
}
/**
* get/set an associative array of table columns
*
* @access public
* @param array key=>type array
* @return array (associative)
*/
function table()
{
// for temporary storage of database fields..
// note this is not declared as we dont want to bloat the print_r output
$args = func_get_args();
if (count($args)) {
$this->_database_fields = $args[0];
}
if (isset($this->_database_fields)) {
return $this->_database_fields;
}
global $_DB_DATAOBJECT;
if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
$this->_connect();
}
if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) {
return $_DB_DATAOBJECT['INI'][$this->_database][$this->__table];
}
$this->databaseStructure();
$ret = array();
if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) {
$ret = $_DB_DATAOBJECT['INI'][$this->_database][$this->__table];
}
return $ret;
}
 
/**
* get/set an array of table primary keys
*
* set usage: $do->keys('id','code');
*
* This is defined in the table definition if it gets it wrong,
* or you do not want to use ini tables, you can override this.
* @param string optional set the key
* @param * optional set more keys
* @access private
* @return array
*/
function keys()
{
// for temporary storage of database fields..
// note this is not declared as we dont want to bloat the print_r output
$args = func_get_args();
if (count($args)) {
$this->_database_keys = $args;
}
if (isset($this->_database_keys)) {
return $this->_database_keys;
}
global $_DB_DATAOBJECT;
if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
$this->_connect();
}
if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"])) {
return array_keys($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"]);
}
$this->databaseStructure();
if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"])) {
return array_keys($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"]);
}
return array();
}
/**
* get/set an sequence key
*
* by default it returns the first key from keys()
* set usage: $do->sequenceKey('id',true);
*
* override this to return array(false,false) if table has no real sequence key.
*
* @param string optional the key sequence/autoinc. key
* @param boolean optional use native increment. default false
* @param false|string optional native sequence name
* @access private
* @return array (column,use_native,sequence_name)
*/
function sequenceKey()
{
global $_DB_DATAOBJECT;
// call setting
if (!$this->_database) {
$this->_connect();
}
if (!isset($_DB_DATAOBJECT['SEQUENCE'][$this->_database])) {
$_DB_DATAOBJECT['SEQUENCE'][$this->_database] = array();
}
 
$args = func_get_args();
if (count($args)) {
$args[1] = isset($args[1]) ? $args[1] : false;
$args[2] = isset($args[2]) ? $args[2] : false;
$_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = $args;
}
if (isset($_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table])) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table];
}
// end call setting (eg. $do->sequenceKeys(a,b,c); )
$keys = $this->keys();
if (!$keys) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table]
= array(false,false,false);;
}
 
$table = isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table]) ?
$_DB_DATAOBJECT['INI'][$this->_database][$this->__table] : $this->table();
$dbtype = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype'];
$usekey = $keys[0];
$seqname = false;
if (!empty($_DB_DATAOBJECT['CONFIG']['sequence_'.$this->__table])) {
$usekey = $_DB_DATAOBJECT['CONFIG']['sequence_'.$this->__table];
if (strpos($usekey,':') !== false) {
list($usekey,$seqname) = explode(':',$usekey);
}
}
// if the key is not an integer - then it's not a sequence or native
if (!($table[$usekey] & DB_DATAOBJECT_INT)) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,false);
}
if (!empty($_DB_DATAOBJECT['CONFIG']['ignore_sequence_keys'])) {
$ignore = $_DB_DATAOBJECT['CONFIG']['ignore_sequence_keys'];
if (is_string($ignore) && (strtoupper($ignore) == 'ALL')) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,$seqname);
}
if (is_string($ignore)) {
$ignore = $_DB_DATAOBJECT['CONFIG']['ignore_sequence_keys'] = explode(',',$ignore);
}
if (in_array($this->__table,$ignore)) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,$seqname);
}
}
$realkeys = $_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"];
// if you are using an old ini file - go back to old behaviour...
if (is_numeric($realkeys[$usekey])) {
$realkeys[$usekey] = 'N';
}
// multiple unique primary keys without a native sequence...
if (($realkeys[$usekey] == 'K') && (count($keys) > 1)) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,$seqname);
}
// use native sequence keys...
// technically postgres native here...
// we need to get the new improved tabledata sorted out first.
if ( in_array($dbtype , array( 'mysql', 'mysqli', 'mssql', 'ifx')) &&
($table[$usekey] & DB_DATAOBJECT_INT) &&
isset($realkeys[$usekey]) && ($realkeys[$usekey] == 'N')
) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array($usekey,true,$seqname);
}
// if not a native autoinc, and we have not assumed all primary keys are sequence
if (($realkeys[$usekey] != 'N') &&
!empty($_DB_DATAOBJECT['CONFIG']['dont_use_pear_sequences'])) {
return array(false,false,false);
}
// I assume it's going to try and be a nextval DB sequence.. (not native)
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array($usekey,false,$seqname);
}
/* =========================================================== */
/* Major Private Methods - the core part! */
/* =========================================================== */
 
/**
* clear the cache values for this class - normally done on insert/update etc.
*
* @access private
* @return void
*/
function _clear_cache()
{
global $_DB_DATAOBJECT;
$class = get_class($this);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Clearing Cache for ".$class,1);
}
if (!empty($_DB_DATAOBJECT['CACHE'][$class])) {
unset($_DB_DATAOBJECT['CACHE'][$class]);
}
}
 
/**
* backend wrapper for quoting, as MDB and DB do it differently...
*
* @access private
* @return string quoted
*/
function _quote($str)
{
global $_DB_DATAOBJECT;
return (empty($_DB_DATAOBJECT['CONFIG']['db_driver']) ||
($_DB_DATAOBJECT['CONFIG']['db_driver'] == 'DB'))
? $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->quoteSmart($str)
: $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->quote($str);
}
/**
* connects to the database
*
*
* TODO: tidy this up - This has grown to support a number of connection options like
* a) dynamic changing of ini file to change which database to connect to
* b) multi data via the table_{$table} = dsn ini option
* c) session based storage.
*
* @access private
* @return true | PEAR::error
*/
function _connect()
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
$this->_loadConfig();
}
 
// is it already connected ?
 
if ($this->_database_dsn_md5 && !empty($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
if (PEAR::isError($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
return $this->raiseError(
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->message,
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->code, PEAR_ERROR_DIE
);
}
 
if (!$this->_database) {
$this->_database = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['database'];
if (($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype'] == 'sqlite')
&& is_file($this->_database))
{
$this->_database = basename($this->_database);
}
}
// theoretically we have a md5, it's listed in connections and it's not an error.
// so everything is ok!
return true;
}
 
// it's not currently connected!
// try and work out what to use for the dsn !
 
$options= &$_DB_DATAOBJECT['CONFIG'];
$dsn = isset($this->_database_dsn) ? $this->_database_dsn : null;
 
if (!$dsn) {
if (!$this->_database) {
$this->_database = isset($options["table_{$this->__table}"]) ? $options["table_{$this->__table}"] : null;
}
if ($this->_database && !empty($options["database_{$this->_database}"])) {
$dsn = $options["database_{$this->_database}"];
} else if (!empty($options['database'])) {
$dsn = $options['database'];
}
}
// if still no database...
if (!$dsn) {
return $this->raiseError(
"No database name / dsn found anywhere",
DB_DATAOBJECT_ERROR_INVALIDCONFIG, PEAR_ERROR_DIE
);
}
 
$this->_database_dsn_md5 = md5($dsn);
 
if (!empty($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("USING CACHED CONNECTION", "CONNECT",3);
}
if (!$this->_database) {
$this->_database = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn["database"];
if (($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype'] == 'sqlite')
&& is_file($this->_database))
{
$this->_database = basename($this->_database);
}
}
return true;
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("NEW CONNECTION", "CONNECT",3);
/* actualy make a connection */
$this->debug("{$dsn} {$this->_database_dsn_md5}", "CONNECT",3);
}
// Note this is verbose deliberatly!
if (!isset($_DB_DATAOBJECT['CONFIG']['db_driver']) ||
($_DB_DATAOBJECT['CONFIG']['db_driver'] == 'DB')) {
/* PEAR DB connect */
// this allows the setings of compatibility on DB
$db_options = PEAR::getStaticProperty('DB','options');
require_once 'DB.php';
if ($db_options) {
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5] = DB::connect($dsn,$db_options);
} else {
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5] = DB::connect($dsn);
}
} else {
/* assumption is MDB */
require_once 'MDB2.php';
// this allows the setings of compatibility on MDB2
$db_options = PEAR::getStaticProperty('MDB2','options');
if ($db_options) {
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5] = MDB2::connect($dsn,$db_options);
} else {
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5] = MDB2::connect($dsn);
}
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug(serialize($_DB_DATAOBJECT['CONNECTIONS']), "CONNECT",5);
}
if (PEAR::isError($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
$this->debug($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->toString(), "CONNECT FAILED",5);
return $this->raiseError(
"Connect failed, turn on debugging to 5 see why",
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->code, PEAR_ERROR_DIE
);
 
}
 
if (!$this->_database) {
$this->_database = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn["database"];
if (($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype'] == 'sqlite')
&& is_file($this->_database))
{
$this->_database = basename($this->_database);
}
}
// Oracle need to optimize for portibility - not sure exactly what this does though :)
$c = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
return true;
}
 
/**
* sends query to database - this is the private one that must work
* - internal functions use this rather than $this->query()
*
* @param string $string
* @access private
* @return mixed none or PEAR_Error
*/
function _query($string)
{
global $_DB_DATAOBJECT;
$this->_connect();
 
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
 
$options = &$_DB_DATAOBJECT['CONFIG'];
$_DB_driver = empty($_DB_DATAOBJECT['CONFIG']['db_driver']) ?
'DB': $_DB_DATAOBJECT['CONFIG']['db_driver'];
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug($string,$log="QUERY");
}
if (strtoupper($string) == 'BEGIN') {
if ($_DB_driver == 'DB') {
$DB->autoCommit(false);
} else {
$DB->beginTransaction();
}
// db backend adds begin anyway from now on..
return true;
}
if (strtoupper($string) == 'COMMIT') {
$res = $DB->commit();
if ($_DB_driver == 'DB') {
$DB->autoCommit(true);
}
return $res;
}
if (strtoupper($string) == 'ROLLBACK') {
$DB->rollback();
if ($_DB_driver == 'DB') {
$DB->autoCommit(true);
}
return true;
}
 
if (!empty($options['debug_ignore_updates']) &&
(strtolower(substr(trim($string), 0, 6)) != 'select') &&
(strtolower(substr(trim($string), 0, 4)) != 'show') &&
(strtolower(substr(trim($string), 0, 8)) != 'describe')) {
 
$this->debug('Disabling Update as you are in debug mode');
return $this->raiseError("Disabling Update as you are in debug mode", null) ;
 
}
//if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 1) {
// this will only work when PEAR:DB supports it.
//$this->debug($DB->getAll('explain ' .$string,DB_DATAOBJECT_FETCHMODE_ASSOC), $log="sql",2);
//}
// some sim
$t= explode(' ',microtime());
$_DB_DATAOBJECT['QUERYENDTIME'] = $time = $t[0]+$t[1];
$result = $DB->query($string);
 
if (is_a($result,'DB_Error')) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug($result->toString(), "Query Error",1 );
}
return $this->raiseError($result);
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$t= explode(' ',microtime());
$_DB_DATAOBJECT['QUERYENDTIME'] = $t[0]+$t[1];
$this->debug('QUERY DONE IN '.($t[0]+$t[1]-$time)." seconds", 'query',1);
}
switch (strtolower(substr(trim($string),0,6))) {
case 'insert':
case 'update':
case 'delete':
if ($_DB_driver == 'DB') {
// pear DB specific
return $DB->affectedRows();
}
return $result;
}
if (is_object($result)) {
// lets hope that copying the result object is OK!
$_DB_resultid = $GLOBALS['_DB_DATAOBJECT']['RESULTSEQ']++;
$_DB_DATAOBJECT['RESULTS'][$_DB_resultid] = $result;
$this->_DB_resultid = $_DB_resultid;
}
$this->N = 0;
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug(serialize($result), 'RESULT',5);
}
if (method_exists($result, 'numrows')) {
$DB->expectError(DB_ERROR_UNSUPPORTED);
$this->N = $result->numrows();
if (is_a($this->N,'DB_Error')) {
$this->N = true;
}
$DB->popExpect();
}
}
 
/**
* Builds the WHERE based on the values of of this object
*
* @param mixed $keys
* @param array $filter (used by update to only uses keys in this filter list).
* @param array $negative_filter (used by delete to prevent deleting using the keys mentioned..)
* @access private
* @return string
*/
function _build_condition($keys, $filter = array(),$negative_filter=array())
{
global $_DB_DATAOBJECT;
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
// if we dont have query vars.. - reset them.
if (!isset($this->_query)) {
$x = new DB_DataObject;
$this->_query= $x->_query;
}
 
foreach($keys as $k => $v) {
// index keys is an indexed array
/* these filter checks are a bit suspicious..
- need to check that update really wants to work this way */
 
if ($filter) {
if (!in_array($k, $filter)) {
continue;
}
}
if ($negative_filter) {
if (in_array($k, $negative_filter)) {
continue;
}
}
if (!isset($this->$k)) {
continue;
}
$kSql = $quoteIdentifiers
? ( $DB->quoteIdentifier($this->__table) . '.' . $DB->quoteIdentifier($k) )
: "{$this->__table}.{$k}";
if (is_a($this->$k,'db_dataobject_cast')) {
$dbtype = $DB->dsn["phptype"];
$value = $this->$k->toString($v,$DB);
if (PEAR::isError($value)) {
$this->raiseError($value->getMessage() ,DB_DATAOBJECT_ERROR_INVALIDARG);
return false;
}
if ((strtolower($value) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) {
$this->whereAdd(" $kSql IS NULL");
continue;
}
$this->whereAdd(" $kSql = $value");
continue;
}
if ((strtolower($this->$k) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) {
$this->whereAdd(" $kSql IS NULL");
continue;
}
 
if ($v & DB_DATAOBJECT_STR) {
$this->whereAdd(" $kSql = " . $this->_quote((string) (
($v & DB_DATAOBJECT_BOOL) ?
// this is thanks to the braindead idea of postgres to
// use t/f for boolean.
(($this->$k == 'f') ? 0 : (int)(bool) $this->$k) :
$this->$k
)) );
continue;
}
if (is_numeric($this->$k)) {
$this->whereAdd(" $kSql = {$this->$k}");
continue;
}
/* this is probably an error condition! */
$this->whereAdd(" $kSql = ".intval($this->$k));
}
}
 
/**
* autoload Class relating to a table
* (depreciated - use ::factory)
*
* @param string $table table
* @access private
* @return string classname on Success
*/
function staticAutoloadTable($table)
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
$p = isset($_DB_DATAOBJECT['CONFIG']['class_prefix']) ?
$_DB_DATAOBJECT['CONFIG']['class_prefix'] : '';
$class = $p . preg_replace('/[^A-Z0-9]/i','_',ucfirst($table));
$class = (class_exists($class)) ? $class : DB_DataObject::_autoloadClass($class);
return $class;
}
/**
* classic factory method for loading a table class
* usage: $do = DB_DataObject::factory('person')
* WARNING - this may emit a include error if the file does not exist..
* use @ to silence it (if you are sure it is acceptable)
* eg. $do = @DB_DataObject::factory('person')
*
* table name will eventually be databasename/table
* - and allow modular dataobjects to be written..
* (this also helps proxy creation)
*
*
* @param string $table tablename (use blank to create a new instance of the same class.)
* @access private
* @return DataObject|PEAR_Error
*/
 
function factory($table = '') {
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
if ($table === '') {
if (is_a($this,'DB_DataObject') && strlen($this->__table)) {
$table = $this->__table;
} else {
return DB_DataObject::raiseError(
"factory did not recieve a table name",
DB_DATAOBJECT_ERROR_INVALIDARGS);
}
}
$p = isset($_DB_DATAOBJECT['CONFIG']['class_prefix']) ?
$_DB_DATAOBJECT['CONFIG']['class_prefix'] : '';
$class = $p . preg_replace('/[^A-Z0-9]/i','_',ucfirst($table));
$class = (class_exists($class)) ? $class : DB_DataObject::_autoloadClass($class);
// proxy = full|light
if (!$class && isset($_DB_DATAOBJECT['CONFIG']['proxy'])) {
$proxyMethod = 'getProxy'.$_DB_DATAOBJECT['CONFIG']['proxy'];
require_once 'DB/DataObject/Generator.php';
$d = new DB_DataObject;
$d->__table = $table;
$d->_connect();
$x = new DB_DataObject_Generator;
return $x->$proxyMethod( $d->_database, $table);
}
if (!$class) {
return DB_DataObject::raiseError(
"factory could not find class $class from $table",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
}
 
return new $class;
}
/**
* autoload Class
*
* @param string $class Class
* @access private
* @return string classname on Success
*/
function _autoloadClass($class)
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
$table = substr($class,strlen($_DB_DATAOBJECT['CONFIG']['class_prefix']));
 
// only include the file if it exists - and barf badly if it has parse errors :)
if (!empty($_DB_DATAOBJECT['CONFIG']['proxy']) && empty($_DB_DATAOBJECT['CONFIG']['class_location'])) {
return false;
}
if (strpos($_DB_DATAOBJECT['CONFIG']['class_location'],'%s') !== false) {
$file = sprintf($_DB_DATAOBJECT['CONFIG']['class_location'], preg_replace('/[^A-Z0-9]/i','_',ucfirst($table)));
} else {
$file = $_DB_DATAOBJECT['CONFIG']['class_location'].'/'.preg_replace('/[^A-Z0-9]/i','_',ucfirst($table)).".php";
}
if (!file_exists($file)) {
$found = false;
foreach(explode(PATH_SEPARATOR, ini_get('include_path')) as $p) {
if (file_exists("$p/$file")) {
$file = "$p/$file";
$found = true;
break;
}
}
if (!$found) {
DB_DataObject::raiseError(
"autoload:Could not find class {$class} using class_location value",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
}
include_once $file;
if (!class_exists($class)) {
DB_DataObject::raiseError(
"autoload:Could not autoload {$class}",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
return $class;
}
/**
* Have the links been loaded?
* if they have it contains a array of those variables.
*
* @access private
* @var boolean | array
*/
var $_link_loaded = false;
/**
* Get the links associate array as defined by the links.ini file.
*
*
* Experimental... -
* Should look a bit like
* [local_col_name] => "related_tablename:related_col_name"
*
*
* @return array|null
* array = if there are links defined for this table.
* empty array - if there is a links.ini file, but no links on this table
* null - if no links.ini exists for this database (hence try auto_links).
* @access public
* @see DB_DataObject::getLinks(), DB_DataObject::getLink()
*/
function links()
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
$this->_loadConfig();
}
if (isset($_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table])) {
return $_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table];
}
$this->databaseStructure();
// if there is no link data at all on the file!
// we return null.
if (!isset($_DB_DATAOBJECT['LINKS'][$this->_database])) {
return null;
}
if (isset($_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table])) {
return $_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table];
}
return array();
}
/**
* load related objects
*
* There are two ways to use this, one is to set up a <dbname>.links.ini file
* into a static property named <dbname>.links and specifies the table joins,
* the other highly dependent on naming columns 'correctly' :)
* using colname = xxxxx_yyyyyy
* xxxxxx = related table; (yyyyy = user defined..)
* looks up table xxxxx, for value id=$this->xxxxx
* stores it in $this->_xxxxx_yyyyy
* you can change what object vars the links are stored in by
* changeing the format parameter
*
*
* @param string format (default _%s) where %s is the table name.
* @author Tim White <tim@cyface.com>
* @access public
* @return boolean , true on success
*/
function getLinks($format = '_%s')
{
// get table will load the options.
if ($this->_link_loaded) {
return true;
}
$this->_link_loaded = false;
$cols = $this->table();
$links = $this->links();
$loaded = array();
if ($links) {
foreach($links as $key => $match) {
list($table,$link) = explode(':', $match);
$k = sprintf($format, str_replace('.', '_', $key));
// makes sure that '.' is the end of the key;
if ($p = strpos($key,'.')) {
$key = substr($key, 0, $p);
}
$this->$k = $this->getLink($key, $table, $link);
if (is_object($this->$k)) {
$loaded[] = $k;
}
}
$this->_link_loaded = $loaded;
return true;
}
// this is the autonaming stuff..
// it sends the column name down to getLink and lets that sort it out..
// if there is a links file then it is not used!
// IT IS DEPRECIATED!!!! - USE
if (!is_null($links)) {
return false;
}
foreach (array_keys($cols) as $key) {
if (!($p = strpos($key, '_'))) {
continue;
}
// does the table exist.
$k =sprintf($format, $key);
$this->$k = $this->getLink($key);
if (is_object($this->$k)) {
$loaded[] = $k;
}
}
$this->_link_loaded = $loaded;
return true;
}
 
/**
* return name from related object
*
* There are two ways to use this, one is to set up a <dbname>.links.ini file
* into a static property named <dbname>.links and specifies the table joins,
* the other is highly dependant on naming columns 'correctly' :)
*
* NOTE: the naming convention is depreciated!!! - use links.ini
*
* using colname = xxxxx_yyyyyy
* xxxxxx = related table; (yyyyy = user defined..)
* looks up table xxxxx, for value id=$this->xxxxx
* stores it in $this->_xxxxx_yyyyy
*
* you can also use $this->getLink('thisColumnName','otherTable','otherTableColumnName')
*
*
* @param string $row either row or row.xxxxx
* @param string $table name of table to look up value in
* @param string $link name of column in other table to match
* @author Tim White <tim@cyface.com>
* @access public
* @return mixed object on success
*/
function &getLink($row, $table = null, $link = false)
{
// GUESS THE LINKED TABLE.. (if found - recursevly call self)
if ($table === null) {
$links = $this->links();
if (is_array($links)) {
if ($links[$row]) {
list($table,$link) = explode(':', $links[$row]);
if ($p = strpos($row,".")) {
$row = substr($row,0,$p);
}
return $r = &$this->getLink($row,$table,$link);
}
$this->raiseError(
"getLink: $row is not defined as a link (normally this is ok)",
DB_DATAOBJECT_ERROR_NODATA);
return false; // technically a possible error condition?
 
}
// use the old _ method - this shouldnt happen if called via getLinks()
if (!($p = strpos($row, '_'))) {
return null;
}
$table = substr($row, 0, $p);
return $r = &$this->getLink($row, $table);
 
}
if (!isset($this->$row)) {
$this->raiseError("getLink: row not set $row", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
// check to see if we know anything about this table..
$obj = $this->factory($table);
if (!is_a($obj,'DB_DataObject')) {
$this->raiseError(
"getLink:Could not find class for row $row, table $table",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
if ($link) {
if ($obj->get($link, $this->$row)) {
return $obj;
}
return false;
}
if ($obj->get($this->$row)) {
return $obj;
}
return false;
}
 
/**
* IS THIS SUPPORTED/USED ANYMORE????
*return a list of options for a linked table
*
* This is highly dependant on naming columns 'correctly' :)
* using colname = xxxxx_yyyyyy
* xxxxxx = related table; (yyyyy = user defined..)
* looks up table xxxxx, for value id=$this->xxxxx
* stores it in $this->_xxxxx_yyyyy
*
* @access public
* @return array of results (empty array on failure)
*/
function &getLinkArray($row, $table = null)
{
$ret = array();
if (!$table) {
$links = $this->links();
if (is_array($links)) {
if (!isset($links[$row])) {
// failed..
return $ret;
}
list($table,$link) = explode(':',$links[$row]);
} else {
if (!($p = strpos($row,'_'))) {
return $ret;
}
$table = substr($row,0,$p);
}
}
$c = $this->factory($table);
if (!is_a($c,'DB_DataObject')) {
$this->raiseError(
"getLinkArray:Could not find class for row $row, table $table",
DB_DATAOBJECT_ERROR_INVALIDCONFIG
);
return $ret;
}
 
// if the user defined method list exists - use it...
if (method_exists($c, 'listFind')) {
$c->listFind($this->id);
} else {
$c->find();
}
while ($c->fetch()) {
$ret[] = $c;
}
return $ret;
}
 
/**
* The JOIN condition
*
* @access private
* @var string
*/
var $_join = '';
 
/**
* joinAdd - adds another dataobject to this, building a joined query.
*
* example (requires links.ini to be set up correctly)
* // get all the images for product 24
* $i = new DataObject_Image();
* $pi = new DataObjects_Product_image();
* $pi->product_id = 24; // set the product id to 24
* $i->joinAdd($pi); // add the product_image connectoin
* $i->find();
* while ($i->fetch()) {
* // do stuff
* }
* // an example with 2 joins
* // get all the images linked with products or productgroups
* $i = new DataObject_Image();
* $pi = new DataObject_Product_image();
* $pgi = new DataObject_Productgroup_image();
* $i->joinAdd($pi);
* $i->joinAdd($pgi);
* $i->find();
* while ($i->fetch()) {
* // do stuff
* }
*
*
* @param optional $obj object |array the joining object (no value resets the join)
* If you use an array here it should be in the format:
* array('local_column','remotetable:remote_column');
* if remotetable does not have a definition, you should
* use @ to hide the include error message..
*
*
* @param optional $joinType string 'LEFT'|'INNER'|'RIGHT'|'' Inner is default, '' indicates
* just select ... from a,b,c with no join and
* links are added as where items.
*
* @param optional $joinAs string if you want to select the table as anther name
* useful when you want to select multiple columsn
* from a secondary table.
* @param optional $joinCol string The column on This objects table to match (needed
* if this table links to the child object in
* multiple places eg.
* user->friend (is a link to another user)
* user->mother (is a link to another user..)
*
* @return none
* @access public
* @author Stijn de Reede <sjr@gmx.co.uk>
*/
function joinAdd($obj = false, $joinType='INNER', $joinAs=false, $joinCol=false)
{
global $_DB_DATAOBJECT;
if ($obj === false) {
$this->_join = '';
return;
}
// support for array as first argument
// this assumes that you dont have a links.ini for the specified table.
// and it doesnt exist as am extended dataobject!! - experimental.
$ofield = false; // object field
$tfield = false; // this field
$toTable = false;
if (is_array($obj)) {
$tfield = $obj[0];
list($toTable,$ofield) = explode(':',$obj[1]);
$obj = DB_DataObject::factory($toTable);
if (!$obj || is_a($obj,'PEAR_Error')) {
$obj = new DB_DataObject;
$obj->__table = $toTable;
}
$obj->_connect();
// set the table items to nothing.. - eg. do not try and match
// things in the child table...???
$items = array();
}
if (!is_object($obj)) {
$this->raiseError("joinAdd: called without an object", DB_DATAOBJECT_ERROR_NODATA,PEAR_ERROR_DIE);
}
/* make sure $this->_database is set. */
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
 
/* look up the links for obj table */
//print_r($obj->links());
if (!$ofield && ($olinks = $obj->links())) {
foreach ($olinks as $k => $v) {
/* link contains {this column} = {linked table}:{linked column} */
$ar = explode(':', $v);
if ($ar[0] == $this->__table) {
// you have explictly specified the column
// and the col is listed here..
// not sure if 1:1 table could cause probs here..
if ($joinCol !== false) {
$this->raiseError(
"joinAdd: You cannot target a join column in the " .
"'link from' table ({$obj->__table}). " .
"Either remove the fourth argument to joinAdd() ".
"({$joinCol}), or alter your links.ini file.",
DB_DATAOBJECT_ERROR_NODATA);
return false;
}
$ofield = $k;
$tfield = $ar[1];
break;
}
}
}
 
/* otherwise see if there are any links from this table to the obj. */
//print_r($this->links());
if (($ofield === false) && ($links = $this->links())) {
foreach ($links as $k => $v) {
/* link contains {this column} = {linked table}:{linked column} */
$ar = explode(':', $v);
if ($ar[0] == $obj->__table) {
if ($joinCol !== false) {
if ($k == $joinCol) {
$tfield = $k;
$ofield = $ar[1];
break;
} else {
continue;
}
} else {
$tfield = $k;
$ofield = $ar[1];
break;
}
}
}
}
/* did I find a conneciton between them? */
 
if ($ofield === false) {
$this->raiseError(
"joinAdd: {$obj->__table} has no link with {$this->__table}",
DB_DATAOBJECT_ERROR_NODATA);
return false;
}
$joinType = strtoupper($joinType);
// we default to joining as the same name (this is remvoed later..)
if ($joinAs === false) {
$joinAs = $obj->__table;
}
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
// not sure how portable adding database prefixes is..
$objTable = $quoteIdentifiers ?
$DB->quoteIdentifier($obj->__table) :
$obj->__table ;
// as far as we know only mysql supports database prefixes..
if (
in_array($DB->dsn['phptype'],array('mysql','mysqli')) &&
($obj->_database != $this->_database) &&
strlen($obj->_database)
)
{
// prefix database (quoted if neccessary..)
$objTable = ($quoteIdentifiers
? $DB->quoteIdentifier($obj->_database)
: $obj->_database)
. '.' . $objTable;
}
// nested (join of joined objects..)
$appendJoin = '';
if ($obj->_join) {
// postgres allows nested queries, with ()'s
// not sure what the results are with other databases..
// may be unpredictable..
if (in_array($DB->dsn["phptype"],array('pgsql'))) {
$objTable = "($objTable {$obj->_join})";
} else {
$appendJoin = $obj->_join;
}
}
$table = $this->__table;
if ($quoteIdentifiers) {
$joinAs = $DB->quoteIdentifier($joinAs);
$table = $DB->quoteIdentifier($table);
$ofield = $DB->quoteIdentifier($ofield);
$tfield = $DB->quoteIdentifier($tfield);
}
// add database prefix if they are different databases
$fullJoinAs = '';
$addJoinAs = ($quoteIdentifiers ? $DB->quoteIdentifier($obj->__table) : $obj->__table) != $joinAs;
if ($addJoinAs) {
$fullJoinAs = "AS {$joinAs}";
} else {
// if
if (
in_array($DB->dsn['phptype'],array('mysql','mysqli')) &&
($obj->_database != $this->_database) &&
strlen($this->_database)
)
{
$joinAs = ($quoteIdentifiers ? $DB->quoteIdentifier($obj->_database) : $obj->_database) . '.' . $joinAs;
}
}
switch ($joinType) {
case 'INNER':
case 'LEFT':
case 'RIGHT': // others??? .. cross, left outer, right outer, natural..?
$this->_join .= "\n {$joinType} JOIN {$objTable} {$fullJoinAs}".
" ON {$joinAs}.{$ofield}={$table}.{$tfield} {$appendJoin} ";
break;
case '': // this is just a standard multitable select..
$this->_join .= "\n , {$objTable} {$fullJoinAs} {$appendJoin}";
$this->whereAdd("{$joinAs}.{$ofield}={$table}.{$tfield}");
}
// if obj only a dataobject - eg. no extended class has been defined..
// it obvioulsy cant work out what child elements might exist...
// untill we get on the fly querying of tables..
if ( strtolower(get_class($obj)) == 'db_dataobject') {
return true;
}
/* now add where conditions for anything that is set in the object */
$items = $obj->table();
// will return an array if no items..
// only fail if we where expecting it to work (eg. not joined on a array)
if (!$items) {
$this->raiseError(
"joinAdd: No table definition for {$obj->__table}",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
 
foreach($items as $k => $v) {
if (!isset($obj->$k)) {
continue;
}
$kSql = ($quoteIdentifiers ? $DB->quoteIdentifier($k) : $k);
if ($v & DB_DATAOBJECT_STR) {
$this->whereAdd("{$joinAs}.{$kSql} = " . $this->_quote((string) (
($v & DB_DATAOBJECT_BOOL) ?
// this is thanks to the braindead idea of postgres to
// use t/f for boolean.
(($obj->$k == 'f') ? 0 : (int)(bool) $obj->$k) :
$obj->$k
)));
continue;
}
if (is_numeric($obj->$k)) {
$this->whereAdd("{$joinAs}.{$kSql} = {$obj->$k}");
continue;
}
/* this is probably an error condition! */
$this->whereAdd("{$joinAs}.{$kSql} = 0");
}
if (!isset($this->_query)) {
$this->raiseError(
"joinAdd can not be run from a object that has had a query run on it,
clone the object or create a new one and use setFrom()",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
// and finally merge the whereAdd from the child..
if (!$obj->_query['condition']) {
return true;
}
$cond = preg_replace('/^\sWHERE/i','',$obj->_query['condition']);
$this->whereAdd("($cond)");
return true;
 
}
 
/**
* Copies items that are in the table definitions from an
* array or object into the current object
* will not override key values.
*
*
* @param array | object $from
* @param string $format eg. map xxxx_name to $object->name using 'xxxx_%s' (defaults to %s - eg. name -> $object->name
* @access public
* @return true on success or array of key=>setValue error message
*/
function setFrom(&$from, $format = '%s', $checkEmpty=false)
{
global $_DB_DATAOBJECT;
$keys = $this->keys();
$items = $this->table();
if (!$items) {
$this->raiseError(
"setFrom:Could not find table definition for {$this->__table}",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return;
}
$overload_return = array();
foreach (array_keys($items) as $k) {
if (in_array($k,$keys)) {
continue; // dont overwrite keys
}
if (!$k) {
continue; // ignore empty keys!!! what
}
if (is_object($from) && isset($from->{sprintf($format,$k)})) {
$kk = (strtolower($k) == 'from') ? '_from' : $k;
if (method_exists($this,'set'.$kk)) {
$ret = $this->{'set'.$kk}($from->{sprintf($format,$k)});
if (is_string($ret)) {
$overload_return[$k] = $ret;
}
continue;
}
$this->$k = $from->{sprintf($format,$k)};
continue;
}
if (is_object($from)) {
continue;
}
if (!isset($from[sprintf($format,$k)])) {
continue;
}
$kk = (strtolower($k) == 'from') ? '_from' : $k;
if (method_exists($this,'set'. $kk)) {
$ret = $this->{'set'.$kk}($from[sprintf($format,$k)]);
if (is_string($ret)) {
$overload_return[$k] = $ret;
}
continue;
}
if (is_object($from[sprintf($format,$k)])) {
continue;
}
if (is_array($from[sprintf($format,$k)])) {
continue;
}
$ret = $this->fromValue($k,$from[sprintf($format,$k)]);
if ($ret !== true) {
$overload_return[$k] = 'Not A Valid Value';
}
//$this->$k = $from[sprintf($format,$k)];
}
if ($overload_return) {
return $overload_return;
}
return true;
}
 
/**
* Returns an associative array from the current data
* (kind of oblivates the idea behind DataObjects, but
* is usefull if you use it with things like QuickForms.
*
* you can use the format to return things like user[key]
* by sending it $object->toArray('user[%s]')
*
* will also return links converted to arrays.
*
* @param string sprintf format for array
* @param bool empty only return elemnts that have a value set.
*
* @access public
* @return array of key => value for row
*/
 
function toArray($format = '%s', $hideEmpty = false)
{
global $_DB_DATAOBJECT;
$ret = array();
$ar = isset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid]) ?
array_merge($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid],$this->table()) :
$this->table();
 
foreach($ar as $k=>$v) {
if (!isset($this->$k)) {
if (!$hideEmpty) {
$ret[sprintf($format,$k)] = '';
}
continue;
}
// call the overloaded getXXXX() method. - except getLink and getLinks
if (method_exists($this,'get'.$k) && !in_array(strtolower($k),array('links','link'))) {
$ret[sprintf($format,$k)] = $this->{'get'.$k}();
continue;
}
// should this call toValue() ???
$ret[sprintf($format,$k)] = $this->$k;
}
if (!$this->_link_loaded) {
return $ret;
}
foreach($this->_link_loaded as $k) {
$ret[sprintf($format,$k)] = $this->$k->toArray();
}
return $ret;
}
 
/**
* validate - override this to set up your validation rules
*
* validate the current objects values either just testing strings/numbers or
* using the user defined validate{Row name}() methods.
* will attempt to call $this->validate{column_name}() - expects true = ok false = ERROR
* you can the use the validate Class from your own methods.
*
* This should really be in a extenal class - eg. DB_DataObject_Validate.
*
* @access public
* @return array of validation results or true
*/
function validate()
{
require_once 'Validate.php';
$table = $this->table();
$ret = array();
$seq = $this->sequenceKey();
foreach($table as $key => $val) {
// call user defined validation always...
$method = "Validate" . ucfirst($key);
if (method_exists($this, $method)) {
$ret[$key] = $this->$method();
continue;
}
// if not null - and it's not set.......
if (!isset($this->$key) && ($val & DB_DATAOBJECT_NOTNULL)) {
// dont check empty sequence key values..
if (($key == $seq[0]) && ($seq[1] == true)) {
continue;
}
$ret[$key] = false;
continue;
}
if (is_string($this->$key) && (strtolower($this->$key) == 'null') && ($val & DB_DATAOBJECT_NOTNULL)) {
$ret[$key] = false;
continue;
}
// ignore things that are not set. ?
if (!isset($this->$key)) {
continue;
}
// if the string is empty.. assume it is ok..
if (!is_object($this->$key) && !is_array($this->$key) && !strlen((string) $this->$key)) {
continue;
}
switch (true) {
// todo: date time.....
case ($val & DB_DATAOBJECT_STR):
$ret[$key] = Validate::string($this->$key, VALIDATE_PUNCTUATION . VALIDATE_NAME);
continue;
case ($val & DB_DATAOBJECT_INT):
$ret[$key] = Validate::number($this->$key, array('decimal'=>'.'));
continue;
}
}
 
foreach ($ret as $key => $val) {
if ($val === false) {
return $ret;
}
}
return true; // everything is OK.
}
 
/**
* Gets the DB object related to an object - so you can use funky peardb stuf with it :)
*
* @access public
* @return object The DB connection
*/
function &getDatabaseConnection()
{
global $_DB_DATAOBJECT;
 
if (($e = $this->_connect()) !== true) {
return $e;
}
if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
return false;
}
return $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
}
/**
* Gets the DB result object related to the objects active query
* - so you can use funky pear stuff with it - like pager for example.. :)
*
* @access public
* @return object The DB result object
*/
function &getDatabaseResult()
{
global $_DB_DATAOBJECT;
$this->_connect();
if (!isset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid])) {
return false;
}
return $_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid];
}
 
/**
* Overload Extension support
* - enables setCOLNAME/getCOLNAME
* if you define a set/get method for the item it will be called.
* otherwise it will just return/set the value.
* NOTE this currently means that a few Names are NO-NO's
* eg. links,link,linksarray, from, Databaseconnection,databaseresult
*
* note
* - set is automatically called by setFrom.
* - get is automatically called by toArray()
*
* setters return true on success. = strings on failure
* getters return the value!
*
* this fires off trigger_error - if any problems.. pear_error,
* has problems with 4.3.2RC2 here
*
* @access public
* @return true?
* @see overload
*/
 
function _call($method,$params,&$return) {
//$this->debug("ATTEMPTING OVERLOAD? $method");
// ignore constructors : - mm
if (strtolower($method) == strtolower(get_class($this))) {
return true;
}
$type = strtolower(substr($method,0,3));
$class = get_class($this);
if (($type != 'set') && ($type != 'get')) {
return false;
}
// deal with naming conflick of setFrom = this is messy ATM!
if (strtolower($method) == 'set_from') {
$return = $this->toValue('from',isset($params[0]) ? $params[0] : null);
return true;
}
$element = substr($method,3);
// dont you just love php's case insensitivity!!!!
$array = array_keys(get_class_vars($class));
/* php5 version which segfaults on 5.0.3 */
if (class_exists('ReflectionClass')) {
$reflection = new ReflectionClass($class);
$array = array_keys($reflection->getdefaultProperties());
}
if (!in_array($element,$array)) {
// munge case
foreach($array as $k) {
$case[strtolower($k)] = $k;
}
if ((substr(phpversion(),0,1) == 5) && isset($case[strtolower($element)])) {
trigger_error("PHP5 set/get calls should match the case of the variable",E_USER_WARNING);
$element = strtolower($element);
}
// does it really exist?
if (!isset($case[$element])) {
return false;
}
// use the mundged case
$element = $case[$element]; // real case !
}
if ($type == 'get') {
$return = $this->toValue($element,isset($params[0]) ? $params[0] : null);
return true;
}
$return = $this->fromValue($element, $params[0]);
return true;
}
/**
* standard set* implementation.
*
* takes data and uses it to set dates/strings etc.
* normally called from __call..
*
* Current supports
* date = using (standard time format, or unixtimestamp).... so you could create a method :
* function setLastread($string) { $this->fromValue('lastread',strtotime($string)); }
*
* time = using strtotime
* datetime = using same as date - accepts iso standard or unixtimestamp.
* string = typecast only..
*
* TODO: add formater:: eg. d/m/Y for date! ???
*
* @param string column of database
* @param mixed value to assign
*
* @return true| false (False on error)
* @access public
* @see DB_DataObject::_call
*/
function fromValue($col,$value)
{
$cols = $this->table();
// dont know anything about this col..
if (!isset($cols[$col])) {
$this->$col = $value;
return true;
}
//echo "FROM VALUE $col, {$cols[$col]}, $value\n";
switch (true) {
// set to null and column is can be null...
case ((strtolower($value) == 'null') && (!($cols[$col] & DB_DATAOBJECT_NOTNULL))):
case (is_object($value) && is_a($value,'DB_DataObject_Cast')):
$this->$col = $value;
return true;
// fail on setting null on a not null field..
case ((strtolower($value) == 'null') && ($cols[$col] & DB_DATAOBJECT_NOTNULL)):
return false;
case (($cols[$col] & DB_DATAOBJECT_DATE) && ($cols[$col] & DB_DATAOBJECT_TIME)):
// empty values get set to '' (which is inserted/updated as NULl
if (!$value) {
$this->$col = '';
}
if (is_numeric($value)) {
$this->$col = date('Y-m-d H:i:s', $value);
return true;
}
// eak... - no way to validate date time otherwise...
$this->$col = (string) $value;
return true;
case ($cols[$col] & DB_DATAOBJECT_DATE):
// empty values get set to '' (which is inserted/updated as NULl
if (!$value) {
$this->$col = '';
return true;
}
if (is_numeric($value)) {
$this->$col = date('Y-m-d',$value);
return true;
}
// try date!!!!
require_once 'Date.php';
$x = new Date($value);
$this->$col = $x->format("%Y-%m-%d");
return true;
case ($cols[$col] & DB_DATAOBJECT_TIME):
// empty values get set to '' (which is inserted/updated as NULl
if (!$value) {
$this->$col = '';
}
$guess = strtotime($value);
if ($guess != -1) {
$this->$col = date('H:i:s', $guess);
return $return = true;
}
// otherwise an error in type...
return false;
case ($cols[$col] & DB_DATAOBJECT_STR):
$this->$col = (string) $value;
return true;
// todo : floats numerics and ints...
default:
$this->$col = $value;
return true;
}
}
/**
* standard get* implementation.
*
* with formaters..
* supported formaters:
* date/time : %d/%m/%Y (eg. php strftime) or pear::Date
* numbers : %02d (eg. sprintf)
* NOTE you will get unexpected results with times like 0000-00-00 !!!
*
*
*
* @param string column of database
* @param format foramt
*
* @return true Description
* @access public
* @see DB_DataObject::_call(),strftime(),Date::format()
*/
function toValue($col,$format = null)
{
if (is_null($format)) {
return $this->$col;
}
$cols = $this->table();
switch (true) {
case (($cols[$col] & DB_DATAOBJECT_DATE) && ($cols[$col] & DB_DATAOBJECT_TIME)):
if (!$this->$col) {
return '';
}
$guess = strtotime($this->$col);
if ($guess != -1) {
return strftime($format, $guess);
}
// eak... - no way to validate date time otherwise...
return $this->$col;
case ($cols[$col] & DB_DATAOBJECT_DATE):
if (!$this->$col) {
return '';
}
$guess = strtotime($this->$col);
if ($guess != -1) {
return strftime($format,$guess);
}
// try date!!!!
require_once 'Date.php';
$x = new Date($this->$col);
return $x->format($format);
case ($cols[$col] & DB_DATAOBJECT_TIME):
if (!$this->$col) {
return '';
}
$guess = strtotime($this->$col);
if ($guess > -1) {
return strftime($format, $guess);
}
// otherwise an error in type...
return $this->$col;
case ($cols[$col] & DB_DATAOBJECT_MYSQLTIMESTAMP):
if (!$this->$col) {
return '';
}
require_once 'Date.php';
$x = new Date($this->$col);
return $x->format($format);
case ($cols[$col] & DB_DATAOBJECT_BOOLEAN):
if ($cols[$col] & DB_DATAOBJECT_STR) {
// it's a 't'/'f' !
return ($cols[$col] == 't');
}
return (bool) $cols[$col];
default:
return sprintf($format,$this->col);
}
 
}
/* ----------------------- Debugger ------------------ */
 
/**
* Debugger. - use this in your extended classes to output debugging information.
*
* Uses DB_DataObject::DebugLevel(x) to turn it on
*
* @param string $message - message to output
* @param string $logtype - bold at start
* @param string $level - output level
* @access public
* @return none
*/
function debug($message, $logtype = 0, $level = 1)
{
global $_DB_DATAOBJECT;
 
if (empty($_DB_DATAOBJECT['CONFIG']['debug']) ||
(is_numeric($_DB_DATAOBJECT['CONFIG']['debug']) && $_DB_DATAOBJECT['CONFIG']['debug'] < $level)) {
return;
}
// this is a bit flaky due to php's wonderfull class passing around crap..
// but it's about as good as it gets..
$class = (isset($this) && is_a($this,'DB_DataObject')) ? get_class($this) : 'DB_DataObject';
if (!is_string($message)) {
$message = print_r($message,true);
}
if (!is_numeric( $_DB_DATAOBJECT['CONFIG']['debug']) && is_callable( $_DB_DATAOBJECT['CONFIG']['debug'])) {
return call_user_func($_DB_DATAOBJECT['CONFIG']['debug'], $class, $message, $logtype, $level);
}
if (!ini_get('html_errors')) {
echo "$class : $logtype : $message\n";
flush();
return;
}
if (!is_string($message)) {
$message = print_r($message,true);
}
echo "<code><B>$class: $logtype:</B> $message</code><BR>\n";
flush();
}
 
/**
* sets and returns debug level
* eg. DB_DataObject::debugLevel(4);
*
* @param int $v level
* @access public
* @return none
*/
function debugLevel($v = null)
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
if ($v !== null) {
$r = isset($_DB_DATAOBJECT['CONFIG']['debug']) ? $_DB_DATAOBJECT['CONFIG']['debug'] : 0;
$_DB_DATAOBJECT['CONFIG']['debug'] = $v;
return $r;
}
return isset($_DB_DATAOBJECT['CONFIG']['debug']) ? $_DB_DATAOBJECT['CONFIG']['debug'] : 0;
}
 
/**
* Last Error that has occured
* - use $this->_lastError or
* $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
*
* @access public
* @var object PEAR_Error (or false)
*/
var $_lastError = false;
 
/**
* Default error handling is to create a pear error, but never return it.
* if you need to handle errors you should look at setting the PEAR_Error callback
* this is due to the fact it would wreck havoc on the internal methods!
*
* @param int $message message
* @param int $type type
* @param int $behaviour behaviour (die or continue!);
* @access public
* @return error object
*/
function raiseError($message, $type = null, $behaviour = null)
{
global $_DB_DATAOBJECT;
if ($behaviour == PEAR_ERROR_DIE && !empty($_DB_DATAOBJECT['CONFIG']['dont_die'])) {
$behaviour = null;
}
$error = &PEAR::getStaticProperty('DB_DataObject','lastError');
if (PEAR::isError($message)) {
$error = $message;
} else {
require_once 'DB/DataObject/Error.php';
$error = PEAR::raiseError($message, $type, $behaviour,
$opts=null, $userinfo=null, 'DB_DataObject_Error'
);
}
// this will never work totally with PHP's object model.
// as this is passed on static calls (like staticGet in our case)
 
if (isset($this) && is_object($this) && is_subclass_of($this,'db_dataobject')) {
$this->_lastError = $error;
}
 
$_DB_DATAOBJECT['LASTERROR'] = $error;
 
// no checks for production here?.......
DB_DataObject::debug($message,"ERROR",1);
return $error;
}
 
/**
* Define the global $_DB_DATAOBJECT['CONFIG'] as an alias to PEAR::getStaticProperty('DB_DataObject','options');
*
* After Profiling DB_DataObject, I discoved that the debug calls where taking
* considerable time (well 0.1 ms), so this should stop those calls happening. as
* all calls to debug are wrapped with direct variable queries rather than actually calling the funciton
* THIS STILL NEEDS FURTHER INVESTIGATION
*
* @access public
* @return object an error object
*/
function _loadConfig()
{
global $_DB_DATAOBJECT;
 
$_DB_DATAOBJECT['CONFIG'] = &PEAR::getStaticProperty('DB_DataObject','options');
 
 
}
/**
* Free global arrays associated with this object.
*
* Note: as we now store resultfields in a global, it is never freed, if you do alot of calls to find(),
* memory will grow gradually.
*
*
* @access public
* @return none
*/
function free()
{
global $_DB_DATAOBJECT;
if (isset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid])) {
unset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid]);
}
if (isset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid])) {
unset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]);
}
// this is a huge bug in DB!
if (isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->num_rows = array();
}
}
/* ---- LEGACY BC METHODS - NOT DOCUMENTED - See Documentation on New Methods. ---*/
function _get_table() { return $this->table(); }
function _get_keys() { return $this->keys(); }
}
// technially 4.3.2RC1 was broken!!
// looks like 4.3.3 may have problems too....
if (!defined('DB_DATAOBJECT_NO_OVERLOAD')) {
 
if ((phpversion() != '4.3.2-RC1') && (version_compare( phpversion(), "4.3.1") > 0)) {
if (version_compare( phpversion(), "5") < 0) {
overload('DB_DataObject');
}
$GLOBALS['_DB_DATAOBJECT']['OVERLOADED'] = true;
}
}
 
/tags/v1.0-Homere/bibliotheque/pear/DB/sqlite.php
New file
0,0 → 1,942
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's sqlite extension
* for interacting with SQLite databases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Urs Gehrig <urs@circle.ch>
* @author Mika Tuupola <tuupola@appelsiini.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
* @version CVS: $Id: sqlite.php,v 1.109 2005/03/10 01:22:48 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's sqlite extension
* for interacting with SQLite databases
*
* These methods overload the ones declared in DB_common.
*
* NOTICE: This driver needs PHP's track_errors ini setting to be on.
* It is automatically turned on when connecting to the database.
* Make sure your scripts don't turn it off.
*
* @category Database
* @package DB
* @author Urs Gehrig <urs@circle.ch>
* @author Mika Tuupola <tuupola@appelsiini.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_sqlite extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'sqlite';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'sqlite';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => 'alter',
'new_link' => false,
'numrows' => true,
'pconnect' => true,
'prepare' => false,
'ssl' => false,
'transactions' => false,
);
 
/**
* A mapping of native error codes to DB error codes
*
* {@internal Error codes according to sqlite_exec. See the online
* manual at http://sqlite.org/c_interface.html for info.
* This error handling based on sqlite_exec is not yet implemented.}}
*
* @var array
*/
var $errorcode_map = array(
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* SQLite data types
*
* @link http://www.sqlite.org/datatypes.html
*
* @var array
*/
var $keywords = array (
'BLOB' => '',
'BOOLEAN' => '',
'CHARACTER' => '',
'CLOB' => '',
'FLOAT' => '',
'INTEGER' => '',
'KEY' => '',
'NATIONAL' => '',
'NUMERIC' => '',
'NVARCHAR' => '',
'PRIMARY' => '',
'TEXT' => '',
'TIMESTAMP' => '',
'UNIQUE' => '',
'VARCHAR' => '',
'VARYING' => '',
);
 
/**
* The most recent error message from $php_errormsg
* @var string
* @access private
*/
var $_lasterror = '';
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_sqlite()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* PEAR DB's sqlite driver supports the following extra DSN options:
* + mode The permissions for the database file, in four digit
* chmod octal format (eg "0600").
*
* Example of connecting to a database in read-only mode:
* <code>
* require_once 'DB.php';
*
* $dsn = 'sqlite:///path/and/name/of/db/file?mode=0400';
* $options = array(
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
* </code>
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('sqlite')) {
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
if ($dsn['database']) {
if (!file_exists($dsn['database'])) {
if (!touch($dsn['database'])) {
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
}
if (!isset($dsn['mode']) ||
!is_numeric($dsn['mode']))
{
$mode = 0644;
} else {
$mode = octdec($dsn['mode']);
}
if (!chmod($dsn['database'], $mode)) {
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
}
if (!file_exists($dsn['database'])) {
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
}
}
if (!is_file($dsn['database'])) {
return $this->sqliteRaiseError(DB_ERROR_INVALID);
}
if (!is_readable($dsn['database'])) {
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
}
} else {
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
}
 
$connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open';
 
// track_errors must remain on for simpleQuery()
ini_set('track_errors', 1);
$php_errormsg = '';
 
if (!$this->connection = @$connect_function($dsn['database'])) {
return $this->raiseError(DB_ERROR_NODBSELECTED,
null, null, null,
$php_errormsg);
}
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @sqlite_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* NOTICE: This method needs PHP's track_errors ini setting to be on.
* It is automatically turned on when connecting to the database.
* Make sure your scripts don't turn it off.
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
 
$php_errormsg = '';
 
$result = @sqlite_query($query, $this->connection);
$this->_lasterror = $php_errormsg ? $php_errormsg : '';
 
$this->result = $result;
if (!$this->result) {
return $this->sqliteRaiseError(null);
}
 
// sqlite_query() seems to allways return a resource
// so cant use that. Using $ismanip instead
if (!$ismanip) {
$numRows = $this->numRows($result);
if (is_object($numRows)) {
// we've got PEAR_Error
return $numRows;
}
return $result;
}
return DB_OK;
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal sqlite result pointer to the next available result
*
* @param resource $result the valid sqlite result resource
*
* @return bool true if a result is available otherwise return false
*/
function nextResult($result)
{
return false;
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@sqlite_seek($this->result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @sqlite_fetch_array($result, SQLITE_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @sqlite_fetch_array($result, SQLITE_NUM);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
/*
* Even though this DBMS already trims output, we do this because
* a field might have intentional whitespace at the end that
* gets removed by DB_PORTABILITY_RTRIM under another driver.
*/
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult(&$result)
{
// XXX No native free?
if (!is_resource($result)) {
return false;
}
$result = null;
return true;
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @sqlite_num_fields($result);
if (!$cols) {
return $this->sqliteRaiseError();
}
return $cols;
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
function numRows($result)
{
$rows = @sqlite_num_rows($result);
if ($rows === null) {
return $this->sqliteRaiseError();
}
return $rows;
}
 
// }}}
// {{{ affected()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
return @sqlite_changes($this->connection);
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_sqlite::nextID(), DB_sqlite::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
 
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_sqlite::nextID(), DB_sqlite::dropSequence()
*/
function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$query = 'CREATE TABLE ' . $seqname .
' (id INTEGER UNSIGNED PRIMARY KEY) ';
$result = $this->query($query);
if (DB::isError($result)) {
return($result);
}
$query = "CREATE TRIGGER ${seqname}_cleanup AFTER INSERT ON $seqname
BEGIN
DELETE FROM $seqname WHERE id<LAST_INSERT_ROWID();
END ";
$result = $this->query($query);
if (DB::isError($result)) {
return($result);
}
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_sqlite::createSequence(), DB_sqlite::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
 
do {
$repeat = 0;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("INSERT INTO $seqname (id) VALUES (NULL)");
$this->popErrorHandling();
if ($result === DB_OK) {
$id = @sqlite_last_insert_rowid($this->connection);
if ($id != 0) {
return $id;
}
} elseif ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE)
{
$result = $this->createSequence($seq_name);
if (DB::isError($result)) {
return $this->raiseError($result);
} else {
$repeat = 1;
}
}
} while ($repeat);
 
return $this->raiseError($result);
}
 
// }}}
// {{{ getDbFileStats()
 
/**
* Get the file stats for the current database
*
* Possible arguments are dev, ino, mode, nlink, uid, gid, rdev, size,
* atime, mtime, ctime, blksize, blocks or a numeric key between
* 0 and 12.
*
* @param string $arg the array key for stats()
*
* @return mixed an array on an unspecified key, integer on a passed
* arg and false at a stats error
*/
function getDbFileStats($arg = '')
{
$stats = stat($this->dsn['database']);
if ($stats == false) {
return false;
}
if (is_array($stats)) {
if (is_numeric($arg)) {
if (((int)$arg <= 12) & ((int)$arg >= 0)) {
return false;
}
return $stats[$arg ];
}
if (array_key_exists(trim($arg), $stats)) {
return $stats[$arg ];
}
}
return $stats;
}
 
// }}}
// {{{ escapeSimple()
 
/**
* Escapes a string according to the current DBMS's standards
*
* In SQLite, this makes things safe for inserts/updates, but may
* cause problems when performing text comparisons against columns
* containing binary data. See the
* {@link http://php.net/sqlite_escape_string PHP manual} for more info.
*
* @param string $str the string to be escaped
*
* @return string the escaped string
*
* @since Method available since Release 1.6.1
* @see DB_common::escapeSimple()
*/
function escapeSimple($str)
{
return @sqlite_escape_string($str);
}
 
// }}}
// {{{ modifyLimitQuery()
 
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
return "$query LIMIT $count OFFSET $from";
}
 
// }}}
// {{{ modifyQuery()
 
/**
* Changes a query string for various DBMS specific reasons
*
* This little hack lets you know how many rows were deleted
* when running a "DELETE FROM table" query. Only implemented
* if the DB_PORTABILITY_DELETE_COUNT portability option is on.
*
* @param string $query the query string to modify
*
* @return string the modified query string
*
* @access protected
* @see DB_common::setOption()
*/
function modifyQuery($query)
{
if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) {
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
'DELETE FROM \1 WHERE 1=1', $query);
}
}
return $query;
}
 
// }}}
// {{{ sqliteRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_sqlite::errorNative(), DB_sqlite::errorCode()
*/
function sqliteRaiseError($errno = null)
{
$native = $this->errorNative();
if ($errno === null) {
$errno = $this->errorCode($native);
}
 
$errorcode = @sqlite_last_error($this->connection);
$userinfo = "$errorcode ** $this->last_query";
 
return $this->raiseError($errno, null, null, $userinfo, $native);
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error message produced by the last query
*
* {@internal This is used to retrieve more meaningfull error messages
* because sqlite_last_error() does not provide adequate info.}}
*
* @return string the DBMS' error message
*/
function errorNative()
{
return $this->_lasterror;
}
 
// }}}
// {{{ errorCode()
 
/**
* Determines PEAR::DB error code from the database's text error message
*
* @param string $errormsg the error message returned from the database
*
* @return integer the DB error number
*/
function errorCode($errormsg)
{
static $error_regexps;
if (!isset($error_regexps)) {
$error_regexps = array(
'/^no such table:/' => DB_ERROR_NOSUCHTABLE,
'/^no such index:/' => DB_ERROR_NOT_FOUND,
'/^(table|index) .* already exists$/' => DB_ERROR_ALREADY_EXISTS,
'/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT,
'/is not unique/' => DB_ERROR_CONSTRAINT,
'/columns .* are not unique/i' => DB_ERROR_CONSTRAINT,
'/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT,
'/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL,
'/^no such column:/' => DB_ERROR_NOSUCHFIELD,
'/column not present in both tables/i' => DB_ERROR_NOSUCHFIELD,
'/^near ".*": syntax error$/' => DB_ERROR_SYNTAX,
'/[0-9]+ values for [0-9]+ columns/i' => DB_ERROR_VALUE_COUNT_ON_ROW,
);
}
foreach ($error_regexps as $regexp => $code) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
}
// Fall back to DB_ERROR if there was no mapping.
return DB_ERROR;
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table
*
* @param string $result a string containing the name of a table
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
* @since Method available since Release 1.7.0
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @sqlite_array_query($this->connection,
"PRAGMA table_info('$result');",
SQLITE_ASSOC);
$got_string = true;
} else {
$this->last_query = '';
return $this->raiseError(DB_ERROR_NOT_CAPABLE, null, null, null,
'This DBMS can not obtain tableInfo' .
' from result sets');
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$count = count($id);
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
if (strpos($id[$i]['type'], '(') !== false) {
$bits = explode('(', $id[$i]['type']);
$type = $bits[0];
$len = rtrim($bits[1],')');
} else {
$type = $id[$i]['type'];
$len = 0;
}
 
$flags = '';
if ($id[$i]['pk']) {
$flags .= 'primary_key ';
}
if ($id[$i]['notnull']) {
$flags .= 'not_null ';
}
if ($id[$i]['dflt_value'] !== null) {
$flags .= 'default_' . rawurlencode($id[$i]['dflt_value']);
}
$flags = trim($flags);
 
$res[$i] = array(
'table' => $case_func($result),
'name' => $case_func($id[$i]['name']),
'type' => $type,
'len' => $len,
'flags' => $flags,
);
 
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
return $res;
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
* @param array $args SQLITE DRIVER ONLY: a private array of arguments
* used by the getSpecialQuery(). Do not use
* this directly.
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type, $args = array())
{
if (!is_array($args)) {
return $this->raiseError('no key specified', null, null, null,
'Argument has to be an array.');
}
 
switch ($type) {
case 'master':
return 'SELECT * FROM sqlite_master;';
case 'tables':
return "SELECT name FROM sqlite_master WHERE type='table' "
. 'UNION ALL SELECT name FROM sqlite_temp_master '
. "WHERE type='table' ORDER BY name;";
case 'schema':
return 'SELECT sql FROM (SELECT * FROM sqlite_master '
. 'UNION ALL SELECT * FROM sqlite_temp_master) '
. "WHERE type!='meta' "
. 'ORDER BY tbl_name, type DESC, name;';
case 'schemax':
case 'schema_x':
/*
* Use like:
* $res = $db->query($db->getSpecialQuery('schema_x',
* array('table' => 'table3')));
*/
return 'SELECT sql FROM (SELECT * FROM sqlite_master '
. 'UNION ALL SELECT * FROM sqlite_temp_master) '
. "WHERE tbl_name LIKE '{$args['table']}' "
. "AND type!='meta' "
. 'ORDER BY type DESC, name;';
case 'alter':
/*
* SQLite does not support ALTER TABLE; this is a helper query
* to handle this. 'table' represents the table name, 'rows'
* the news rows to create, 'save' the row(s) to keep _with_
* the data.
*
* Use like:
* $args = array(
* 'table' => $table,
* 'rows' => "id INTEGER PRIMARY KEY, firstname TEXT, surname TEXT, datetime TEXT",
* 'save' => "NULL, titel, content, datetime"
* );
* $res = $db->query( $db->getSpecialQuery('alter', $args));
*/
$rows = strtr($args['rows'], $this->keywords);
 
$q = array(
'BEGIN TRANSACTION',
"CREATE TEMPORARY TABLE {$args['table']}_backup ({$args['rows']})",
"INSERT INTO {$args['table']}_backup SELECT {$args['save']} FROM {$args['table']}",
"DROP TABLE {$args['table']}",
"CREATE TABLE {$args['table']} ({$args['rows']})",
"INSERT INTO {$args['table']} SELECT {$rows} FROM {$args['table']}_backup",
"DROP TABLE {$args['table']}_backup",
'COMMIT',
);
 
/*
* This is a dirty hack, since the above query will not get
* executed with a single query call so here the query method
* will be called directly and return a select instead.
*/
foreach ($q as $query) {
$this->query($query);
}
return "SELECT * FROM {$args['table']};";
default:
return null;
}
}
 
// }}}
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/oci8.php
New file
0,0 → 1,1117
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's oci8 extension
* for interacting with Oracle databases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author James L. Pine <jlp@valinux.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: oci8.php,v 1.103 2005/04/11 15:10:22 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's oci8 extension
* for interacting with Oracle databases
*
* Definitely works with versions 8 and 9 of Oracle.
*
* These methods overload the ones declared in DB_common.
*
* Be aware... OCIError() only appears to return anything when given a
* statement, so functions return the generic DB_ERROR instead of more
* useful errors that have to do with feedback from the database.
*
* @category Database
* @package DB
* @author James L. Pine <jlp@valinux.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_oci8 extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'oci8';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'oci8';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => 'alter',
'new_link' => '5.0.0',
'numrows' => 'subquery',
'pconnect' => true,
'prepare' => true,
'ssl' => false,
'transactions' => true,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
1 => DB_ERROR_CONSTRAINT,
900 => DB_ERROR_SYNTAX,
904 => DB_ERROR_NOSUCHFIELD,
913 => DB_ERROR_VALUE_COUNT_ON_ROW,
921 => DB_ERROR_SYNTAX,
923 => DB_ERROR_SYNTAX,
942 => DB_ERROR_NOSUCHTABLE,
955 => DB_ERROR_ALREADY_EXISTS,
1400 => DB_ERROR_CONSTRAINT_NOT_NULL,
1401 => DB_ERROR_INVALID,
1407 => DB_ERROR_CONSTRAINT_NOT_NULL,
1418 => DB_ERROR_NOT_FOUND,
1476 => DB_ERROR_DIVZERO,
1722 => DB_ERROR_INVALID_NUMBER,
2289 => DB_ERROR_NOSUCHTABLE,
2291 => DB_ERROR_CONSTRAINT,
2292 => DB_ERROR_CONSTRAINT,
2449 => DB_ERROR_CONSTRAINT,
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* Should data manipulation queries be committed automatically?
* @var bool
* @access private
*/
var $autocommit = true;
 
/**
* Stores the $data passed to execute() in the oci8 driver
*
* Gets reset to array() when simpleQuery() is run.
*
* Needed in case user wants to call numRows() after prepare/execute
* was used.
*
* @var array
* @access private
*/
var $_data = array();
 
/**
* The result or statement handle from the most recently executed query
* @var resource
*/
var $last_stmt;
 
/**
* Is the given prepared statement a data manipulation query?
* @var array
* @access private
*/
var $manip_query = array();
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_oci8()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* If PHP is at version 5.0.0 or greater:
* + Generally, oci_connect() or oci_pconnect() are used.
* + But if the new_link DSN option is set to true, oci_new_connect()
* is used.
*
* When using PHP version 4.x, OCILogon() or OCIPLogon() are used.
*
* PEAR DB's oci8 driver supports the following extra DSN options:
* + charset The character set to be used on the connection.
* Only used if PHP is at version 5.0.0 or greater
* and the Oracle server is at 9.2 or greater.
* Available since PEAR DB 1.7.0.
* + new_link If set to true, causes subsequent calls to
* connect() to return a new connection link
* instead of the existing one. WARNING: this is
* not portable to other DBMS's.
* Available since PEAR DB 1.7.0.
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('oci8')) {
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
if (function_exists('oci_connect')) {
if (isset($dsn['new_link'])
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true))
{
$connect_function = 'oci_new_connect';
} else {
$connect_function = $persistent ? 'oci_pconnect'
: 'oci_connect';
}
 
// Backwards compatibility with DB < 1.7.0
if (empty($dsn['database']) && !empty($dsn['hostspec'])) {
$db = $dsn['hostspec'];
} else {
$db = $dsn['database'];
}
 
$char = empty($dsn['charset']) ? null : $dsn['charset'];
$this->connection = @$connect_function($dsn['username'],
$dsn['password'],
$db,
$char);
$error = OCIError();
if (!empty($error) && $error['code'] == 12541) {
// Couldn't find TNS listener. Try direct connection.
$this->connection = @$connect_function($dsn['username'],
$dsn['password'],
null,
$char);
}
} else {
$connect_function = $persistent ? 'OCIPLogon' : 'OCILogon';
if ($dsn['hostspec']) {
$this->connection = @$connect_function($dsn['username'],
$dsn['password'],
$dsn['hostspec']);
} elseif ($dsn['username'] || $dsn['password']) {
$this->connection = @$connect_function($dsn['username'],
$dsn['password']);
}
}
 
if (!$this->connection) {
$error = OCIError();
$error = (is_array($error)) ? $error['message'] : null;
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$error);
}
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
if (function_exists('oci_close')) {
$ret = @oci_close($this->connection);
} else {
$ret = @OCILogOff($this->connection);
}
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* To determine how many rows of a result set get buffered using
* ocisetprefetch(), see the "result_buffering" option in setOptions().
* This option was added in Release 1.7.0.
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$this->_data = array();
$this->last_parameters = array();
$this->last_query = $query;
$query = $this->modifyQuery($query);
$result = @OCIParse($this->connection, $query);
if (!$result) {
return $this->oci8RaiseError();
}
if ($this->autocommit) {
$success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS);
} else {
$success = @OCIExecute($result,OCI_DEFAULT);
}
if (!$success) {
return $this->oci8RaiseError($result);
}
$this->last_stmt = $result;
if (DB::isManip($query)) {
return DB_OK;
} else {
@ocisetprefetch($result, $this->options['result_buffering']);
return $result;
}
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal oracle result pointer to the next available result
*
* @param a valid oci8 result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
function nextResult($result)
{
return false;
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE &&
$moredata)
{
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS);
}
if (!$moredata) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return @OCIFreeStatement($result);
}
 
/**
* Frees the internal resources associated with a prepared query
*
* @param resource $stmt the prepared statement's resource
* @param bool $free_resource should the PHP resource be freed too?
* Use false if you need to get data
* from the result set later.
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_oci8::prepare()
*/
function freePrepared($stmt, $free_resource = true)
{
if (!is_resource($stmt)) {
return false;
}
if ($free_resource) {
@ocifreestatement($stmt);
}
if (isset($this->prepare_types[(int)$stmt])) {
unset($this->prepare_types[(int)$stmt]);
unset($this->manip_query[(int)$stmt]);
} else {
return false;
}
return true;
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* Only works if the DB_PORTABILITY_NUMROWS portability option
* is turned on.
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows(), DB_common::setOption()
*/
function numRows($result)
{
// emulate numRows for Oracle. yuck.
if ($this->options['portability'] & DB_PORTABILITY_NUMROWS &&
$result === $this->last_stmt)
{
$countquery = 'SELECT COUNT(*) FROM ('.$this->last_query.')';
$save_query = $this->last_query;
$save_stmt = $this->last_stmt;
 
if (count($this->_data)) {
$smt = $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')');
$count = $this->execute($smt, $this->_data);
} else {
$count =& $this->query($countquery);
}
 
if (DB::isError($count) ||
DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED)))
{
$this->last_query = $save_query;
$this->last_stmt = $save_stmt;
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
return $row[0];
}
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @OCINumCols($result);
if (!$cols) {
return $this->oci8RaiseError($result);
}
return $cols;
}
 
// }}}
// {{{ prepare()
 
/**
* Prepares a query for multiple execution with execute().
*
* With oci8, this is emulated.
*
* prepare() requires a generic query as string like <code>
* INSERT INTO numbers VALUES (?, ?, ?)
* </code>. The <kbd>?</kbd> characters are placeholders.
*
* Three types of placeholders can be used:
* + <kbd>?</kbd> a quoted scalar value, i.e. strings, integers
* + <kbd>!</kbd> value is inserted 'as is'
* + <kbd>&</kbd> requires a file name. The file's contents get
* inserted into the query (i.e. saving binary
* data in a db)
*
* Use backslashes to escape placeholder characters if you don't want
* them to be interpreted as placeholders. Example: <code>
* "UPDATE foo SET col=? WHERE col='over \& under'"
* </code>
*
* @param string $query the query to be prepared
*
* @return mixed DB statement resource on success. DB_Error on failure.
*
* @see DB_oci8::execute()
*/
function prepare($query)
{
$tokens = preg_split('/((?<!\\\)[&?!])/', $query, -1,
PREG_SPLIT_DELIM_CAPTURE);
$binds = count($tokens) - 1;
$token = 0;
$types = array();
$newquery = '';
 
foreach ($tokens as $key => $val) {
switch ($val) {
case '?':
$types[$token++] = DB_PARAM_SCALAR;
unset($tokens[$key]);
break;
case '&':
$types[$token++] = DB_PARAM_OPAQUE;
unset($tokens[$key]);
break;
case '!':
$types[$token++] = DB_PARAM_MISC;
unset($tokens[$key]);
break;
default:
$tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val);
if ($key != $binds) {
$newquery .= $tokens[$key] . ':bind' . $token;
} else {
$newquery .= $tokens[$key];
}
}
}
 
$this->last_query = $query;
$newquery = $this->modifyQuery($newquery);
if (!$stmt = @OCIParse($this->connection, $newquery)) {
return $this->oci8RaiseError();
}
$this->prepare_types[(int)$stmt] = $types;
$this->manip_query[(int)$stmt] = DB::isManip($query);
return $stmt;
}
 
// }}}
// {{{ execute()
 
/**
* Executes a DB statement prepared with prepare().
*
* To determine how many rows of a result set get buffered using
* ocisetprefetch(), see the "result_buffering" option in setOptions().
* This option was added in Release 1.7.0.
*
* @param resource $stmt a DB statement resource returned from prepare()
* @param mixed $data array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 for non-array items or the
* quantity of elements in the array.
*
* @return mixed returns an oic8 result resource for successful SELECT
* queries, DB_OK for other successful queries.
* A DB error object is returned on failure.
*
* @see DB_oci8::prepare()
*/
function &execute($stmt, $data = array())
{
$data = (array)$data;
$this->last_parameters = $data;
$this->_data = $data;
 
$types =& $this->prepare_types[(int)$stmt];
if (count($types) != count($data)) {
$tmp =& $this->raiseError(DB_ERROR_MISMATCH);
return $tmp;
}
 
$i = 0;
foreach ($data as $key => $value) {
if ($types[$i] == DB_PARAM_MISC) {
/*
* Oracle doesn't seem to have the ability to pass a
* parameter along unchanged, so strip off quotes from start
* and end, plus turn two single quotes to one single quote,
* in order to avoid the quotes getting escaped by
* Oracle and ending up in the database.
*/
$data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]);
$data[$key] = str_replace("''", "'", $data[$key]);
} elseif ($types[$i] == DB_PARAM_OPAQUE) {
$fp = @fopen($data[$key], 'rb');
if (!$fp) {
$tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
return $tmp;
}
$data[$key] = fread($fp, filesize($data[$key]));
fclose($fp);
}
if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) {
$tmp = $this->oci8RaiseError($stmt);
return $tmp;
}
$i++;
}
if ($this->autocommit) {
$success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS);
} else {
$success = @OCIExecute($stmt, OCI_DEFAULT);
}
if (!$success) {
$tmp = $this->oci8RaiseError($stmt);
return $tmp;
}
$this->last_stmt = $stmt;
if ($this->manip_query[(int)$stmt]) {
$tmp = DB_OK;
} else {
@ocisetprefetch($stmt, $this->options['result_buffering']);
$tmp =& new DB_result($this, $stmt);
}
return $tmp;
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff = false)
{
$this->autocommit = (bool)$onoff;;
return DB_OK;
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
$result = @OCICommit($this->connection);
if (!$result) {
return $this->oci8RaiseError();
}
return DB_OK;
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
$result = @OCIRollback($this->connection);
if (!$result) {
return $this->oci8RaiseError();
}
return DB_OK;
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
if ($this->last_stmt === false) {
return $this->oci8RaiseError();
}
$result = @OCIRowCount($this->last_stmt);
if ($result === false) {
return $this->oci8RaiseError($this->last_stmt);
}
return $result;
}
 
// }}}
// {{{ modifyQuery()
 
/**
* Changes a query string for various DBMS specific reasons
*
* "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle.
*
* @param string $query the query string to modify
*
* @return string the modified query string
*
* @access protected
*/
function modifyQuery($query)
{
if (preg_match('/^\s*SELECT/i', $query) &&
!preg_match('/\sFROM\s/i', $query)) {
$query .= ' FROM dual';
}
return $query;
}
 
// }}}
// {{{ modifyLimitQuery()
 
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
// Let Oracle return the name of the columns instead of
// coding a "home" SQL parser
 
if (count($params)) {
$result = $this->prepare("SELECT * FROM ($query) "
. 'WHERE NULL = NULL');
$tmp =& $this->execute($result, $params);
} else {
$q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
 
if (!$result = @OCIParse($this->connection, $q_fields)) {
$this->last_query = $q_fields;
return $this->oci8RaiseError();
}
if (!@OCIExecute($result, OCI_DEFAULT)) {
$this->last_query = $q_fields;
return $this->oci8RaiseError($result);
}
}
 
$ncols = OCINumCols($result);
$cols = array();
for ( $i = 1; $i <= $ncols; $i++ ) {
$cols[] = '"' . OCIColumnName($result, $i) . '"';
}
$fields = implode(', ', $cols);
// XXX Test that (tip by John Lim)
//if (preg_match('/^\s*SELECT\s+/is', $query, $match)) {
// // Introduce the FIRST_ROWS Oracle query optimizer
// $query = substr($query, strlen($match[0]), strlen($query));
// $query = "SELECT /* +FIRST_ROWS */ " . $query;
//}
 
// Construct the query
// more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2
// Perhaps this could be optimized with the use of Unions
$query = "SELECT $fields FROM".
" (SELECT rownum as linenum, $fields FROM".
" ($query)".
' WHERE rownum <= '. ($from + $count) .
') WHERE linenum >= ' . ++$from;
return $query;
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_oci8::createSequence(), DB_oci8::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
$repeat = 0;
do {
$this->expectError(DB_ERROR_NOSUCHTABLE);
$result =& $this->query("SELECT ${seqname}.nextval FROM dual");
$this->popExpect();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = 1;
$result = $this->createSequence($seq_name);
if (DB::isError($result)) {
return $this->raiseError($result);
}
} else {
$repeat = 0;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
return $arr[0];
}
 
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_oci8::nextID(), DB_oci8::dropSequence()
*/
function createSequence($seq_name)
{
return $this->query('CREATE SEQUENCE '
. $this->getSequenceName($seq_name));
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_oci8::nextID(), DB_oci8::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DROP SEQUENCE '
. $this->getSequenceName($seq_name));
}
 
// }}}
// {{{ oci8RaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_oci8::errorNative(), DB_oci8::errorCode()
*/
function oci8RaiseError($errno = null)
{
if ($errno === null) {
$error = @OCIError($this->connection);
return $this->raiseError($this->errorCode($error['code']),
null, null, null, $error['message']);
} elseif (is_resource($errno)) {
$error = @OCIError($errno);
return $this->raiseError($this->errorCode($error['code']),
null, null, null, $error['message']);
}
return $this->raiseError($this->errorCode($errno));
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error code produced by the last query
*
* @return int the DBMS' error code. FALSE if the code could not be
* determined
*/
function errorNative()
{
if (is_resource($this->last_stmt)) {
$error = @OCIError($this->last_stmt);
} else {
$error = @OCIError($this->connection);
}
if (is_array($error)) {
return $error['code'];
}
return false;
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
* is a table name.
*
* NOTE: flags won't contain index information.
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
*/
function tableInfo($result, $mode = null)
{
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$res = array();
 
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$result = strtoupper($result);
$q_fields = 'SELECT column_name, data_type, data_length, '
. 'nullable '
. 'FROM user_tab_columns '
. "WHERE table_name='$result' ORDER BY column_id";
 
$this->last_query = $q_fields;
 
if (!$stmt = @OCIParse($this->connection, $q_fields)) {
return $this->oci8RaiseError(DB_ERROR_NEED_MORE_DATA);
}
if (!@OCIExecute($stmt, OCI_DEFAULT)) {
return $this->oci8RaiseError($stmt);
}
 
$i = 0;
while (@OCIFetch($stmt)) {
$res[$i] = array(
'table' => $case_func($result),
'name' => $case_func(@OCIResult($stmt, 1)),
'type' => @OCIResult($stmt, 2),
'len' => @OCIResult($stmt, 3),
'flags' => (@OCIResult($stmt, 4) == 'N') ? 'not_null' : '',
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
$i++;
}
 
if ($mode) {
$res['num_fields'] = $i;
}
@OCIFreeStatement($stmt);
 
} else {
if (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$result = $result->result;
}
 
$res = array();
 
if ($result === $this->last_stmt) {
$count = @OCINumCols($result);
if ($mode) {
$res['num_fields'] = $count;
}
for ($i = 0; $i < $count; $i++) {
$res[$i] = array(
'table' => '',
'name' => $case_func(@OCIColumnName($result, $i+1)),
'type' => @OCIColumnType($result, $i+1),
'len' => @OCIColumnSize($result, $i+1),
'flags' => '',
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
} else {
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
}
return $res;
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'tables':
return 'SELECT table_name FROM user_tables';
case 'synonyms':
return 'SELECT synonym_name FROM user_synonyms';
default:
return null;
}
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/QueryTool.php
New file
0,0 → 1,63
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the DB_QueryTool class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_QueryTool
* @author Wolfram Kriesing <wk@visionp.de>
* @author Paolo Panto <wk@visionp.de>
* @copyright 2003-2005 Wolfram Kriesing, Paolo Panto
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: QueryTool.php,v 1.4 2005/02/25 16:38:27 quipo Exp $
* @link http://pear.php.net/package/DB_QueryTool
*/
 
/**
* require the DB_QueryTool_EasyJoin class
*/
require_once 'DB/QueryTool/EasyJoin.php';
 
/**
* MDB_QueryTool class
*
* This class should be extended; it's here to make it easy using the base
* class of the package by its package name.
* Since I tried to seperate the functionality a bit inside the
* really working classes i decided to have this class here just to
* provide the name, since the functionality inside the other
* classes might be restructured a bit but this name always stays.
*
* @category Database
* @package DB_QueryTool
* @author Wolfram Kriesing <wk@visionp.de>
* @copyright 2003-2005 Wolfram Kriesing
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/DB_QueryTool
*/
class DB_QueryTool extends DB_QueryTool_EasyJoin
{
// {{{ DB_QueryTool()
 
/**
* call parent constructor
* @param mixed $dsn DSN string, DSN array or DB object
* @param array $options
*/
function DB_QueryTool($dsn=false, $options=array())
{
parent::__construct($dsn, $options);
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/storage.php
New file
0,0 → 1,504
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Provides an object interface to a table row
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Stig Bakken <stig@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: storage.php,v 1.21 2005/02/02 02:54:51 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB class so it can be extended from
*/
require_once 'DB.php';
 
/**
* Provides an object interface to a table row
*
* It lets you add, delete and change rows using objects rather than SQL
* statements.
*
* @category Database
* @package DB
* @author Stig Bakken <stig@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_storage extends PEAR
{
// {{{ properties
 
/** the name of the table (or view, if the backend database supports
updates in views) we hold data from */
var $_table = null;
 
/** which column(s) in the table contains primary keys, can be a
string for single-column primary keys, or an array of strings
for multiple-column primary keys */
var $_keycolumn = null;
 
/** DB connection handle used for all transactions */
var $_dbh = null;
 
/** an assoc with the names of database fields stored as properties
in this object */
var $_properties = array();
 
/** an assoc with the names of the properties in this object that
have been changed since they were fetched from the database */
var $_changes = array();
 
/** flag that decides if data in this object can be changed.
objects that don't have their table's key column in their
property lists will be flagged as read-only. */
var $_readonly = false;
 
/** function or method that implements a validator for fields that
are set, this validator function returns true if the field is
valid, false if not */
var $_validator = null;
 
// }}}
// {{{ constructor
 
/**
* Constructor
*
* @param $table string the name of the database table
*
* @param $keycolumn mixed string with name of key column, or array of
* strings if the table has a primary key of more than one column
*
* @param $dbh object database connection object
*
* @param $validator mixed function or method used to validate
* each new value, called with three parameters: the name of the
* field/column that is changing, a reference to the new value and
* a reference to this object
*
*/
function DB_storage($table, $keycolumn, &$dbh, $validator = null)
{
$this->PEAR('DB_Error');
$this->_table = $table;
$this->_keycolumn = $keycolumn;
$this->_dbh = $dbh;
$this->_readonly = false;
$this->_validator = $validator;
}
 
// }}}
// {{{ _makeWhere()
 
/**
* Utility method to build a "WHERE" clause to locate ourselves in
* the table.
*
* XXX future improvement: use rowids?
*
* @access private
*/
function _makeWhere($keyval = null)
{
if (is_array($this->_keycolumn)) {
if ($keyval === null) {
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
$keyval[] = $this->{$this->_keycolumn[$i]};
}
}
$whereclause = '';
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
if ($i > 0) {
$whereclause .= ' AND ';
}
$whereclause .= $this->_keycolumn[$i];
if (is_null($keyval[$i])) {
// there's not much point in having a NULL key,
// but we support it anyway
$whereclause .= ' IS NULL';
} else {
$whereclause .= ' = ' . $this->_dbh->quote($keyval[$i]);
}
}
} else {
if ($keyval === null) {
$keyval = @$this->{$this->_keycolumn};
}
$whereclause = $this->_keycolumn;
if (is_null($keyval)) {
// there's not much point in having a NULL key,
// but we support it anyway
$whereclause .= ' IS NULL';
} else {
$whereclause .= ' = ' . $this->_dbh->quote($keyval);
}
}
return $whereclause;
}
 
// }}}
// {{{ setup()
 
/**
* Method used to initialize a DB_storage object from the
* configured table.
*
* @param $keyval mixed the key[s] of the row to fetch (string or array)
*
* @return int DB_OK on success, a DB error if not
*/
function setup($keyval)
{
$whereclause = $this->_makeWhere($keyval);
$query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause;
$sth = $this->_dbh->query($query);
if (DB::isError($sth)) {
return $sth;
}
$row = $sth->fetchRow(DB_FETCHMODE_ASSOC);
if (DB::isError($row)) {
return $row;
}
if (!$row) {
return $this->raiseError(null, DB_ERROR_NOT_FOUND, null, null,
$query, null, true);
}
foreach ($row as $key => $value) {
$this->_properties[$key] = true;
$this->$key = $value;
}
return DB_OK;
}
 
// }}}
// {{{ insert()
 
/**
* Create a new (empty) row in the configured table for this
* object.
*/
function insert($newpk)
{
if (is_array($this->_keycolumn)) {
$primarykey = $this->_keycolumn;
} else {
$primarykey = array($this->_keycolumn);
}
settype($newpk, "array");
for ($i = 0; $i < sizeof($primarykey); $i++) {
$pkvals[] = $this->_dbh->quote($newpk[$i]);
}
 
$sth = $this->_dbh->query("INSERT INTO $this->_table (" .
implode(",", $primarykey) . ") VALUES(" .
implode(",", $pkvals) . ")");
if (DB::isError($sth)) {
return $sth;
}
if (sizeof($newpk) == 1) {
$newpk = $newpk[0];
}
$this->setup($newpk);
}
 
// }}}
// {{{ toString()
 
/**
* Output a simple description of this DB_storage object.
* @return string object description
*/
function toString()
{
$info = strtolower(get_class($this));
$info .= " (table=";
$info .= $this->_table;
$info .= ", keycolumn=";
if (is_array($this->_keycolumn)) {
$info .= "(" . implode(",", $this->_keycolumn) . ")";
} else {
$info .= $this->_keycolumn;
}
$info .= ", dbh=";
if (is_object($this->_dbh)) {
$info .= $this->_dbh->toString();
} else {
$info .= "null";
}
$info .= ")";
if (sizeof($this->_properties)) {
$info .= " [loaded, key=";
$keyname = $this->_keycolumn;
if (is_array($keyname)) {
$info .= "(";
for ($i = 0; $i < sizeof($keyname); $i++) {
if ($i > 0) {
$info .= ",";
}
$info .= $this->$keyname[$i];
}
$info .= ")";
} else {
$info .= $this->$keyname;
}
$info .= "]";
}
if (sizeof($this->_changes)) {
$info .= " [modified]";
}
return $info;
}
 
// }}}
// {{{ dump()
 
/**
* Dump the contents of this object to "standard output".
*/
function dump()
{
foreach ($this->_properties as $prop => $foo) {
print "$prop = ";
print htmlentities($this->$prop);
print "<br />\n";
}
}
 
// }}}
// {{{ &create()
 
/**
* Static method used to create new DB storage objects.
* @param $data assoc. array where the keys are the names
* of properties/columns
* @return object a new instance of DB_storage or a subclass of it
*/
function &create($table, &$data)
{
$classname = strtolower(get_class($this));
$obj =& new $classname($table);
foreach ($data as $name => $value) {
$obj->_properties[$name] = true;
$obj->$name = &$value;
}
return $obj;
}
 
// }}}
// {{{ loadFromQuery()
 
/**
* Loads data into this object from the given query. If this
* object already contains table data, changes will be saved and
* the object re-initialized first.
*
* @param $query SQL query
*
* @param $params parameter list in case you want to use
* prepare/execute mode
*
* @return int DB_OK on success, DB_WARNING_READ_ONLY if the
* returned object is read-only (because the object's specified
* key column was not found among the columns returned by $query),
* or another DB error code in case of errors.
*/
// XXX commented out for now
/*
function loadFromQuery($query, $params = null)
{
if (sizeof($this->_properties)) {
if (sizeof($this->_changes)) {
$this->store();
$this->_changes = array();
}
$this->_properties = array();
}
$rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params);
if (DB::isError($rowdata)) {
return $rowdata;
}
reset($rowdata);
$found_keycolumn = false;
while (list($key, $value) = each($rowdata)) {
if ($key == $this->_keycolumn) {
$found_keycolumn = true;
}
$this->_properties[$key] = true;
$this->$key = &$value;
unset($value); // have to unset, or all properties will
// refer to the same value
}
if (!$found_keycolumn) {
$this->_readonly = true;
return DB_WARNING_READ_ONLY;
}
return DB_OK;
}
*/
 
// }}}
// {{{ set()
 
/**
* Modify an attriute value.
*/
function set($property, $newvalue)
{
// only change if $property is known and object is not
// read-only
if ($this->_readonly) {
return $this->raiseError(null, DB_WARNING_READ_ONLY, null,
null, null, null, true);
}
if (@isset($this->_properties[$property])) {
if (empty($this->_validator)) {
$valid = true;
} else {
$valid = @call_user_func($this->_validator,
$this->_table,
$property,
$newvalue,
$this->$property,
$this);
}
if ($valid) {
$this->$property = $newvalue;
if (empty($this->_changes[$property])) {
$this->_changes[$property] = 0;
} else {
$this->_changes[$property]++;
}
} else {
return $this->raiseError(null, DB_ERROR_INVALID, null,
null, "invalid field: $property",
null, true);
}
return true;
}
return $this->raiseError(null, DB_ERROR_NOSUCHFIELD, null,
null, "unknown field: $property",
null, true);
}
 
// }}}
// {{{ &get()
 
/**
* Fetch an attribute value.
*
* @param string attribute name
*
* @return attribute contents, or null if the attribute name is
* unknown
*/
function &get($property)
{
// only return if $property is known
if (isset($this->_properties[$property])) {
return $this->$property;
}
$tmp = null;
return $tmp;
}
 
// }}}
// {{{ _DB_storage()
 
/**
* Destructor, calls DB_storage::store() if there are changes
* that are to be kept.
*/
function _DB_storage()
{
if (sizeof($this->_changes)) {
$this->store();
}
$this->_properties = array();
$this->_changes = array();
$this->_table = null;
}
 
// }}}
// {{{ store()
 
/**
* Stores changes to this object in the database.
*
* @return DB_OK or a DB error
*/
function store()
{
foreach ($this->_changes as $name => $foo) {
$params[] = &$this->$name;
$vars[] = $name . ' = ?';
}
if ($vars) {
$query = 'UPDATE ' . $this->_table . ' SET ' .
implode(', ', $vars) . ' WHERE ' .
$this->_makeWhere();
$stmt = $this->_dbh->prepare($query);
$res = $this->_dbh->execute($stmt, $params);
if (DB::isError($res)) {
return $res;
}
$this->_changes = array();
}
return DB_OK;
}
 
// }}}
// {{{ remove()
 
/**
* Remove the row represented by this object from the database.
*
* @return mixed DB_OK or a DB error
*/
function remove()
{
if ($this->_readonly) {
return $this->raiseError(null, DB_WARNING_READ_ONLY, null,
null, null, null, true);
}
$query = 'DELETE FROM ' . $this->_table .' WHERE '.
$this->_makeWhere();
$res = $this->_dbh->query($query);
if (DB::isError($res)) {
return $res;
}
foreach ($this->_properties as $prop => $foo) {
unset($this->$prop);
}
$this->_properties = array();
$this->_changes = array();
return DB_OK;
}
 
// }}}
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/mysql.php
New file
0,0 → 1,1034
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's mysql extension
* for interacting with MySQL databases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: mysql.php,v 1.117 2005/03/29 15:03:26 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's mysql extension
* for interacting with MySQL databases
*
* These methods overload the ones declared in DB_common.
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_mysql extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'mysql';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'mysql';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => 'alter',
'new_link' => '4.2.0',
'numrows' => true,
'pconnect' => true,
'prepare' => false,
'ssl' => false,
'transactions' => true,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
1004 => DB_ERROR_CANNOT_CREATE,
1005 => DB_ERROR_CANNOT_CREATE,
1006 => DB_ERROR_CANNOT_CREATE,
1007 => DB_ERROR_ALREADY_EXISTS,
1008 => DB_ERROR_CANNOT_DROP,
1022 => DB_ERROR_ALREADY_EXISTS,
1044 => DB_ERROR_ACCESS_VIOLATION,
1046 => DB_ERROR_NODBSELECTED,
1048 => DB_ERROR_CONSTRAINT,
1049 => DB_ERROR_NOSUCHDB,
1050 => DB_ERROR_ALREADY_EXISTS,
1051 => DB_ERROR_NOSUCHTABLE,
1054 => DB_ERROR_NOSUCHFIELD,
1061 => DB_ERROR_ALREADY_EXISTS,
1062 => DB_ERROR_ALREADY_EXISTS,
1064 => DB_ERROR_SYNTAX,
1091 => DB_ERROR_NOT_FOUND,
1100 => DB_ERROR_NOT_LOCKED,
1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
1142 => DB_ERROR_ACCESS_VIOLATION,
1146 => DB_ERROR_NOSUCHTABLE,
1216 => DB_ERROR_CONSTRAINT,
1217 => DB_ERROR_CONSTRAINT,
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* Should data manipulation queries be committed automatically?
* @var bool
* @access private
*/
var $autocommit = true;
 
/**
* The quantity of transactions begun
*
* {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
* @access private
*/
var $transaction_opcount = 0;
 
/**
* The database specified in the DSN
*
* It's a fix to allow calls to different databases in the same script.
*
* @var string
* @access private
*/
var $_db = '';
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_mysql()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* PEAR DB's mysql driver supports the following extra DSN options:
* + new_link If set to true, causes subsequent calls to connect()
* to return a new connection link instead of the
* existing one. WARNING: this is not portable to
* other DBMS's. Available since PEAR DB 1.7.0.
* + client_flags Any combination of MYSQL_CLIENT_* constants.
* Only used if PHP is at version 4.3.0 or greater.
* Available since PEAR DB 1.7.0.
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('mysql')) {
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
$params = array();
if ($dsn['protocol'] && $dsn['protocol'] == 'unix') {
$params[0] = ':' . $dsn['socket'];
} else {
$params[0] = $dsn['hostspec'] ? $dsn['hostspec']
: 'localhost';
if ($dsn['port']) {
$params[0] .= ':' . $dsn['port'];
}
}
$params[] = $dsn['username'] ? $dsn['username'] : null;
$params[] = $dsn['password'] ? $dsn['password'] : null;
 
if (!$persistent) {
if (isset($dsn['new_link'])
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true))
{
$params[] = true;
} else {
$params[] = false;
}
}
if (version_compare(phpversion(), '4.3.0', '>=')) {
$params[] = isset($dsn['client_flags'])
? $dsn['client_flags'] : null;
}
 
$connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect';
 
$ini = ini_get('track_errors');
$php_errormsg = '';
if ($ini) {
$this->connection = @call_user_func_array($connect_function,
$params);
} else {
ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function,
$params);
ini_set('track_errors', $ini);
}
 
if (!$this->connection) {
if (($err = @mysql_error()) != '') {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$err);
} else {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$php_errormsg);
}
}
 
if ($dsn['database']) {
if (!@mysql_select_db($dsn['database'], $this->connection)) {
return $this->mysqlRaiseError();
}
$this->_db = $dsn['database'];
}
 
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @mysql_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* Generally uses mysql_query(). If you want to use
* mysql_unbuffered_query() set the "result_buffering" option to 0 using
* setOptions(). This option was added in Release 1.7.0.
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
if ($this->_db) {
if (!@mysql_select_db($this->_db, $this->connection)) {
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
}
}
if (!$this->autocommit && $ismanip) {
if ($this->transaction_opcount == 0) {
$result = @mysql_query('SET AUTOCOMMIT=0', $this->connection);
$result = @mysql_query('BEGIN', $this->connection);
if (!$result) {
return $this->mysqlRaiseError();
}
}
$this->transaction_opcount++;
}
if (!$this->options['result_buffering']) {
$result = @mysql_unbuffered_query($query, $this->connection);
} else {
$result = @mysql_query($query, $this->connection);
}
if (!$result) {
return $this->mysqlRaiseError();
}
if (is_resource($result)) {
return $result;
}
return DB_OK;
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal mysql result pointer to the next available result
*
* This method has not been implemented yet.
*
* @param a valid sql result resource
*
* @return false
*/
function nextResult($result)
{
return false;
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@mysql_data_seek($result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @mysql_fetch_array($result, MYSQL_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @mysql_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
/*
* Even though this DBMS already trims output, we do this because
* a field might have intentional whitespace at the end that
* gets removed by DB_PORTABILITY_RTRIM under another driver.
*/
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return @mysql_free_result($result);
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @mysql_num_fields($result);
if (!$cols) {
return $this->mysqlRaiseError();
}
return $cols;
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
function numRows($result)
{
$rows = @mysql_num_rows($result);
if ($rows === null) {
return $this->mysqlRaiseError();
}
return $rows;
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff = false)
{
// XXX if $this->transaction_opcount > 0, we should probably
// issue a warning here.
$this->autocommit = $onoff ? true : false;
return DB_OK;
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
if ($this->transaction_opcount > 0) {
if ($this->_db) {
if (!@mysql_select_db($this->_db, $this->connection)) {
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
}
}
$result = @mysql_query('COMMIT', $this->connection);
$result = @mysql_query('SET AUTOCOMMIT=1', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->mysqlRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
if ($this->transaction_opcount > 0) {
if ($this->_db) {
if (!@mysql_select_db($this->_db, $this->connection)) {
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
}
}
$result = @mysql_query('ROLLBACK', $this->connection);
$result = @mysql_query('SET AUTOCOMMIT=1', $this->connection);
$this->transaction_opcount = 0;
if (!$result) {
return $this->mysqlRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
if (DB::isManip($this->last_query)) {
return @mysql_affected_rows($this->connection);
} else {
return 0;
}
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_mysql::createSequence(), DB_mysql::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
do {
$repeat = 0;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("UPDATE ${seqname} ".
'SET id=LAST_INSERT_ID(id+1)');
$this->popErrorHandling();
if ($result === DB_OK) {
// COMMON CASE
$id = @mysql_insert_id($this->connection);
if ($id != 0) {
return $id;
}
// EMPTY SEQ TABLE
// Sequence table must be empty for some reason, so fill
// it and return 1 and obtain a user-level lock
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
if (DB::isError($result)) {
return $this->raiseError($result);
}
if ($result == 0) {
// Failed to get the lock
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
}
 
// add the default value
$result = $this->query("REPLACE INTO ${seqname} (id) VALUES (0)");
if (DB::isError($result)) {
return $this->raiseError($result);
}
 
// Release the lock
$result = $this->getOne('SELECT RELEASE_LOCK('
. "'${seqname}_lock')");
if (DB::isError($result)) {
return $this->raiseError($result);
}
// We know what the result will be, so no need to try again
return 1;
 
} elseif ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE)
{
// ONDEMAND TABLE CREATION
$result = $this->createSequence($seq_name);
if (DB::isError($result)) {
return $this->raiseError($result);
} else {
$repeat = 1;
}
 
} elseif (DB::isError($result) &&
$result->getCode() == DB_ERROR_ALREADY_EXISTS)
{
// BACKWARDS COMPAT
// see _BCsequence() comment
$result = $this->_BCsequence($seqname);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$repeat = 1;
}
} while ($repeat);
 
return $this->raiseError($result);
}
 
// }}}
// {{{ createSequence()
 
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_mysql::nextID(), DB_mysql::dropSequence()
*/
function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$res = $this->query('CREATE TABLE ' . $seqname
. ' (id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'
. ' PRIMARY KEY(id))');
if (DB::isError($res)) {
return $res;
}
// insert yields value 1, nextId call will generate ID 2
$res = $this->query("INSERT INTO ${seqname} (id) VALUES (0)");
if (DB::isError($res)) {
return $res;
}
// so reset to zero
return $this->query("UPDATE ${seqname} SET id = 0");
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_mysql::nextID(), DB_mysql::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
 
// }}}
// {{{ _BCsequence()
 
/**
* Backwards compatibility with old sequence emulation implementation
* (clean up the dupes)
*
* @param string $seqname the sequence name to clean up
*
* @return bool true on success. A DB_Error object on failure.
*
* @access private
*/
function _BCsequence($seqname)
{
// Obtain a user-level lock... this will release any previous
// application locks, but unlike LOCK TABLES, it does not abort
// the current transaction and is much less frequently used.
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
if (DB::isError($result)) {
return $result;
}
if ($result == 0) {
// Failed to get the lock, can't do the conversion, bail
// with a DB_ERROR_NOT_LOCKED error
return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
}
 
$highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}");
if (DB::isError($highest_id)) {
return $highest_id;
}
// This should kill all rows except the highest
// We should probably do something if $highest_id isn't
// numeric, but I'm at a loss as how to handle that...
$result = $this->query('DELETE FROM ' . $seqname
. " WHERE id <> $highest_id");
if (DB::isError($result)) {
return $result;
}
 
// If another thread has been waiting for this lock,
// it will go thru the above procedure, but will have no
// real effect
$result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')");
if (DB::isError($result)) {
return $result;
}
return true;
}
 
// }}}
// {{{ quoteIdentifier()
 
/**
* Quotes a string so it can be safely used as a table or column name
*
* MySQL can't handle the backtick character (<kbd>`</kbd>) in
* table or column names.
*
* @param string $str identifier name to be quoted
*
* @return string quoted identifier string
*
* @see DB_common::quoteIdentifier()
* @since Method available since Release 1.6.0
*/
function quoteIdentifier($str)
{
return '`' . $str . '`';
}
 
// }}}
// {{{ quote()
 
/**
* @deprecated Deprecated in release 1.6.0
*/
function quote($str)
{
return $this->quoteSmart($str);
}
 
// }}}
// {{{ escapeSimple()
 
/**
* Escapes a string according to the current DBMS's standards
*
* @param string $str the string to be escaped
*
* @return string the escaped string
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
function escapeSimple($str)
{
if (function_exists('mysql_real_escape_string')) {
return @mysql_real_escape_string($str, $this->connection);
} else {
return @mysql_escape_string($str);
}
}
 
// }}}
// {{{ modifyQuery()
 
/**
* Changes a query string for various DBMS specific reasons
*
* This little hack lets you know how many rows were deleted
* when running a "DELETE FROM table" query. Only implemented
* if the DB_PORTABILITY_DELETE_COUNT portability option is on.
*
* @param string $query the query string to modify
*
* @return string the modified query string
*
* @access protected
* @see DB_common::setOption()
*/
function modifyQuery($query)
{
if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) {
// "DELETE FROM table" gives 0 affected rows in MySQL.
// This little hack lets you know how many rows were deleted.
if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
$query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
'DELETE FROM \1 WHERE 1=1', $query);
}
}
return $query;
}
 
// }}}
// {{{ modifyLimitQuery()
 
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
if (DB::isManip($query)) {
return $query . " LIMIT $count";
} else {
return $query . " LIMIT $from, $count";
}
}
 
// }}}
// {{{ mysqlRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_mysql::errorNative(), DB_common::errorCode()
*/
function mysqlRaiseError($errno = null)
{
if ($errno === null) {
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL;
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT;
} else {
// Doing this in case mode changes during runtime.
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS;
}
$errno = $this->errorCode(mysql_errno($this->connection));
}
return $this->raiseError($errno, null, null, null,
@mysql_errno($this->connection) . ' ** ' .
@mysql_error($this->connection));
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error code produced by the last query
*
* @return int the DBMS' error code
*/
function errorNative()
{
return @mysql_errno($this->connection);
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @mysql_list_fields($this->dsn['database'],
$result, $this->connection);
$got_string = true;
} elseif (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$id = $result->result;
$got_string = false;
} else {
/*
* Probably received a result resource identifier.
* Copy it.
* Deprecated. Here for compatibility only.
*/
$id = $result;
$got_string = false;
}
 
if (!is_resource($id)) {
return $this->mysqlRaiseError(DB_ERROR_NEED_MORE_DATA);
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$count = @mysql_num_fields($id);
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
$res[$i] = array(
'table' => $case_func(@mysql_field_table($id, $i)),
'name' => $case_func(@mysql_field_name($id, $i)),
'type' => @mysql_field_type($id, $i),
'len' => @mysql_field_len($id, $i),
'flags' => @mysql_field_flags($id, $i),
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
// free the result only if we were called on a table
if ($got_string) {
@mysql_free_result($id);
}
return $res;
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'tables':
return 'SHOW TABLES';
case 'users':
return 'SELECT DISTINCT User FROM mysql.user';
case 'databases':
return 'SHOW DATABASES';
default:
return null;
}
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/odbc.php
New file
0,0 → 1,883
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's odbc extension
* for interacting with databases via ODBC connections
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: odbc.php,v 1.78 2005/02/28 01:42:17 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's odbc extension
* for interacting with databases via ODBC connections
*
* These methods overload the ones declared in DB_common.
*
* More info on ODBC errors could be found here:
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/trblsql/tr_err_odbc_5stz.asp
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_odbc extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'odbc';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'sql92';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* NOTE: The feature set of the following drivers are different than
* the default:
* + solid: 'transactions' = true
* + navision: 'limit' = false
*
* @var array
*/
var $features = array(
'limit' => 'emulate',
'new_link' => false,
'numrows' => true,
'pconnect' => true,
'prepare' => false,
'ssl' => false,
'transactions' => false,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
'01004' => DB_ERROR_TRUNCATED,
'07001' => DB_ERROR_MISMATCH,
'21S01' => DB_ERROR_VALUE_COUNT_ON_ROW,
'21S02' => DB_ERROR_MISMATCH,
'22001' => DB_ERROR_INVALID,
'22003' => DB_ERROR_INVALID_NUMBER,
'22005' => DB_ERROR_INVALID_NUMBER,
'22008' => DB_ERROR_INVALID_DATE,
'22012' => DB_ERROR_DIVZERO,
'23000' => DB_ERROR_CONSTRAINT,
'23502' => DB_ERROR_CONSTRAINT_NOT_NULL,
'23503' => DB_ERROR_CONSTRAINT,
'23504' => DB_ERROR_CONSTRAINT,
'23505' => DB_ERROR_CONSTRAINT,
'24000' => DB_ERROR_INVALID,
'34000' => DB_ERROR_INVALID,
'37000' => DB_ERROR_SYNTAX,
'42000' => DB_ERROR_SYNTAX,
'42601' => DB_ERROR_SYNTAX,
'IM001' => DB_ERROR_UNSUPPORTED,
'S0000' => DB_ERROR_NOSUCHTABLE,
'S0001' => DB_ERROR_ALREADY_EXISTS,
'S0002' => DB_ERROR_NOSUCHTABLE,
'S0011' => DB_ERROR_ALREADY_EXISTS,
'S0012' => DB_ERROR_NOT_FOUND,
'S0021' => DB_ERROR_ALREADY_EXISTS,
'S0022' => DB_ERROR_NOSUCHFIELD,
'S1009' => DB_ERROR_INVALID,
'S1090' => DB_ERROR_INVALID,
'S1C00' => DB_ERROR_NOT_CAPABLE,
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* The number of rows affected by a data manipulation query
* @var integer
* @access private
*/
var $affected = 0;
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_odbc()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* PEAR DB's odbc driver supports the following extra DSN options:
* + cursor The type of cursor to be used for this connection.
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('odbc')) {
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
switch ($this->dbsyntax) {
case 'access':
case 'db2':
case 'solid':
$this->features['transactions'] = true;
break;
case 'navision':
$this->features['limit'] = false;
}
 
/*
* This is hear for backwards compatibility. Should have been using
* 'database' all along, but prior to 1.6.0RC3 'hostspec' was used.
*/
if ($dsn['database']) {
$odbcdsn = $dsn['database'];
} elseif ($dsn['hostspec']) {
$odbcdsn = $dsn['hostspec'];
} else {
$odbcdsn = 'localhost';
}
 
$connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect';
 
if (empty($dsn['cursor'])) {
$this->connection = @$connect_function($odbcdsn, $dsn['username'],
$dsn['password']);
} else {
$this->connection = @$connect_function($odbcdsn, $dsn['username'],
$dsn['password'],
$dsn['cursor']);
}
 
if (!is_resource($this->connection)) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$this->errorNative());
}
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$err = @odbc_close($this->connection);
$this->connection = null;
return $err;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$this->last_query = $query;
$query = $this->modifyQuery($query);
$result = @odbc_exec($this->connection, $query);
if (!$result) {
return $this->odbcRaiseError(); // XXX ERRORMSG
}
// Determine which queries that should return data, and which
// should return an error code only.
if (DB::isManip($query)) {
$this->affected = $result; // For affectedRows()
return DB_OK;
}
$this->affected = 0;
return $result;
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal odbc result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
function nextResult($result)
{
return @odbc_next_result($result);
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
$arr = array();
if ($rownum !== null) {
$rownum++; // ODBC first row is 1
if (version_compare(phpversion(), '4.2.0', 'ge')) {
$cols = @odbc_fetch_into($result, $arr, $rownum);
} else {
$cols = @odbc_fetch_into($result, $rownum, $arr);
}
} else {
$cols = @odbc_fetch_into($result, $arr);
}
if (!$cols) {
return null;
}
if ($fetchmode !== DB_FETCHMODE_ORDERED) {
for ($i = 0; $i < count($arr); $i++) {
$colName = @odbc_field_name($result, $i+1);
$a[$colName] = $arr[$i];
}
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$a = array_change_key_case($a, CASE_LOWER);
}
$arr = $a;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return @odbc_free_result($result);
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @odbc_num_fields($result);
if (!$cols) {
return $this->odbcRaiseError();
}
return $cols;
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
if (empty($this->affected)) { // In case of SELECT stms
return 0;
}
$nrows = @odbc_num_rows($this->affected);
if ($nrows == -1) {
return $this->odbcRaiseError();
}
return $nrows;
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* Not all ODBC drivers support this functionality. If they don't
* a DB_Error object for DB_ERROR_UNSUPPORTED is returned.
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
function numRows($result)
{
$nrows = @odbc_num_rows($result);
if ($nrows == -1) {
return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED);
}
if ($nrows === false) {
return $this->odbcRaiseError();
}
return $nrows;
}
 
// }}}
// {{{ quoteIdentifier()
 
/**
* Quotes a string so it can be safely used as a table or column name
*
* Use 'mssql' as the dbsyntax in the DB DSN only if you've unchecked
* "Use ANSI quoted identifiers" when setting up the ODBC data source.
*
* @param string $str identifier name to be quoted
*
* @return string quoted identifier string
*
* @see DB_common::quoteIdentifier()
* @since Method available since Release 1.6.0
*/
function quoteIdentifier($str)
{
switch ($this->dsn['dbsyntax']) {
case 'access':
return '[' . $str . ']';
case 'mssql':
case 'sybase':
return '[' . str_replace(']', ']]', $str) . ']';
case 'mysql':
case 'mysqli':
return '`' . $str . '`';
default:
return '"' . str_replace('"', '""', $str) . '"';
}
}
 
// }}}
// {{{ quote()
 
/**
* @deprecated Deprecated in release 1.6.0
* @internal
*/
function quote($str)
{
return $this->quoteSmart($str);
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_odbc::createSequence(), DB_odbc::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
$repeat = 0;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("update ${seqname} set id = id + 1");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = 1;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->createSequence($seq_name);
$this->popErrorHandling();
if (DB::isError($result)) {
return $this->raiseError($result);
}
$result = $this->query("insert into ${seqname} (id) values(0)");
} else {
$repeat = 0;
}
} while ($repeat);
 
if (DB::isError($result)) {
return $this->raiseError($result);
}
 
$result = $this->query("select id from ${seqname}");
if (DB::isError($result)) {
return $result;
}
 
$row = $result->fetchRow(DB_FETCHMODE_ORDERED);
if (DB::isError($row || !$row)) {
return $row;
}
 
return $row[0];
}
 
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_odbc::nextID(), DB_odbc::dropSequence()
*/
function createSequence($seq_name)
{
return $this->query('CREATE TABLE '
. $this->getSequenceName($seq_name)
. ' (id integer NOT NULL,'
. ' PRIMARY KEY(id))');
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_odbc::nextID(), DB_odbc::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff = false)
{
if (!@odbc_autocommit($this->connection, $onoff)) {
return $this->odbcRaiseError();
}
return DB_OK;
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
if (!@odbc_commit($this->connection)) {
return $this->odbcRaiseError();
}
return DB_OK;
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
if (!@odbc_rollback($this->connection)) {
return $this->odbcRaiseError();
}
return DB_OK;
}
 
// }}}
// {{{ odbcRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_odbc::errorNative(), DB_common::errorCode()
*/
function odbcRaiseError($errno = null)
{
if ($errno === null) {
switch ($this->dbsyntax) {
case 'access':
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
$this->errorcode_map['07001'] = DB_ERROR_NOSUCHFIELD;
} else {
// Doing this in case mode changes during runtime.
$this->errorcode_map['07001'] = DB_ERROR_MISMATCH;
}
 
$native_code = odbc_error($this->connection);
 
// S1000 is for "General Error." Let's be more specific.
if ($native_code == 'S1000') {
$errormsg = odbc_errormsg($this->connection);
static $error_regexps;
if (!isset($error_regexps)) {
$error_regexps = array(
'/includes related records.$/i' => DB_ERROR_CONSTRAINT,
'/cannot contain a Null value/i' => DB_ERROR_CONSTRAINT_NOT_NULL,
);
}
foreach ($error_regexps as $regexp => $code) {
if (preg_match($regexp, $errormsg)) {
return $this->raiseError($code,
null, null, null,
$native_code . ' ' . $errormsg);
}
}
$errno = DB_ERROR;
} else {
$errno = $this->errorCode($native_code);
}
break;
default:
$errno = $this->errorCode(odbc_error($this->connection));
}
}
return $this->raiseError($errno, null, null, null,
$this->errorNative());
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error code and message produced by the last query
*
* @return string the DBMS' error code and message
*/
function errorNative()
{
if (!is_resource($this->connection)) {
return @odbc_error() . ' ' . @odbc_errormsg();
}
return @odbc_error($this->connection) . ' ' . @odbc_errormsg($this->connection);
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
* @since Method available since Release 1.7.0
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @odbc_exec($this->connection, "SELECT * FROM $result");
if (!$id) {
return $this->odbcRaiseError();
}
$got_string = true;
} elseif (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$id = $result->result;
$got_string = false;
} else {
/*
* Probably received a result resource identifier.
* Copy it.
* Deprecated. Here for compatibility only.
*/
$id = $result;
$got_string = false;
}
 
if (!is_resource($id)) {
return $this->odbcRaiseError(DB_ERROR_NEED_MORE_DATA);
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$count = @odbc_num_fields($id);
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
$col = $i + 1;
$res[$i] = array(
'table' => $got_string ? $case_func($result) : '',
'name' => $case_func(@odbc_field_name($id, $col)),
'type' => @odbc_field_type($id, $col),
'len' => @odbc_field_len($id, $col),
'flags' => '',
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
// free the result only if we were called on a table
if ($got_string) {
@odbc_free_result($id);
}
return $res;
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* Thanks to symbol1@gmail.com and Philippe.Jausions@11abacus.com.
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the list of objects requested
*
* @access protected
* @see DB_common::getListOf()
* @since Method available since Release 1.7.0
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'databases':
if (!function_exists('odbc_data_source')) {
return null;
}
$res = @odbc_data_source($this->connection, SQL_FETCH_FIRST);
if (is_array($res)) {
$out = array($res['server']);
while($res = @odbc_data_source($this->connection,
SQL_FETCH_NEXT))
{
$out[] = $res['server'];
}
return $out;
} else {
return $this->odbcRaiseError();
}
break;
case 'tables':
case 'schema.tables':
$keep = 'TABLE';
break;
case 'views':
$keep = 'VIEW';
break;
default:
return null;
}
 
/*
* Removing non-conforming items in the while loop rather than
* in the odbc_tables() call because some backends choke on this:
* odbc_tables($this->connection, '', '', '', 'TABLE')
*/
$res = @odbc_tables($this->connection);
if (!$res) {
return $this->odbcRaiseError();
}
$out = array();
while ($row = odbc_fetch_array($res)) {
if ($row['TABLE_TYPE'] != $keep) {
continue;
}
if ($type == 'schema.tables') {
$out[] = $row['TABLE_SCHEM'] . '.' . $row['TABLE_NAME'];
} else {
$out[] = $row['TABLE_NAME'];
}
}
return $out;
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/fbsql.php
New file
0,0 → 1,770
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's fbsql extension
* for interacting with FrontBase databases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Frank M. Kromann <frank@frontbase.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: fbsql.php,v 1.82 2005/03/04 23:12:36 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's fbsql extension
* for interacting with FrontBase databases
*
* These methods overload the ones declared in DB_common.
*
* @category Database
* @package DB
* @author Frank M. Kromann <frank@frontbase.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
* @since Class functional since Release 1.7.0
*/
class DB_fbsql extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'fbsql';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'fbsql';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => 'alter',
'new_link' => false,
'numrows' => true,
'pconnect' => true,
'prepare' => false,
'ssl' => false,
'transactions' => true,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
22 => DB_ERROR_SYNTAX,
85 => DB_ERROR_ALREADY_EXISTS,
108 => DB_ERROR_SYNTAX,
116 => DB_ERROR_NOSUCHTABLE,
124 => DB_ERROR_VALUE_COUNT_ON_ROW,
215 => DB_ERROR_NOSUCHFIELD,
217 => DB_ERROR_INVALID_NUMBER,
226 => DB_ERROR_NOSUCHFIELD,
231 => DB_ERROR_INVALID,
239 => DB_ERROR_TRUNCATED,
251 => DB_ERROR_SYNTAX,
266 => DB_ERROR_NOT_FOUND,
357 => DB_ERROR_CONSTRAINT_NOT_NULL,
358 => DB_ERROR_CONSTRAINT,
360 => DB_ERROR_CONSTRAINT,
361 => DB_ERROR_CONSTRAINT,
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_fbsql()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('fbsql')) {
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
$params = array(
$dsn['hostspec'] ? $dsn['hostspec'] : 'localhost',
$dsn['username'] ? $dsn['username'] : null,
$dsn['password'] ? $dsn['password'] : null,
);
 
$connect_function = $persistent ? 'fbsql_pconnect' : 'fbsql_connect';
 
$ini = ini_get('track_errors');
$php_errormsg = '';
if ($ini) {
$this->connection = @call_user_func_array($connect_function,
$params);
} else {
ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function,
$params);
ini_set('track_errors', $ini);
}
 
if (!$this->connection) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$php_errormsg);
}
 
if ($dsn['database']) {
if (!@fbsql_select_db($dsn['database'], $this->connection)) {
return $this->fbsqlRaiseError();
}
}
 
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @fbsql_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$this->last_query = $query;
$query = $this->modifyQuery($query);
$result = @fbsql_query("$query;", $this->connection);
if (!$result) {
return $this->fbsqlRaiseError();
}
// Determine which queries that should return data, and which
// should return an error code only.
if (DB::isManip($query)) {
return DB_OK;
}
return $result;
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal fbsql result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
function nextResult($result)
{
return @fbsql_next_result($result);
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@fbsql_data_seek($result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @fbsql_fetch_array($result, FBSQL_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @fbsql_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return @fbsql_free_result($result);
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff=false)
{
if ($onoff) {
$this->query("SET COMMIT TRUE");
} else {
$this->query("SET COMMIT FALSE");
}
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
@fbsql_commit();
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
@fbsql_rollback();
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @fbsql_num_fields($result);
if (!$cols) {
return $this->fbsqlRaiseError();
}
return $cols;
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
function numRows($result)
{
$rows = @fbsql_num_rows($result);
if ($rows === null) {
return $this->fbsqlRaiseError();
}
return $rows;
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
if (DB::isManip($this->last_query)) {
$result = @fbsql_affected_rows($this->connection);
} else {
$result = 0;
}
return $result;
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_fbsql::createSequence(), DB_fbsql::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
do {
$repeat = 0;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query('SELECT UNIQUE FROM ' . $seqname);
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = 1;
$result = $this->createSequence($seq_name);
if (DB::isError($result)) {
return $result;
}
} else {
$repeat = 0;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->fbsqlRaiseError();
}
$result->fetchInto($tmp, DB_FETCHMODE_ORDERED);
return $tmp[0];
}
 
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_fbsql::nextID(), DB_fbsql::dropSequence()
*/
function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$res = $this->query('CREATE TABLE ' . $seqname
. ' (id INTEGER NOT NULL,'
. ' PRIMARY KEY(id))');
if ($res) {
$res = $this->query('SET UNIQUE = 0 FOR ' . $seqname);
}
return $res;
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_fbsql::nextID(), DB_fbsql::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)
. ' RESTRICT');
}
 
// }}}
// {{{ modifyLimitQuery()
 
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
if (DB::isManip($query)) {
return preg_replace('/^([\s(])*SELECT/i',
"\\1SELECT TOP($count)", $query);
} else {
return preg_replace('/([\s(])*SELECT/i',
"\\1SELECT TOP($from, $count)", $query);
}
}
 
// }}}
// {{{ quoteSmart()
 
/**
* Formats input so it can be safely used in a query
*
* @param mixed $in the data to be formatted
*
* @return mixed the formatted data. The format depends on the input's
* PHP type:
* + null = the string <samp>NULL</samp>
* + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp>
* + integer or double = the unquoted number
* + other (including strings and numeric strings) =
* the data escaped according to FrontBase's settings
* then encapsulated between single quotes
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
function quoteSmart($in)
{
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
return $in ? 'TRUE' : 'FALSE';
} elseif (is_null($in)) {
return 'NULL';
} else {
return "'" . $this->escapeSimple($in) . "'";
}
}
 
// }}}
// {{{ fbsqlRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_fbsql::errorNative(), DB_common::errorCode()
*/
function fbsqlRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode(fbsql_errno($this->connection));
}
return $this->raiseError($errno, null, null, null,
@fbsql_error($this->connection));
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error code produced by the last query
*
* @return int the DBMS' error code
*/
function errorNative()
{
return @fbsql_errno($this->connection);
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @fbsql_list_fields($this->dsn['database'],
$result, $this->connection);
$got_string = true;
} elseif (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$id = $result->result;
$got_string = false;
} else {
/*
* Probably received a result resource identifier.
* Copy it.
* Deprecated. Here for compatibility only.
*/
$id = $result;
$got_string = false;
}
 
if (!is_resource($id)) {
return $this->fbsqlRaiseError(DB_ERROR_NEED_MORE_DATA);
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$count = @fbsql_num_fields($id);
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
$res[$i] = array(
'table' => $case_func(@fbsql_field_table($id, $i)),
'name' => $case_func(@fbsql_field_name($id, $i)),
'type' => @fbsql_field_type($id, $i),
'len' => @fbsql_field_len($id, $i),
'flags' => @fbsql_field_flags($id, $i),
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
// free the result only if we were called on a table
if ($got_string) {
@fbsql_free_result($id);
}
return $res;
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'tables':
return 'SELECT "table_name" FROM information_schema.tables'
. ' t0, information_schema.schemata t1'
. ' WHERE t0.schema_pk=t1.schema_pk AND'
. ' "table_type" = \'BASE TABLE\''
. ' AND "schema_name" = current_schema';
case 'views':
return 'SELECT "table_name" FROM information_schema.tables'
. ' t0, information_schema.schemata t1'
. ' WHERE t0.schema_pk=t1.schema_pk AND'
. ' "table_type" = \'VIEW\''
. ' AND "schema_name" = current_schema';
case 'users':
return 'SELECT "user_name" from information_schema.users';
case 'functions':
return 'SELECT "routine_name" FROM'
. ' information_schema.psm_routines'
. ' t0, information_schema.schemata t1'
. ' WHERE t0.schema_pk=t1.schema_pk'
. ' AND "routine_kind"=\'FUNCTION\''
. ' AND "schema_name" = current_schema';
case 'procedures':
return 'SELECT "routine_name" FROM'
. ' information_schema.psm_routines'
. ' t0, information_schema.schemata t1'
. ' WHERE t0.schema_pk=t1.schema_pk'
. ' AND "routine_kind"=\'PROCEDURE\''
. ' AND "schema_name" = current_schema';
default:
return null;
}
}
 
// }}}
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/NestedSet/Event.php
New file
0,0 → 1,79
<?php
/**
// +----------------------------------------------------------------------+
// | PEAR :: DB_NestedSet_DB |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Daniel Khan <dk@webcluster.at> |
// +----------------------------------------------------------------------+
//
// $Id: Event.php,v 1.3 2003/10/07 00:11:27 datenpunk Exp $
//
//
*/
 
/**
* Poor mans event handler for DB_NestedSet
*
* Mostly for demo purposes or for extending it if
* someone has ideas...
*
* @author Daniel Khan <dk@webcluster.at>
* @package DB_NestedSet
* @version $Revision: 1.3 $
* @access public
*/
Class DB_NestedSetEvent extends PEAR {
 
/**
* Constructor
*
* @return void
*/
function DB_NestedSetEvent() {
 
$this->PEAR();
}
 
/**
* Destructor
*
* @return void
*/
function _DB_NestedSetEvent() {
 
$this->_PEAR();
}
 
 
/**
* Calls the event handler
*
* You may want to do a switch() here and call you methods
* depending on the event
*
* @param string $event The Event that occured
* @param object node $node A Reference to the node object which was subject to changes
* @param array $eparams A associative array of params which may be needed by the handler
* @return void
* @access private
*/
function callEvent($event, &$node, $eparams = array()) {
 
echo "<br>Override callEvent() if you want to have custom event handlers<br>\n";
echo "Event $event was called with the following params:<br><br>\n";
echo "<PRE>";
print_r($eparams);
echo "</PRE><br>\n";
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/NestedSet/MDB.php
New file
0,0 → 1,136
<?php
//
// +----------------------------------------------------------------------+
// | PEAR :: DB_NestedSet_MDB |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Daniel Khan <dk@webcluster.at> |
// +----------------------------------------------------------------------+
// Thanks to Hans Lellelid for suggesting support for PEAR::MDB
// and for his help in implementing this.
//
// $Id: MDB.php,v 1.7 2003/10/07 00:11:27 datenpunk Exp $
//
 
require_once 'MDB.php';
 
// {{{ DB_NestedSet_MDB:: class
 
/**
* Wrapper class for PEAR::MDB
*
* @author Daniel Khan <dk@webcluster.at>
* @package DB_NestedSet
* @version $Revision: 1.7 $
* @access public
*/
// }}}
class DB_NestedSet_MDB extends DB_NestedSet {
// {{{ properties
 
/**
* @var object The MDB object
*/
var $db;
 
// }}}
// {{{ constructor
 
/**
* Constructor
*
* @param mixed $dsn DSN as PEAR dsn URI or dsn Array
* @param array $params Database column fields which should be returned
*
*/
function DB_NestedSet_MDB($dsn, $params = array())
{
$this->_debugMessage('DB_NestedSet_MDB($dsn, $params = array())');
$this->DB_NestedSet($params);
$this->db =& $this->_db_Connect($dsn);
$this->db->setFetchMode(MDB_FETCHMODE_ASSOC);
}
 
// }}}
// {{{ destructor
 
/**
* Destructor
*/
function _DB_NestedSet_MDB()
{
$this->_debugMessage('_DB_NestedSet_MDB()');
$this->_DB_NestedSet();
$this->_db_Disconnect();
}
 
// }}}
// {{{ _db_Connect()
 
/**
* Connects to the db
*
* @return object DB The database object
* @access private
*/
function &_db_Connect($dsn)
{
$this->_debugMessage('_db_Connect($dsn)');
if (is_object($this->db)) {
return $this->db;
}
 
$db =& MDB::connect($dsn);
$this->_testFatalAbort($db, __FILE__, __LINE__);
 
return $db;
}
 
// }}}
 
function _isDBError($err) {
if(!MDB::isError($err)) {
return false;
}
return true;
}
 
function _numRows($res) {
return $this->db->numRows($res);
}
 
function _quote($str) {
return $this->db->getTextValue($str);
}
 
// {{{ _db_Disconnect()
 
/**
* Disconnects from db
*
* @return void
* @access private
*/
function _db_Disconnect()
{
$this->_debugMessage('_db_Disconnect()');
if (is_object($this->db)) {
@$this->db->disconnect();
}
 
return true;
}
 
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/NestedSet/TreeMenu.php
New file
0,0 → 1,205
<?php
//
// +----------------------------------------------------------------------+
// | PEAR :: DB_NestedSet_TreeMenu |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Jason Rust <jrust@rustyparts.com> |
// +----------------------------------------------------------------------+
//
// $Id: TreeMenu.php,v 1.13 2003/10/07 00:11:27 datenpunk Exp $
//
 
require_once 'HTML/TreeMenu.php';
 
// {{{ DB_NestedSet_TreeMenu:: class
 
/**
* A helper class to translate the data from a nested set table into a HTML_TreeMenu object
* so that it can be used to create a dynamic tree menu using the PEAR HTML_TreeMenu class.
*
* @see docs/TreeMenu_example.php
* @author Jason Rust <jrust@rustyparts.com>
* @package DB_NestedSet
* @version $Revision: 1.13 $
* @access public
*/
// }}}
class DB_NestedSet_TreeMenu extends DB_NestedSet_Output {
// {{{ properties
 
/**
* @var array The current menu structure
* @access private
*/
var $_structTreeMenu = false;
 
// }}}
// {{{ DB_NestedSet_TreeMenu
 
function &DB_NestedSet_TreeMenu($params) {
$this->_structTreeMenu =& $this->_createFromStructure($params);
}
 
// }}}
// {{{ _createFromStructure()
 
/**
* <pre>Creates a HTML_TreeMenu structure based off of the results from getAllNodes() method
* of the DB_NestedSet class. The needed parameters are:
* o 'structure' => the result from $nestedSet->getAllNodes(true)
* o 'textField' => the field in the table that has the text for node
* o 'linkField' => the field in the table that has the link for the node
* o 'options' => (optional) an array of any additional options to pass to the node when
* Additionally these parameters may be added to the individual nodes to control their
* behavior:
* o 'ensureVisible' => (optional) whether or not the field should be forced as visible
* creating it such as 'icon' or 'expandedIcon'
* o 'events' => (optional) an array of any events to pass to the node when creating it
* such as 'onclick' or 'onexpand'</pre>
* </pre>
* @access public
* @return object A HTML_TreeMenu object
*/
function &_createFromStructure($params)
{
// Basically we go through the array of nodes checking to see
// if each node has children and if so recursing. The reason this
// works is because the data from getAllNodes() is ordered by level
// so a root node will always be first, and sub children will always
// be after them.
if (!isset($params['treeMenu'])) {
$treeMenu =& new HTML_TreeMenu();
} else {
$treeMenu =& $params['treeMenu'];
}
 
// always start at level 1
if (!isset($params['currentLevel'])) {
$params['currentLevel'] = 1;
}
 
// have to use a while loop here because foreach works on a copy of the array and
// the child nodes are passed by reference during the recursion so that the parent
// will know when they have been hit.
reset($params['structure']);
while(list($key, $node) = each($params['structure'])) {
// see if we've already been here before
if (isset($node['hit'])) {
continue;
}
 
// mark that we've hit this node
$params['structure'][$key]['hit'] = $node['hit'] = true;
$tag = array(
'text' => $node[$params['textField']],
'link' => $node[$params['linkField']],
'ensureVisible' => isset($node['ensureVisible']) ? $node['ensureVisible'] : false,
);
$options = isset($params['options']) ? array_merge($params['options'], $tag) : $tag;
$events = isset($node['events']) ? $node['events'] : array();
$parentNode =& $treeMenu->addItem(new HTML_TreeNode($options, $events));
// see if it has children
if (($node['r'] - 1) != $node['l']) {
$children = array();
// harvest all the children
$tempStructure = $params['structure'];
foreach ($tempStructure as $childKey => $childNode) {
if (!isset($childNode['hit']) &&
$childNode['l'] > $node['l'] &&
$childNode['r'] < $node['r'] &&
$childNode['rootid'] == $node['rootid']) {
// important that we assign it by reference here, so that when the child
// marks itself 'hit' the parent loops will know
$children[] =& $params['structure'][$childKey];
}
}
 
$recurseParams = $params;
$recurseParams['structure'] = $children;
$recurseParams['treeMenu'] =& $parentNode;
$recurseParams['currentLevel']++;
$this->_createFromStructure($recurseParams);
}
}
 
return $treeMenu;
}
 
// }}}
// {{{ printTree()
 
/**
* Print's the current tree using the output driver
*
* @access public
*/
function printTree() {
$options = $this->_getOptions('printTree');
$tree =& new HTML_TreeMenu_DHTML($this->_structTreeMenu, $options);
$tree->printMenu();
}
 
// }}}
// {{{ printListbox()
 
/**
* Print's a listbox representing the current tree
*
* @access public
*/
function printListbox() {
$options = $this->_getOptions('printListbox');
$listBox =& new HTML_TreeMenu_Listbox($this->_structTreeMenu, $options);
$listBox->printMenu();
}
// }}}
 
// }}}
// {{{ tree_toHTML()
 
/**
* Returns the HTML for the DHTML-menu. This method can be
* used instead of printMenu() to use the menu system
* with a template system.
*
* @access public
* @return string The HTML for the menu
* @Author Emanuel Zueger
*/
function tree_toHTML() {
$options = $this->_getOptions('toHTML');
$tree =& new HTML_TreeMenu_DHTML($this->_structTreeMenu, $options);
return $tree->toHTML();
}
 
// }}}
// {{{ listbox_toHTML()
 
/**
* Returns the HTML for the listbox. This method can be
* used instead of printListbox() to use the menu system
* with a template system.
*
* @access public
* @return string The HTML for the listbox
* @author Emanuel Zueger
*/
function listbox_toHTML() {
$options = $this->_getOptions('toHTML');
$listBox =& new HTML_TreeMenu_Listbox($this->_structTreeMenu, $options);
return $listBox->toHTML();
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/NestedSet/DB.php
New file
0,0 → 1,135
<?php
//
// +----------------------------------------------------------------------+
// | PEAR :: DB_NestedSet_DB |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Daniel Khan <dk@webcluster.at> |
// +----------------------------------------------------------------------+
//
// $Id: DB.php,v 1.7 2003/10/07 00:11:27 datenpunk Exp $
//
 
require_once 'DB.php';
 
// {{{ DB_NestedSet_DB:: class
 
/**
* Wrapper class for PEAR::DB
*
* @author Daniel Khan <dk@webcluster.at>
* @package DB_NestedSet
* @version $Revision: 1.7 $
* @access public
*/
 
// }}}
class DB_NestedSet_DB extends DB_NestedSet {
// {{{ properties
 
/**
* @var object Db object
*/
var $db;
 
// }}}
// {{{ constructor
 
/**
* Constructor
*
* @param mixed $dsn DSN as PEAR dsn URI or dsn Array
* @param array $params Database column fields which should be returned
*
*/
function DB_NestedSet_DB($dsn, $params = array())
{
$this->_debugMessage('DB_NestedSet_DB($dsn, $params = array())');
$this->DB_NestedSet($params);
$this->db =& $this->_db_Connect($dsn);
$this->db->setFetchMode(DB_FETCHMODE_ASSOC);
}
 
// }}}
// {{{ destructor
 
/**
* Destructor
*/
function _DB_NestedSet_DB()
{
$this->_debugMessage('_DB_NestedSet_DB()');
$this->_DB_NestedSet();
$this->_db_Disconnect();
}
 
// }}}
// {{{ _db_Connect()
 
/**
* Connects to the db
*
* @return object DB The database object
* @access private
*/
function &_db_Connect($dsn)
{
$this->_debugMessage('_db_Connect($dsn)');
if (is_object($this->db)) {
return $this->db;
}
 
$db =& DB::connect($dsn);
$this->_testFatalAbort($db, __FILE__, __LINE__);
return $db;
}
 
// }}}
 
 
function _numRows($res) {
return $res->numRows();
}
 
function _isDBError($err) {
if(!DB::isError($err)) {
return false;
}
return true;
}
 
function _quote($str) {
return $this->db->quote($str);
}
 
// {{{ _db_Disconnect()
 
/**
* Disconnects from db
*
* @return void
* @access private
*/
function _db_Disconnect()
{
$this->_debugMessage('_db_Disconnect()');
if (is_object($this->db)) {
@$this->db->disconnect();
}
 
return true;
}
 
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/NestedSet/TigraMenu.php
New file
0,0 → 1,402
<?php
//
// +----------------------------------------------------------------------+
// | PEAR :: DB_NestedSet_TigraMenu |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Daniel Khan <dk@webcluster.at> |
// +----------------------------------------------------------------------+
//
// $Id: TigraMenu.php,v 1.8 2003/10/07 00:11:27 datenpunk Exp $
//
 
// {{{ DB_NestedSet_TigraMenu:: class
 
/**
* This class can be used to generate the data to build javascript popup menu
* from a DB_NestedSet node array.
* The Javascript part is done using the free available TigraMenu
* available at http://www.softcomplex.com/products/tigra_menu/.
* Currently version 1.0 is supported.
* Parts of this class where taken ftom the TreemMenu driver by Jason Rust
*
* @author Daniel Khan <dk@webcluster.at>
* @package DB_NestedSet
* @version $Revision: 1.8 $
* @access public
*/
// }}}
class DB_NestedSet_TigraMenu extends DB_NestedSet_Output {
// {{{{ properties
 
/**
* @var integer The depth of the current menu.
* @access private
*/
var $_levels = 1;
 
/**
* @var integer The level we started at
* @access private
*/
var $_levelOffset = false;
 
 
/**
* @var array The current menu structure
* @access private
*/
var $_structTigraMenu = false;
 
/**
* @var array The longest text for each level
* @access private
*/
var $_strlenByLevel = array();
 
// }}}
// {{{ DB_NestedSet_TigraMenu
 
/**
* Constructor
*
* @param array $params A hash with parameters needed by the class
* @see _createFromStructure()
* @return bool
**/
function &DB_NestedSet_TigraMenu($params) {
$this->_menu_id = $params['menu_id'];
$this->_structTigraMenu = $this->_createFromStructure($params);
return true;
}
 
// }}}
// {{{ _createFromStructure()
 
/**
* Creates the JavaScript array for TigraMenu
* Initially this method was introduced for the TreeMenu driver by Jason Rust
*
* o 'structure' => the result from $nestedSet->getAllNodes(true)
* o 'textField' => the field in the table that has the text for node
* o 'linkField' => the field in the table that has the link for the node
*
* @access private
* @return string The TigraMenu JavaScript array
*/
function &_createFromStructure($params)
{
// Basically we go through the array of nodes checking to see
// if each node has children and if so recursing. The reason this
// works is because the data from getAllNodes() is ordered by level
// so a root node will always be first, and sub children will always
// be after them.
 
static $rootlevel;
 
// always start at level 1
if (!isset($params['currentLevel'])) {
$params['currentLevel'] = 1;
}
 
if (!isset($rootlevel)) {
$rootlevel = $params['currentLevel'];
}
 
if (isset($params['tigraMenu'])) {
$tigraMenu = $tigraMenu.$params['tigraMenu'];
}
 
if(!$this->_levelOffset) {
$this->_levelOffset = $params['currentLevel'];
}
 
if($this->_levels < ($params['currentLevel']- $this->_levelOffset)) {
$this->_levels = $params['currentLevel'] - $this->_levelOffset;
}
 
 
// have to use a while loop here because foreach works on a copy of the array and
// the child nodes are passed by reference during the recursion so that the parent
// will know when they have been hit.
reset($params['structure']);
while(list($key, $node) = each($params['structure'])) {
// see if we've already been here before
if (isset($node['hit']) || $node['level'] < $params['currentLevel']) {
continue;
}
 
// mark that we've hit this node
$params['structure'][$key]['hit'] = $node['hit'] = true;
 
$tag = array(
isset($node[$params['textField']]) ? "'".$node[$params['textField']]."'" : 'null',
isset($node[$params['linkField']]) ? "'".$node[$params['linkField']]."'" : 'null'
);
 
if (!$this->_strlenByLevel[$params['currentLevel'] - $this->_levelOffset] ||
strlen($node[$params['textField']]) > $this->_strlenByLevel[$params['currentLevel'] - $this->_levelOffset]) {
$this->_strlenByLevel[$params['currentLevel'] - $this->_levelOffset] = strlen($node[$params['textField']]);
};
 
$tigraMenu = $tigraMenu.$this->_openSubMenu($tag);
 
// see if it has children
if (($node['r'] - 1) != $node['l']) {
$children = array();
// harvest all the children
$tempStructure = $params['structure'];
foreach ($tempStructure as $childKey => $childNode) {
if (!isset($childNode['hit']) &&
$node['rootid'] == $childNode['rootid'] &&
$node['l'] < $childNode['l'] &&
$node['r'] > $childNode['r'] &&
$childNode['level'] > $params['currentLevel']) {
// important that we assign it by reference here, so that when the child
// marks itself 'hit' the parent loops will know
$children[] =& $params['structure'][$childKey];
}
}
 
$recurseParams = $params;
$recurseParams['structure'] = $children;
$recurseParams['currentLevel']++;
$tigraMenu = $tigraMenu.$this->_createFromStructure($recurseParams);
}
 
$tigraMenu = $tigraMenu.$this->_closeSubMenu();
}
return $tigraMenu;
}
 
// }}}
// {{{ _openMenu()
 
/**
* Returns the string which opens the JavaScript menu
*
* @access private
* @param int $menu_id ID of the menu needed to use more than one menu on a page
* @return string The JavaScript piece
*/
function _openMenu($menu_id=1)
{
$str = false;
$str = $str."var MENU_ITEMS".$menu_id." = new Array();\n";
$str = $str."MENU_ITEMS".$menu_id." = [\n";
return $str;
}
 
// }}}
// {{{ _openSubMenu()
 
/**
* Returns the string which opens a submenu within the JavaScript menu
*
* @access private
* @param array $tag Contains the content of the current item (name, link)
* @return string The JavaScript piece
*/
function _openSubMenu($tag)
{
$rtag = implode(', ', $tag);
return "\n[".$rtag.',';
}
 
// }}}
// {{{ _closeMenu()
 
/**
* Closes the JavaScript array
*
* @access private
* @return string The JavaScript piece
*/
function _closeMenu()
{
 
return '];';
}
 
// }}}
// {{{ _closeSubMenu()
 
/**
* Closes the JavaScript array of a submenu
*
* @access private
* @return string The JavaScript piece
*/
function _closeSubMenu()
{
return "\n],";
}
 
// }}}
// {{{ _addStyles()
 
/**
* Creates the JavaScript code which sets the styles for each level
*
* @access private
* @param int $menu_id ID of the menu needed to use more than one menu on a page
* @param array $rootStyles Array of style attributes for the top items
* @param array $childStyles Array of style attributes for the sub items
* @return string The JavaScript piece
*/
function _addStyles($menu_id, $rootStyles, $childStyles = false)
{
if (!$childStyles) {
$childStyles = $rootStyles;
}
 
$styles = array();
foreach ($rootStyles as $key => $val) {
foreach ($val as $skey => $sval) {
$styles["'$key'"][$skey][] = "'$sval'";
}
}
 
foreach ($childStyles as $key => $val) {
foreach ($val as $skey => $sval) {
for ($i = 1; $i <= $this->_levels; $i++) {
$styles["'$key'"][$skey][] = "'$sval'";
}
}
}
 
$menustyles = false;
$menustyles = $menustyles . 'var MENU_STYLES'.$menu_id." = new Array();\n";
foreach ($styles as $key => $val) {
$menustyles = $menustyles.'MENU_STYLES'.$menu_id."[$key] = [\n";
foreach ($val as $skey => $sval) {
$menustyles = $menustyles . "'$skey', [".implode(', ', $sval)."],\n";
}
$menustyles = $menustyles."];\n";
}
 
return $menustyles;
}
 
// }}}
// {{{ _addGeometry()
 
/**
* Creates the JavaScript code which sets the position and geometry of the menu
*
* @access private
* @param int $menu_id ID of the menu needed to use more than one menu on a page
* @param array $rootGeometry Array of geometry attributes for the top items
* @param array $childGeometry Array of geometry attributes for the sub items
* @return string The JavaScript piece
*/
function _addGeometry($menu_id, $rootGeometry, $childGeometry = false)
{
if (!$childGeometry) {
$childGeometry = $rootGeometry;
}
 
$params = array();
$geometry = array();
foreach ($rootGeometry as $key => $val) {
$geometry["'$key'"][] = $val;
$incr = false;
if (strpos($val, ',') !== false) {
list($start, $interval) = explode(',',$val);
$incr = true;
}
 
$ratio = false;
if ($key == 'width' && strpos($val, '*') !== false) {
$ratio = trim(str_replace('*','', $val));
}
if ($incr) {
$val = trim($interval);
if ($key == 'left' && preg_match('/[+-]/', $interval)) {
$val = $params[0]['width'] + trim($val);
}
} elseif ($incr) {
$val = trim($start);
} elseif ($ratio) {
$val = $ratio * $this->_strlenByLevel[0];
}
$geometry["'$key'"][0] = $val;
$params[0][$key] = $val;
}
 
foreach($childGeometry as $key => $val) {
$incr = false;
if (strpos($val, ',') !== false) {
list($start, $interval) = explode(',', $val);
$incr = true;
}
 
$ratio = false;
if ($key == 'width' && strpos($val, '*') !== false) {
$ratio = trim(str_replace('*', '', $val));
}
 
for ($i = 1; $i <= $this->_levels; $i++) {
if ($incr && isset($lastval[$key])) {
$val = trim($interval);
if($key == 'block_left' && preg_match('/[+-]/', $interval)) {
$val = $params[$i - 1]['width'] + trim($val);
}
} elseif($incr) {
$val = trim($start);
} elseif ($ratio) {
$val = $ratio * $this->_strlenByLevel[$i];
if($val < $params[0]['width']) {
$val = $params[0]['width'];
}
}
 
$lastval[$key] = $val;
$geometry["'$key'"][] = $val;
$params[$i][$key] = $val;
}
 
}
 
$pos = false;
$pos = $pos . 'var MENU_POS'.$menu_id." = new Array();\n";
foreach ($geometry as $key => $val) {
$pos = $pos . 'MENU_POS' . $menu_id . "[$key] = [" . implode(', ', $val) . "];\n";
}
 
return $pos;
}
 
// }}}
// {{{ printTree()
 
/**
* Print's the current tree using the output driver
*
* @access public
*/
function printTree()
{
if (!$options = $this->_getOptions('printTree')) {
return PEAR::raiseError("TigraMenu::printTree() needs options. See TigraMenu::setOptions()", NESEO_ERROR_NO_OPTIONS, PEAR_ERROR_TRIGGER, E_USER_ERROR);
}
 
echo $this->_openMenu($options['menu_id']) . $this->_structTigraMenu .$this->_closeMenu();
echo "\n\n";
echo $this->_addStyles($options['menu_id'], $options['rootStyles'], $options['childStyles']);
echo "\n\n";
echo $this->_addGeometry($options['menu_id'], $options['rootGeometry'], $options['childGeometry']);
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/NestedSet/Output.php
New file
0,0 → 1,211
<?php
//
// +----------------------------------------------------------------------+
// | PEAR :: DB_NestedSet_Output |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Daniel Khan <dk@webcluster.at> |
// | Jason Rust <jason@rustyparts.com> |
// +----------------------------------------------------------------------+
// $Id: Output.php,v 1.11 2003/10/07 00:11:27 datenpunk Exp $
//
 
require_once 'PEAR.php';
 
// {{{ constants
 
define('NESEO_ERROR_NO_METHOD', 'E1000');
define('NESEO_DRIVER_NOT_FOUND', 'E1100');
define('NESEO_ERROR_NO_OPTIONS', 'E2100');
 
// }}}
// {{{ DB_NestedSet_Output:: class
 
/**
* DB_NestedSet_Output is a unified API for other output drivers
* Status is beta
*
* At the moment PEAR::HTML_TreeMenu written by Jason Rust is supported
* A driver for treemenu.org will follow soon.
*
* Usage example:
*
* require_once('DB_NestedSet/NestedSet/Output.php');
* $icon = 'folder.gif';
* $expandedIcon = 'folder-expanded.gif';
* // get data (important to fetch it as an array, using the true flag)
* $data = $NeSe->getAllNodes(true);
* // change the events for one of the elements
* $data[35]['events'] = array('onexpand' => 'alert("we expanded!");');
* // add links to each item
* foreach ($data as $a_data) {
* $a_data['link'] = 'http://foo.com/foo.php?' . $a_data['id'];
* }
* $params = array(
* 'structure' => $data,
* 'options' => array(
* 'icon' => $icon,
* 'expandedIcon' => $expandedIcon,
* ),
* 'textField' => 'name',
* 'linkField' => 'link',
* );
* $menu =& DB_NestedSet_Output::factory('TreeMenu', $params);
* $menu->printListbox();
*
* @author Daniel Khan <dk@webcluster.at>
* @package DB_NestedSet
* @version $Revision: 1.11 $
* @access public
*
*/
 
// }}}
class DB_NestedSet_Output {
// {{{ properties
 
/**
* @var object The tree menu structure
* @access private
*/
var $_structTreeMenu = false;
 
/**
* @var array Array of options to be passed to the ouput methods
* @access public
*/
var $options = array();
 
// }}}
// {{{ factory()
 
/**
* Returns a output driver object
*
* @param array $params A DB_NestedSet nodeset
* @param string $driver (optional) The driver, such as TreeMenu (default)
*
* @access public
* @return object The DB_NestedSet_Ouput object
*/
function &factory ($params, $driver = 'TreeMenu') {
 
$path = dirname(__FILE__).'/'.$driver.'.php';
 
if(is_dir($path) || !file_exists($path)) {
PEAR::raiseError("The output driver '$driver' wasn't found", NESEO_DRIVER_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR);
}
 
require_once($path);
$driverClass = 'DB_NestedSet_'.$driver;
return new $driverClass($params);
}
 
// }}}
// {{{ setOptions()
 
/**
* Set's options for a specific output group (printTree, printListbox)
* This enables you to set specific options for each output method
*
* @param string $group Output group ATM 'printTree' or 'printListbox'
* @param array $options Hash with options
*
* @access public
* @return bool
*/
function setOptions($group, $options) {
$this->options[$group] = $options;
return true;
}
 
// }}}
// {{{ _getOptions()
 
/**
* Get's all option for a specific output group (printTree, printListbox)
*
* @param string $group Output group ATM 'printTree' or 'printListbox'
*
* @access private
* @return array Options
*/
function _getOptions($group) {
 
if (!isset($this->options[$group])) {
return array();
}
return $this->options[$group];
}
 
// }}}
// {{{ printTree()
 
/**
* Print's the current tree using the output driver
* Overriden by the driver class
*
* @access public
*/
function printTree() {
PEAR::raiseError("Method not available for this driver", NESEO_ERROR_NO_METHOD, PEAR_ERROR_TRIGGER, E_USER_ERROR);
}
 
// }}}
// {{{ printListbox()
 
/**
* Print's a listbox representing the current tree
* Overriden by the driver class
*
* @access public
*/
function printListbox() {
PEAR::raiseError("Method not available for this driver", NESEO_ERROR_NO_METHOD, PEAR_ERROR_TRIGGER, E_USER_ERROR);
}
 
// }}}
 
// {{{ toHTML()
 
/**
* Returns the HTML for the DHTML-menu. This method can be
* used instead of printMenu() to use the menu system
* with a template system.
*
* @access public
* @return string The HTML for the menu
* @author Emanuel Zueger
*/
function tree_toHTML() {
PEAR::raiseError("Method not available for this driver", NESEO_ERROR_NO_METHOD, PEAR_ERROR_TRIGGER, E_USER_ERROR);
}
 
// }}}
// {{{ listbox_toHTML()
 
/**
* Returns the HTML for the listbox. This method can be
* used instead of printListbox() to use the menu system
* with a template system.
*
* @access public
* @return string The HTML for the listbox
* @author Emanuel Zueger
*/
function listbox_toHTML() {
PEAR::raiseError("Method not available for this driver", NESEO_ERROR_NO_METHOD, PEAR_ERROR_TRIGGER, E_USER_ERROR);
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/DataObject/Generator.php
New file
0,0 → 1,929
<?php
/**
* Generation tools for DB_DataObject
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_DataObject
* @author Alan Knowles <alan@akbkhome.com>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Generator.php,v 1.96 2005/06/16 02:03:45 alan_k Exp $
* @link http://pear.php.net/package/DB_DataObject
*/
/**
*
* Config _$ptions
* [DB_DataObject_Generator]
* ; optional default = DB/DataObject.php
* extends_location =
* ; optional default = DB_DataObject
* extends =
* ; alter the extends field when updating a class (defaults to only replacing DB_DataObject)
* generator_class_rewrite = ANY|specific_name // default is DB_DataObject
*
*/
 
/**
* Needed classes
*/
require_once 'DB/DataObject.php';
//require_once('Config.php');
 
/**
* Generator class
*
* @package DB_DataObject
*/
class DB_DataObject_Generator extends DB_DataObject
{
/* =========================================================== */
/* Utility functions - for building db config files */
/* =========================================================== */
 
/**
* Array of table names
*
* @var array
* @access private
*/
var $tables;
 
/**
* associative array table -> array of table row objects
*
* @var array
* @access private
*/
var $_definitions;
 
/**
* active table being output
*
* @var string
* @access private
*/
var $table; // active tablename
 
 
/**
* The 'starter' = call this to start the process
*
* @access public
* @return none
*/
function start()
{
$options = &PEAR::getStaticProperty('DB_DataObject','options');
$databases = array();
foreach($options as $k=>$v) {
if (substr($k,0,9) == 'database_') {
$databases[substr($k,9)] = $v;
}
}
 
if (@$options['database']) {
require_once 'DB.php';
$dsn = DB::parseDSN($options['database']);
if (!isset($database[$dsn['database']])) {
$databases[$dsn['database']] = $options['database'];
}
}
 
foreach($databases as $databasename => $database) {
if (!$database) {
continue;
}
$this->debug("CREATING FOR $databasename\n");
$class = get_class($this);
$t = new $class;
$t->_database_dsn = $database;
$t->_database = $databasename;
$dsn = DB::parseDSN($database);
if (($dsn['phptype'] == 'sqlite') && is_file($databasename)) {
$t->_database = basename($t->_database);
}
$t->_createTableList();
 
foreach(get_class_methods($class) as $method) {
if (substr($method,0,8 ) != 'generate') {
continue;
}
$this->debug("calling $method");
$t->$method();
}
}
$this->debug("DONE\n\n");
}
 
/**
* Output File was config object, now just string
* Used to generate the Tables
*
* @var string outputbuffer for table definitions
* @access private
*/
var $_newConfig;
 
/**
* Build a list of tables;
* Currently this is very Mysql Specific - ideas for more generic stiff welcome
*
* @access private
* @return none
*/
function _createTableList()
{
$this->_connect();
$options = &PEAR::getStaticProperty('DB_DataObject','options');
 
$__DB= &$GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'][$this->_database_dsn_md5];
// try getting a list of schema tables first. (postgres)
$__DB->expectError(DB_ERROR_UNSUPPORTED);
$this->tables = $__DB->getListOf('schema.tables');
$__DB->popExpect();
if (empty($this->tables) || is_a($this->tables , 'PEAR_Error')) {
//if that fails fall back to clasic tables list.
$this->tables = $__DB->getListOf('tables');
}
if (is_a($this->tables , 'PEAR_Error')) {
return PEAR::raiseError($this->tables->toString(), null, PEAR_ERROR_DIE);
}
// build views as well if asked to.
if (!empty($options['build_views'])) {
$views = $__DB->getListOf('views');
if (is_a($views,'PEAR_Error')) {
return PEAR::raiseError(
'Error getting Views (check the PEAR bug database for the fix to DB), ' .
$views->toString(),
null,
PEAR_ERROR_DIE
);
}
$this->tables = array_merge ($this->tables, $views);
}
// declare a temporary table to be filled with matching tables names
$tmp_table = array();
 
 
foreach($this->tables as $table) {
if (isset($options['generator_include_regex']) &&
!preg_match($options['generator_include_regex'],$table)) {
continue;
} else if (isset($options['generator_exclude_regex']) &&
preg_match($options['generator_exclude_regex'],$table)) {
continue;
}
// postgres strip the schema bit from the
if (!empty($options['generator_strip_schema'])) {
$bits = explode('.', $table,2);
$table = $bits[0];
if (count($bits) > 1) {
$table = $bits[1];
}
}
$defs = $__DB->tableInfo($table);
if (is_a($defs,'PEAR_Error')) {
echo $defs->toString();
exit;
}
// cast all definitions to objects - as we deal with that better.
foreach($defs as $def) {
if (!is_array($def)) {
continue;
}
$this->_definitions[$table][] = (object) $def;
}
// we find a matching table, just store it into a temporary array
$tmp_table[] = $table;
}
// the temporary table array is now the right one (tables names matching
// with regex expressions have been removed)
$this->tables = $tmp_table;
//print_r($this->_definitions);
}
 
/**
* Auto generation of table data.
*
* it will output to db_oo_{database} the table definitions
*
* @access private
* @return none
*/
function generateDefinitions()
{
$this->debug("Generating Definitions file: ");
if (!$this->tables) {
$this->debug("-- NO TABLES -- \n");
return;
}
 
$options = &PEAR::getStaticProperty('DB_DataObject','options');
 
 
//$this->_newConfig = new Config('IniFile');
$this->_newConfig = '';
foreach($this->tables as $this->table) {
$this->_generateDefinitionsTable();
}
$this->_connect();
// dont generate a schema if location is not set
// it's created on the fly!
if (!@$options['schema_location'] && @!$options["ini_{$this->_database}"] ) {
return;
}
$base = @$options['schema_location'];
if (isset($options["ini_{$this->_database}"])) {
$file = $options["ini_{$this->_database}"];
} else {
$file = "{$base}/{$this->_database}.ini";
}
if (!file_exists(dirname($file))) {
require_once 'System.php';
System::mkdir(array('-p','-m',0755,dirname($file)));
}
$this->debug("Writing ini as {$file}\n");
touch($file);
//print_r($this->_newConfig);
$fh = fopen($file,'w');
fwrite($fh,$this->_newConfig);
fclose($fh);
//$ret = $this->_newConfig->writeInput($file,false);
 
//if (PEAR::isError($ret) ) {
// return PEAR::raiseError($ret->message,null,PEAR_ERROR_DIE);
// }
}
 
/**
* The table geneation part
*
* @access private
* @return tabledef and keys array.
*/
function _generateDefinitionsTable()
{
global $_DB_DATAOBJECT;
$defs = $this->_definitions[$this->table];
$this->_newConfig .= "\n[{$this->table}]\n";
$keys_out = "\n[{$this->table}__keys]\n";
$keys_out_primary = '';
$keys_out_secondary = '';
if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 2) {
echo "TABLE STRUCTURE FOR {$this->table}\n";
print_r($defs);
}
$DB = $this->getDatabaseConnection();
$dbtype = $DB->phptype;
$ret = array(
'table' => array(),
'keys' => array(),
);
$ret_keys_primary = array();
$ret_keys_secondary = array();
foreach($defs as $t) {
$n=0;
 
switch (strtoupper($t->type)) {
 
case 'INT':
case 'INT2': // postgres
case 'INT4': // postgres
case 'INT8': // postgres
case 'SERIAL4': // postgres
case 'SERIAL8': // postgres
case 'INTEGER':
case 'TINYINT':
case 'SMALLINT':
case 'MEDIUMINT':
case 'BIGINT':
$type = DB_DATAOBJECT_INT;
if ($t->len == 1) {
$type += DB_DATAOBJECT_BOOL;
}
break;
case 'REAL':
case 'DOUBLE':
case 'FLOAT':
case 'FLOAT8': // double precision (postgres)
case 'DECIMAL':
case 'NUMERIC':
case 'NUMBER': // oci8
$type = DB_DATAOBJECT_INT; // should really by FLOAT!!! / MONEY...
break;
case 'YEAR':
$type = DB_DATAOBJECT_INT;
break;
case 'BIT':
case 'BOOL':
case 'BOOLEAN':
$type = DB_DATAOBJECT_BOOL;
// postgres needs to quote '0'
if ($dbtype == 'pgsql') {
$type += DB_DATAOBJECT_STR;
}
break;
case 'STRING':
case 'CHAR':
case 'VARCHAR':
case 'VARCHAR2':
case 'TINYTEXT':
case 'ENUM':
case 'SET': // not really but oh well
case 'TIMESTAMPTZ': // postgres
case 'BPCHAR': // postgres
case 'INTERVAL': // postgres (eg. '12 days')
case 'CIDR': // postgres IP net spec
case 'INET': // postgres IP
case 'MACADDR': // postgress network Mac address.
$type = DB_DATAOBJECT_STR;
break;
case 'TEXT':
case 'MEDIUMTEXT':
case 'LONGTEXT':
$type = DB_DATAOBJECT_STR + DB_DATAOBJECT_TXT;
break;
case 'DATE':
$type = DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE;
break;
case 'TIME':
$type = DB_DATAOBJECT_STR + DB_DATAOBJECT_TIME;
break;
case 'DATETIME':
$type = DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME;
break;
case 'TIMESTAMP': // do other databases use this???
$type = ($dbtype == 'mysql') ?
DB_DATAOBJECT_MYSQLTIMESTAMP :
DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME;
break;
case 'TINYBLOB':
case 'BLOB': /// these should really be ignored!!!???
case 'MEDIUMBLOB':
case 'LONGBLOB':
case 'BYTEA': // postgres blob support..
$type = DB_DATAOBJECT_STR + DB_DATAOBJECT_BLOB;
break;
}
if (!strlen(trim($t->name))) {
continue;
}
if (preg_match('/not_null/i',$t->flags)) {
$type += DB_DATAOBJECT_NOTNULL;
}
$write_ini = true;
if (in_array($t->name,array('null','yes','no','true','false'))) {
echo "*****************************************************************\n".
"** WARNING **\n".
"** Found column '{$t->name}', which is invalid in an .ini file **\n".
"** This line will not be writen to the file - you will have **\n".
"** define the keys()/method manually. **\n".
"*****************************************************************\n";
$write_ini = false;
} else {
$this->_newConfig .= "{$t->name} = $type\n";
}
$ret['table'][$t->name] = $type;
// i've no idea if this will work well on other databases?
// only use primary key or nextval(), cause the setFrom blocks you setting all key items...
// if no keys exist fall back to using unique
//echo "\n{$t->name} => {$t->flags}\n";
if (preg_match("/(auto_increment|nextval\()/i",rawurldecode($t->flags))) {
// native sequences = 2
if ($write_ini) {
$keys_out_primary .= "{$t->name} = N\n";
}
$ret_keys_primary[$t->name] = 'N';
} else if (preg_match("/(primary|unique)/i",$t->flags)) {
// keys.. = 1
if ($write_ini) {
$keys_out_secondary .= "{$t->name} = K\n";
}
$ret_keys_secondary[$t->name] = 'K';
}
}
$this->_newConfig .= $keys_out . (empty($keys_out_primary) ? $keys_out_secondary : $keys_out_primary);
$ret['keys'] = empty($keys_out_primary) ? $ret_keys_secondary : $ret_keys_primary;
if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 2) {
print_r(array("dump for {$this->table}", $ret));
}
return $ret;
}
 
/*
* building the class files
* for each of the tables output a file!
*/
function generateClasses()
{
//echo "Generating Class files: \n";
$options = &PEAR::getStaticProperty('DB_DataObject','options');
$base = $options['class_location'];
if (strpos($base,'%s') !== false) {
$base = dirname($base);
}
if (!file_exists($base)) {
require_once 'System.php';
System::mkdir(array('-p',$base));
}
$class_prefix = $options['class_prefix'];
if ($extends = @$options['extends']) {
$this->_extends = $extends;
$this->_extendsFile = $options['extends_location'];
}
 
foreach($this->tables as $this->table) {
$this->table = trim($this->table);
$this->classname = $class_prefix.preg_replace('/[^A-Z0-9]/i','_',ucfirst($this->table));
$i = '';
if (strpos($options['class_location'],'%s') !== false) {
$outfilename = sprintf($options['class_location'], preg_replace('/[^A-Z0-9]/i','_',ucfirst($this->table)));
} else {
$outfilename = "{$base}/".preg_replace('/[^A-Z0-9]/i','_',ucfirst($this->table)).".php";
}
$oldcontents = '';
if (file_exists($outfilename)) {
// file_get_contents???
$oldcontents = implode('',file($outfilename));
}
$out = $this->_generateClassTable($oldcontents);
$this->debug( "writing $this->classname\n");
$fh = fopen($outfilename, "w");
fputs($fh,$out);
fclose($fh);
}
//echo $out;
}
 
/**
* class being extended (can be overridden by [DB_DataObject_Generator] extends=xxxx
*
* @var string
* @access private
*/
var $_extends = 'DB_DataObject';
 
/**
* line to use for require('DB/DataObject.php');
*
* @var string
* @access private
*/
var $_extendsFile = "DB/DataObject.php";
 
/**
* class being generated
*
* @var string
* @access private
*/
var $_className;
 
/**
* The table class geneation part - single file.
*
* @access private
* @return none
*/
function _generateClassTable($input = '')
{
// title = expand me!
$foot = "";
$head = "<?php\n/**\n * Table Definition for {$this->table}\n */\n";
// requires
$head .= "require_once '{$this->_extendsFile}';\n\n";
// add dummy class header in...
// class
$head .= "class {$this->classname} extends {$this->_extends} \n{";
 
$body = "\n ###START_AUTOCODE\n";
$body .= " /* the code below is auto generated do not remove the above tag */\n\n";
// table
$padding = (30 - strlen($this->table));
if ($padding < 2) $padding =2;
$p = str_repeat(' ',$padding) ;
$options = &PEAR::getStaticProperty('DB_DataObject','options');
$var = (substr(phpversion(),0,1) > 4) ? 'public' : 'var';
$body .= " {$var} \$__table = '{$this->table}'; {$p}// table name\n";
// if we are using the option database_{databasename} = dsn
// then we should add var $_database = here
// as database names may not always match..
if (isset($options["database_{$this->_database}"])) {
$body .= " {$var} \$_database = '{$this->_database}'; {$p}// database name (used with database_{*} config)\n";
}
$var = (substr(phpversion(),0,1) > 4) ? 'public' : 'var';
if (!empty($options['generator_novars'])) {
$var = '//'.$var;
}
$defs = $this->_definitions[$this->table];
 
// show nice information!
$connections = array();
$sets = array();
foreach($defs as $t) {
if (!strlen(trim($t->name))) {
continue;
}
$padding = (30 - strlen($t->name));
if ($padding < 2) $padding =2;
$p = str_repeat(' ',$padding) ;
$body .=" {$var} \${$t->name}; {$p}// {$t->type}({$t->len}) {$t->flags}\n";
// can not do set as PEAR::DB table info doesnt support it.
//if (substr($t->Type,0,3) == "set")
// $sets[$t->Field] = "array".substr($t->Type,3);
$body .= $this->derivedHookVar($t,$padding);
}
 
// THIS IS TOTALLY BORKED old FC creation
// IT WILL BE REMOVED!!!!! in DataObjects 1.6
// grep -r __clone * to find all it's uses
// and replace them with $x = clone($y);
// due to the change in the PHP5 clone design.
if ( substr(phpversion(),0,1) < 5) {
$body .= "\n";
$body .= " /* ZE2 compatibility trick*/\n";
$body .= " function __clone() { return \$this;}\n";
}
 
// simple creation tools ! (static stuff!)
$body .= "\n";
$body .= " /* Static get */\n";
$body .= " function staticGet(\$k,\$v=NULL) { return DB_DataObject::staticGet('{$this->classname}',\$k,\$v); }\n";
// generate getter and setter methods
$body .= $this->_generateGetters($input);
$body .= $this->_generateSetters($input);
/*
theoretically there is scope here to introduce 'list' methods
based up 'xxxx_up' column!!! for heiracitcal trees..
*/
 
// set methods
//foreach ($sets as $k=>$v) {
// $kk = strtoupper($k);
// $body .=" function getSets{$k}() { return {$v}; }\n";
//}
$body .= $this->derivedHookFunctions();
 
$body .= "\n /* the code above is auto generated do not remove the tag below */";
$body .= "\n ###END_AUTOCODE\n";
 
 
// stubs..
if (!empty($options['generator_add_validate_stubs'])) {
foreach($defs as $t) {
if (!strlen(trim($t->name))) {
continue;
}
$validate_fname = 'validate' . ucfirst(strtolower($t->name));
// dont re-add it..
if (preg_match('/\s+function\s+' . $validate_fname . '\s*\(/i', $input)) {
continue;
}
$body .= "\n function {$validate_fname}()\n {\n return false;\n }\n";
}
}
 
 
 
 
$foot .= "}\n";
$full = $head . $body . $foot;
 
if (!$input) {
return $full;
}
if (!preg_match('/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n)/s',$input)) {
return $full;
}
if (!preg_match('/(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s',$input)) {
return $full;
}
 
 
/* this will only replace extends DB_DataObject by default,
unless use set generator_class_rewrite to ANY or a name*/
 
$class_rewrite = 'DB_DataObject';
$options = &PEAR::getStaticProperty('DB_DataObject','options');
if (!($class_rewrite = @$options['generator_class_rewrite'])) {
$class_rewrite = 'DB_DataObject';
}
if ($class_rewrite == 'ANY') {
$class_rewrite = '[a-z_]+';
}
 
$input = preg_replace(
'/(\n|\r\n)class\s*[a-z0-9_]+\s*extends\s*' .$class_rewrite . '\s*\{(\n|\r\n)/si',
"\nclass {$this->classname} extends {$this->_extends} \n{\n",
$input);
 
return preg_replace(
'/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n).*(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s',
$body,$input);
}
 
/**
* hook to add extra methods to all classes
*
* called once for each class, use with $this->table and
* $this->_definitions[$this->table], to get data out of the current table,
* use it to add extra methods to the default classes.
*
* @access public
* @return string added to class eg. functions.
*/
function derivedHookFunctions()
{
// This is so derived generator classes can generate functions
// It MUST NOT be changed here!!!
return "";
}
 
/**
* hook for var lines
* called each time a var line is generated, override to add extra var
* lines
*
* @param object t containing type,len,flags etc. from tableInfo call
* @param int padding number of spaces
* @access public
* @return string added to class eg. functions.
*/
function derivedHookVar(&$t,$padding)
{
// This is so derived generator classes can generate variabels
// It MUST NOT be changed here!!!
return "";
}
 
 
/**
* getProxyFull - create a class definition on the fly and instantate it..
*
* similar to generated files - but also evals the class definitoin code.
*
*
* @param string database name
* @param string table name of table to create proxy for.
*
*
* @return object Instance of class. or PEAR Error
* @access public
*/
function getProxyFull($database,$table) {
if ($err = $this->fillTableSchema($database,$table)) {
return $err;
}
$options = &PEAR::getStaticProperty('DB_DataObject','options');
$class_prefix = $options['class_prefix'];
if ($extends = @$options['extends']) {
$this->_extends = $extends;
$this->_extendsFile = $options['extends_location'];
}
 
$classname = $this->classname = $class_prefix.preg_replace('/[^A-Z0-9]/i','_',ucfirst(trim($this->table)));
 
$out = $this->_generateClassTable();
//echo $out;
eval('?>'.$out);
return new $classname;
}
/**
* fillTableSchema - set the database schema on the fly
*
*
*
* @param string database name
* @param string table name of table to create schema info for
*
* @return none | PEAR::error()
* @access public
*/
function fillTableSchema($database,$table) {
global $_DB_DATAOBJECT;
$this->_database = $database;
$this->_connect();
$table = trim($table);
$__DB= &$GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'][$this->_database_dsn_md5];
$defs = $__DB->tableInfo($table);
if (PEAR::isError($defs)) {
return $defs;
}
if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 2) {
$this->debug("getting def for $database/$table",'fillTable');
$this->debug(print_r($defs,true),'defs');
}
// cast all definitions to objects - as we deal with that better.
foreach($defs as $def) {
if (is_array($def)) {
$this->_definitions[$table][] = (object) $def;
}
}
 
$this->table = trim($table);
$ret = $this->_generateDefinitionsTable();
$_DB_DATAOBJECT['INI'][$database][$table] = $ret['table'];
$_DB_DATAOBJECT['INI'][$database][$table.'__keys'] = $ret['keys'];
return false;
}
/**
* Generate getter methods for class definition
*
* @param string $input Existing class contents
* @return string
* @access public
*/
function _generateGetters($input) {
 
$options = &PEAR::getStaticProperty('DB_DataObject','options');
$getters = '';
 
// only generate if option is set to true
if (empty($options['generate_getters'])) {
return '';
}
 
// remove auto-generated code from input to be able to check if the method exists outside of the auto-code
$input = preg_replace('/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n).*(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s', '', $input);
 
$getters .= "\n\n";
$defs = $this->_definitions[$this->table];
 
// loop through properties and create getter methods
foreach ($defs = $defs as $t) {
 
// build mehtod name
$methodName = 'get' . ucfirst($t->name);
 
if (!strlen(trim($t->name)) || preg_match("/function[\s]+[&]?$methodName\(/i", $input)) {
continue;
}
 
$getters .= " /**\n";
$getters .= " * Getter for \${$t->name}\n";
$getters .= " *\n";
$getters .= (stristr($t->flags, 'multiple_key')) ? " * @return object\n"
: " * @return {$t->type}\n";
$getters .= " * @access public\n";
$getters .= " */\n";
$getters .= (substr(phpversion(),0,1) > 4) ? ' public '
: ' ';
$getters .= "function $methodName() {\n";
$getters .= " return \$this->{$t->name};\n";
$getters .= " }\n\n";
}
 
return $getters;
}
 
 
/**
* Generate setter methods for class definition
*
* @param string Existing class contents
* @return string
* @access public
*/
function _generateSetters($input) {
 
$options = &PEAR::getStaticProperty('DB_DataObject','options');
$setters = '';
 
// only generate if option is set to true
if (empty($options['generate_setters'])) {
return '';
}
 
// remove auto-generated code from input to be able to check if the method exists outside of the auto-code
$input = preg_replace('/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n).*(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s', '', $input);
 
$setters .= "\n";
$defs = $this->_definitions[$this->table];
 
// loop through properties and create setter methods
foreach ($defs = $defs as $t) {
 
// build mehtod name
$methodName = 'set' . ucfirst($t->name);
 
if (!strlen(trim($t->name)) || preg_match("/function[\s]+[&]?$methodName\(/i", $input)) {
continue;
}
 
$setters .= " /**\n";
$setters .= " * Setter for \${$t->name}\n";
$setters .= " *\n";
$setters .= " * @param mixed input value\n";
$setters .= " * @access public\n";
$setters .= " */\n";
$setters .= (substr(phpversion(),0,1) > 4) ? ' public '
: ' ';
$setters .= "function $methodName(\$value) {\n";
$setters .= " \$this->{$t->name} = \$value;\n";
$setters .= " }\n\n";
}
 
return $setters;
}
 
}
/tags/v1.0-Homere/bibliotheque/pear/DB/DataObject/Error.php
New file
0,0 → 1,53
<?php
/**
* DataObjects error handler, loaded on demand...
*
* DB_DataObject_Error is a quick wrapper around pear error, so you can distinguish the
* error code source.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_DataObject
* @author Alan Knowles <alan@akbkhome.com>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Error.php,v 1.3 2005/03/23 02:35:35 alan_k Exp $
* @link http://pear.php.net/package/DB_DataObject
*/
class DB_DataObject_Error extends PEAR_Error
{
/**
* DB_DataObject_Error constructor.
*
* @param mixed $code DB error code, or string with error message.
* @param integer $mode what "error mode" to operate in
* @param integer $level what error level to use for $mode & PEAR_ERROR_TRIGGER
* @param mixed $debuginfo additional debug info, such as the last query
*
* @access public
*
* @see PEAR_Error
*/
function DB_DataObject_Error($message = '', $code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
$level = E_USER_NOTICE)
{
$this->PEAR_Error('DB_DataObject Error: ' . $message, $code, $mode, $level);
}
// todo : - support code -> message handling, and translated error messages...
}
/tags/v1.0-Homere/bibliotheque/pear/DB/DataObject/Cast.php
New file
0,0 → 1,546
<?php
/**
* Prototype Castable Object.. for DataObject queries
*
* Storage for Data that may be cast into a variety of formats.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_DataObject
* @author Alan Knowles <alan@akbkhome.com>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Cast.php,v 1.15 2005/07/07 05:30:53 alan_k Exp $
* @link http://pear.php.net/package/DB_DataObject
*/
/**
*
* Common usages:
* // blobs
* $data = DB_DataObject_Cast::blob($somefile);
* $data = DB_DataObject_Cast::string($somefile);
* $dataObject->someblobfield = $data
*
* // dates?
* $d1 = new DB_DataObject_Cast::date('12/12/2000');
* $d2 = new DB_DataObject_Cast::date(2000,12,30);
* $d3 = new DB_DataObject_Cast::date($d1->year, $d1->month+30, $d1->day+30);
*
* // time, datetime.. ?????????
*
* // raw sql????
* $data = DB_DataObject_Cast::sql('cast("123123",datetime)');
* $data = DB_DataObject_Cast::sql('NULL');
*
* // int's/string etc. are proably pretty pointless..!!!!
*
*
* inside DB_DataObject,
* if (is_a($v,'db_dataobject_class')) {
* $value .= $v->toString(DB_DATAOBJECT_INT,'mysql');
* }
*
*
*
*
 
*/
class DB_DataObject_Cast {
/**
* Type of data Stored in the object..
*
* @var string (date|blob|.....?)
* @access public
*/
var $type;
/**
* Data For date representation
*
* @var int day/month/year
* @access public
*/
var $day;
var $month;
var $year;
 
/**
* Generic Data..
*
* @var string
* @access public
*/
 
var $value;
 
 
 
/**
* Blob consructor
*
* create a Cast object from some raw data.. (binary)
*
*
* @param string (with binary data!)
*
* @return object DB_DataObject_Cast
* @access public
*/
function blob($value) {
$r = new DB_DataObject_Cast;
$r->type = 'blob';
$r->value = $value;
return $r;
}
 
 
/**
* String consructor (actually use if for ints and everything else!!!
*
* create a Cast object from some string (not binary)
*
*
* @param string (with binary data!)
*
* @return object DB_DataObject_Cast
* @access public
*/
function string($value) {
$r = new DB_DataObject_Cast;
$r->type = 'string';
$r->value = $value;
return $r;
}
/**
* SQL constructor (for raw SQL insert)
*
* create a Cast object from some sql
*
* @param string (with binary data!)
*
* @return object DB_DataObject_Cast
* @access public
*/
function sql($value)
{
$r = new DB_DataObject_Cast;
$r->type = 'sql';
$r->value = $value;
return $r;
}
 
 
/**
* Date Constructor
*
* create a Cast object from some string (not binary)
* NO VALIDATION DONE, although some crappy re-calcing done!
*
* @param vargs... accepts
* dd/mm
* dd/mm/yyyy
* yyyy-mm
* yyyy-mm-dd
* array(yyyy,dd)
* array(yyyy,dd,mm)
*
*
*
* @return object DB_DataObject_Cast
* @access public
*/
function date()
{
$args = func_get_args();
switch(count($args)) {
case 0: // no args = today!
$bits = explode('-',date('Y-m-d'));
break;
case 1: // one arg = a string
if (strpos($args[0],'/') !== false) {
$bits = array_reverse(explode('/',$args[0]));
} else {
$bits = explode('-',$args[0]);
}
break;
default: // 2 or more..
$bits = $args;
}
if (count($bits) == 1) { // if YYYY set day = 1st..
$bits[] = 1;
}
if (count($bits) == 2) { // if YYYY-DD set day = 1st..
$bits[] = 1;
}
// if year < 1970 we cant use system tools to check it...
// so we make a few best gueses....
// basically do date calculations for the year 2000!!!
// fix me if anyone has more time...
if (($bits[0] < 1975) || ($bits[0] > 2030)) {
$oldyear = $bits[0];
$bits = explode('-',date('Y-m-d',mktime(1,1,1,$bits[1],$bits[2],2000)));
$bits[0] = ($bits[0] - 2000) + $oldyear;
} else {
// now mktime
$bits = explode('-',date('Y-m-d',mktime(1,1,1,$bits[1],$bits[2],$bits[0])));
}
$r = new DB_DataObject_Cast;
$r->type = 'date';
list($r->year,$r->month,$r->day) = $bits;
return $r;
}
 
/**
* Data For time representation ** does not handle timezones!!
*
* @var int hour/minute/second
* @access public
*/
var $hour;
var $minute;
var $second;
 
/**
* DateTime Constructor
*
* create a Cast object from a Date/Time
* Maybe should accept a Date object.!
* NO VALIDATION DONE, although some crappy re-calcing done!
*
* @param vargs... accepts
* noargs (now)
* yyyy-mm-dd HH:MM:SS (Iso)
* array(yyyy,mm,dd,HH,MM,SS)
*
*
* @return object DB_DataObject_Cast
* @access public
* @author therion 5 at hotmail
*/
function dateTime()
{
$args = func_get_args();
switch(count($args)) {
case 0: // no args = now!
$datetime = date('Y-m-d G:i:s', mktime());
case 1:
// continue on from 0 args.
if (!isset($datetime)) {
$datetime = $args[0];
}
$parts = explode(' ', $datetime);
$bits = explode('-', $parts[0]);
$bits = array_merge($bits, explode(':', $parts[1]));
break;
default: // 2 or more..
$bits = $args;
}
 
if (count($bits) != 6) {
// PEAR ERROR?
return false;
}
$r = DB_DataObject_Cast::date($bits[0], $bits[1], $bits[2]);
if (!$r) {
return $r; // pass thru error (False) - doesnt happen at present!
}
// change the type!
$r->type = 'datetime';
// should we mathematically sort this out..
// (or just assume that no-one's dumb enough to enter 26:90:90 as a time!
$r->hour = $bits[3];
$r->minute = $bits[4];
$r->second = $bits[5];
return $r;
 
}
 
 
 
/**
* time Constructor
*
* create a Cast object from a Date/Time
* Maybe should accept a Date object.!
* NO VALIDATION DONE, and no-recalcing done!
*
* @param vargs... accepts
* noargs (now)
* HH:MM:SS (Iso)
* array(HH,MM,SS)
*
*
* @return object DB_DataObject_Cast
* @access public
* @author therion 5 at hotmail
*/
function time()
{
$args = func_get_args();
switch (count($args)) {
case 0: // no args = now!
$time = date('G:i:s', mktime());
case 1:
// continue on from 0 args.
if (!isset($time)) {
$time = $args[0];
}
$bits = explode(':', $time);
break;
default: // 2 or more..
$bits = $args;
}
if (count($bits) != 3) {
return false;
}
// now take data from bits into object fields
$r = new DB_DataObject_Cast;
$r->type = 'time';
$r->hour = $bits[0];
$r->minute = $bits[1];
$r->second = $bits[2];
return $r;
 
}
 
/**
* get the string to use in the SQL statement for this...
*
*
* @param int $to Type (DB_DATAOBJECT_*
* @param object $db DB Connection Object
*
*
* @return string
* @access public
*/
function toString($to=false,$db)
{
// if $this->type is not set, we are in serious trouble!!!!
// values for to:
$method = 'toStringFrom'.$this->type;
return $this->$method($to,$db);
}
/**
* get the string to use in the SQL statement from a blob of binary data
* ** Suppots only blob->postgres::bytea
*
* @param int $to Type (DB_DATAOBJECT_*
* @param object $db DB Connection Object
*
*
* @return string
* @access public
*/
function toStringFromBlob($to,$db)
{
// first weed out invalid casts..
// in blobs can only be cast to blobs.!
// perhaps we should support TEXT fields???
if (!($to & DB_DATAOBJECT_BLOB)) {
return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::blob to something other than a blob!');
}
switch ($db->dsn["phptype"]) {
case 'pgsql':
return "'".pg_escape_bytea($this->value)."'::bytea";
case 'mysql':
return "'".mysql_real_escape_string($this->value,$db->connection)."'";
case 'mysqli':
// this is funny - the parameter order is reversed ;)
return "'".mysqli_real_escape_string($db->connection, $this->value)."'";
default:
return PEAR::raiseError("DB_DataObject_Cast cant handle blobs for Database:{$db->dsn['phptype']} Yet");
}
}
/**
* get the string to use in the SQL statement for a blob from a string!
* ** Suppots only string->postgres::bytea
*
*
* @param int $to Type (DB_DATAOBJECT_*
* @param object $db DB Connection Object
*
*
* @return string
* @access public
*/
function toStringFromString($to,$db)
{
// first weed out invalid casts..
// in blobs can only be cast to blobs.!
// perhaps we should support TEXT fields???
//
if (!($to & DB_DATAOBJECT_BLOB)) {
return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::string to something other than a blob!'.
' (why not just use native features)');
}
switch ($db->dsn['phptype']) {
case 'pgsql':
return "'".pg_escape_string($this->value)."'::bytea";
case 'mysql':
return "'".mysql_real_escape_string($this->value,$db->connection)."'";
case 'mysqli':
return "'".mysqli_real_escape_string($db->connection, $this->value)."'";
 
default:
return PEAR::raiseError("DB_DataObject_Cast cant handle blobs for Database:{$db->dsn['phptype']} Yet");
}
}
/**
* get the string to use in the SQL statement for a date
*
*
*
* @param int $to Type (DB_DATAOBJECT_*
* @param object $db DB Connection Object
*
*
* @return string
* @access public
*/
function toStringFromDate($to,$db)
{
// first weed out invalid casts..
// in blobs can only be cast to blobs.!
// perhaps we should support TEXT fields???
//
if (($to !== false) && !($to & DB_DATAOBJECT_DATE)) {
return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::string to something other than a date!'.
' (why not just use native features)');
}
return "'{$this->year}-{$this->month}-{$this->day}'";
}
/**
* get the string to use in the SQL statement for a datetime
*
*
*
* @param int $to Type (DB_DATAOBJECT_*
* @param object $db DB Connection Object
*
*
* @return string
* @access public
* @author therion 5 at hotmail
*/
function toStringFromDateTime($to,$db)
{
// first weed out invalid casts..
// in blobs can only be cast to blobs.!
// perhaps we should support TEXT fields???
if (($to !== false) &&
!($to & (DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME))) {
return PEAR::raiseError('Invalid Cast from a ' .
' DB_DataObject_Cast::dateTime to something other than a datetime!' .
' (try using native features)');
}
return "'{$this->year}-{$this->month}-{$this->day} {$this->hour}:{$this->minute}:{$this->second}'";
}
 
/**
* get the string to use in the SQL statement for a time
*
*
*
* @param int $to Type (DB_DATAOBJECT_*
* @param object $db DB Connection Object
*
*
* @return string
* @access public
* @author therion 5 at hotmail
*/
 
function toStringFromTime($to,$db)
{
// first weed out invalid casts..
// in blobs can only be cast to blobs.!
// perhaps we should support TEXT fields???
if (($to !== false) && !($to & DB_DATAOBJECT_TIME)) {
return PEAR::raiseError('Invalid Cast from a' .
' DB_DataObject_Cast::time to something other than a time!'.
' (try using native features)');
}
return "'{$this->hour}:{$this->minute}:{$this->second}'";
}
/**
* get the string to use in the SQL statement for a raw sql statement.
*
* @param int $to Type (DB_DATAOBJECT_*
* @param object $db DB Connection Object
*
*
* @return string
* @access public
*/
function toStringFromSql($to,$db)
{
return $this->value;
}
}
 
/tags/v1.0-Homere/bibliotheque/pear/DB/DataObject/createTables.php
New file
0,0 → 1,55
#!/usr/bin/php -q
<?php
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Alan Knowles <alan@akbkhome.com>
// +----------------------------------------------------------------------+
//
// $Id: createTables.php,v 1.23 2005/05/04 14:13:57 alan_k Exp $
//
 
// since this version doesnt use overload,
// and I assume anyone using custom generators should add this..
 
define('DB_DATAOBJECT_NO_OVERLOAD',1);
 
require_once 'DB/DataObject/Generator.php';
 
if (!ini_get('register_argc_argv')) {
PEAR::raiseError("\nERROR: You must turn register_argc_argv On in you php.ini file for this to work\neg.\n\nregister_argc_argv = On\n\n", null, PEAR_ERROR_DIE);
exit;
}
 
if (!@$_SERVER['argv'][1]) {
PEAR::raiseError("\nERROR: createTable.php usage:\n\nC:\php\pear\DB\DataObjects\createTable.php example.ini\n\n", null, PEAR_ERROR_DIE);
exit;
}
 
$config = parse_ini_file($_SERVER['argv'][1], true);
foreach($config as $class=>$values) {
$options = &PEAR::getStaticProperty($class,'options');
$options = $values;
}
 
 
$options = &PEAR::getStaticProperty('DB_DataObject','options');
if (empty($options)) {
PEAR::raiseError("\nERROR: could not read ini file\n\n", null, PEAR_ERROR_DIE);
exit;
}
set_time_limit(0);
DB_DataObject::debugLevel(1);
$generator = new DB_DataObject_Generator;
$generator->start();
/tags/v1.0-Homere/bibliotheque/pear/DB/msql.php
New file
0,0 → 1,810
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's msql extension
* for interacting with Mini SQL databases
*
* PHP's mSQL extension did weird things with NULL values prior to PHP
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds
* those versions.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: msql.php,v 1.57 2005/02/22 07:26:46 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's msql extension
* for interacting with Mini SQL databases
*
* These methods overload the ones declared in DB_common.
*
* PHP's mSQL extension did weird things with NULL values prior to PHP
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds
* those versions.
*
* @category Database
* @package DB
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
* @since Class not functional until Release 1.7.0
*/
class DB_msql extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'msql';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'msql';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => 'emulate',
'new_link' => false,
'numrows' => true,
'pconnect' => true,
'prepare' => false,
'ssl' => false,
'transactions' => false,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* The query result resource created by PHP
*
* Used to make affectedRows() work. Only contains the result for
* data manipulation queries. Contains false for other queries.
*
* @var resource
* @access private
*/
var $_result;
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_msql()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* Example of how to connect:
* <code>
* require_once 'DB.php';
*
* // $dsn = 'msql://hostname/dbname'; // use a TCP connection
* $dsn = 'msql:///dbname'; // use a socket
* $options = array(
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
* </code>
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('msql')) {
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
$params = array();
if ($dsn['hostspec']) {
$params[] = $dsn['port']
? $dsn['hostspec'] . ',' . $dsn['port']
: $dsn['hostspec'];
}
 
$connect_function = $persistent ? 'msql_pconnect' : 'msql_connect';
 
$ini = ini_get('track_errors');
$php_errormsg = '';
if ($ini) {
$this->connection = @call_user_func_array($connect_function,
$params);
} else {
ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function,
$params);
ini_set('track_errors', $ini);
}
 
if (!$this->connection) {
if (($err = @msql_error()) != '') {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$err);
} else {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$php_errormsg);
}
}
 
if (!@msql_select_db($dsn['database'], $this->connection)) {
return $this->msqlRaiseError();
}
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @msql_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$this->last_query = $query;
$query = $this->modifyQuery($query);
$result = @msql_query($query, $this->connection);
if (!$result) {
return $this->msqlRaiseError();
}
// Determine which queries that should return data, and which
// should return an error code only.
if (DB::isManip($query)) {
$this->_result = $result;
return DB_OK;
} else {
$this->_result = false;
return $result;
}
}
 
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal msql result pointer to the next available result
*
* @param a valid fbsql result resource
*
* @access public
*
* @return true if a result is available otherwise return false
*/
function nextResult($result)
{
return false;
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* PHP's mSQL extension did weird things with NULL values prior to PHP
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds
* those versions.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@msql_data_seek($result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @msql_fetch_array($result, MSQL_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @msql_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return @msql_free_result($result);
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @msql_num_fields($result);
if (!$cols) {
return $this->msqlRaiseError();
}
return $cols;
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
function numRows($result)
{
$rows = @msql_num_rows($result);
if ($rows === false) {
return $this->msqlRaiseError();
}
return $rows;
}
 
// }}}
// {{{ affected()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
if (!$this->_result) {
return 0;
}
return msql_affected_rows($this->_result);
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_msql::createSequence(), DB_msql::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
$repeat = false;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result =& $this->query("SELECT _seq FROM ${seqname}");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
$repeat = true;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->createSequence($seq_name);
$this->popErrorHandling();
if (DB::isError($result)) {
return $this->raiseError($result);
}
} else {
$repeat = false;
}
} while ($repeat);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$arr = $result->fetchRow(DB_FETCHMODE_ORDERED);
$result->free();
return $arr[0];
}
 
// }}}
// {{{ createSequence()
 
/**
* Creates a new sequence
*
* Also creates a new table to associate the sequence with. Uses
* a separate table to ensure portability with other drivers.
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_msql::nextID(), DB_msql::dropSequence()
*/
function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$res = $this->query('CREATE TABLE ' . $seqname
. ' (id INTEGER NOT NULL)');
if (DB::isError($res)) {
return $res;
}
$res = $this->query("CREATE SEQUENCE ON ${seqname}");
return $res;
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_msql::nextID(), DB_msql::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
 
// }}}
// {{{ quoteIdentifier()
 
/**
* mSQL does not support delimited identifiers
*
* @param string $str the identifier name to be quoted
*
* @return object a DB_Error object
*
* @see DB_common::quoteIdentifier()
* @since Method available since Release 1.7.0
*/
function quoteIdentifier($str)
{
return $this->raiseError(DB_ERROR_UNSUPPORTED);
}
 
// }}}
// {{{ escapeSimple()
 
/**
* Escapes a string according to the current DBMS's standards
*
* @param string $str the string to be escaped
*
* @return string the escaped string
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.7.0
*/
function escapeSimple($str)
{
return addslashes($str);
}
 
// }}}
// {{{ msqlRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_msql::errorNative(), DB_msql::errorCode()
*/
function msqlRaiseError($errno = null)
{
$native = $this->errorNative();
if ($errno === null) {
$errno = $this->errorCode($native);
}
return $this->raiseError($errno, null, null, null, $native);
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error message produced by the last query
*
* @return string the DBMS' error message
*/
function errorNative()
{
return @msql_error();
}
 
// }}}
// {{{ errorCode()
 
/**
* Determines PEAR::DB error code from the database's text error message
*
* @param string $errormsg the error message returned from the database
*
* @return integer the error number from a DB_ERROR* constant
*/
function errorCode($errormsg)
{
static $error_regexps;
if (!isset($error_regexps)) {
$error_regexps = array(
'/^Access to database denied/i'
=> DB_ERROR_ACCESS_VIOLATION,
'/^Bad index name/i'
=> DB_ERROR_ALREADY_EXISTS,
'/^Bad order field/i'
=> DB_ERROR_SYNTAX,
'/^Bad type for comparison/i'
=> DB_ERROR_SYNTAX,
'/^Can\'t perform LIKE on/i'
=> DB_ERROR_SYNTAX,
'/^Can\'t use TEXT fields in LIKE comparison/i'
=> DB_ERROR_SYNTAX,
'/^Couldn\'t create temporary table/i'
=> DB_ERROR_CANNOT_CREATE,
'/^Error creating table file/i'
=> DB_ERROR_CANNOT_CREATE,
'/^Field .* cannot be null$/i'
=> DB_ERROR_CONSTRAINT_NOT_NULL,
'/^Index (field|condition) .* cannot be null$/i'
=> DB_ERROR_SYNTAX,
'/^Invalid date format/i'
=> DB_ERROR_INVALID_DATE,
'/^Invalid time format/i'
=> DB_ERROR_INVALID,
'/^Literal value for .* is wrong type$/i'
=> DB_ERROR_INVALID_NUMBER,
'/^No Database Selected/i'
=> DB_ERROR_NODBSELECTED,
'/^No value specified for field/i'
=> DB_ERROR_VALUE_COUNT_ON_ROW,
'/^Non unique value for unique index/i'
=> DB_ERROR_CONSTRAINT,
'/^Out of memory for temporary table/i'
=> DB_ERROR_CANNOT_CREATE,
'/^Permission denied/i'
=> DB_ERROR_ACCESS_VIOLATION,
'/^Reference to un-selected table/i'
=> DB_ERROR_SYNTAX,
'/^syntax error/i'
=> DB_ERROR_SYNTAX,
'/^Table .* exists$/i'
=> DB_ERROR_ALREADY_EXISTS,
'/^Unknown database/i'
=> DB_ERROR_NOSUCHDB,
'/^Unknown field/i'
=> DB_ERROR_NOSUCHFIELD,
'/^Unknown (index|system variable)/i'
=> DB_ERROR_NOT_FOUND,
'/^Unknown table/i'
=> DB_ERROR_NOSUCHTABLE,
'/^Unqualified field/i'
=> DB_ERROR_SYNTAX,
);
}
 
foreach ($error_regexps as $regexp => $code) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
}
return DB_ERROR;
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::setOption()
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @msql_query("SELECT * FROM $result",
$this->connection);
$got_string = true;
} elseif (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$id = $result->result;
$got_string = false;
} else {
/*
* Probably received a result resource identifier.
* Copy it.
* Deprecated. Here for compatibility only.
*/
$id = $result;
$got_string = false;
}
 
if (!is_resource($id)) {
return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$count = @msql_num_fields($id);
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
$tmp = @msql_fetch_field($id);
 
$flags = '';
if ($tmp->not_null) {
$flags .= 'not_null ';
}
if ($tmp->unique) {
$flags .= 'unique_key ';
}
$flags = trim($flags);
 
$res[$i] = array(
'table' => $case_func($tmp->table),
'name' => $case_func($tmp->name),
'type' => $tmp->type,
'len' => msql_field_len($id, $i),
'flags' => $flags,
);
 
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
// free the result only if we were called on a table
if ($got_string) {
@msql_free_result($id);
}
return $res;
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtain a list of a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return array the array containing the list of objects requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'databases':
$id = @msql_list_dbs($this->connection);
break;
case 'tables':
$id = @msql_list_tables($this->dsn['database'],
$this->connection);
break;
default:
return null;
}
if (!$id) {
return $this->msqlRaiseError();
}
$out = array();
while ($row = @msql_fetch_row($id)) {
$out[] = $row[0];
}
return $out;
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/QueryTool/Query.php
New file
0,0 → 1,2395
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the DB_QueryTool_Query class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_QueryTool
* @author Wolfram Kriesing <wk@visionp.de>
* @author Paolo Panto <wk@visionp.de>
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @copyright 2003-2005 Wolfram Kriesing, Paolo Panto, Lorenzo Alberton
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Query.php,v 1.57 2005/02/27 19:13:19 quipo Exp $
* @link http://pear.php.net/package/DB_QueryTool
*/
 
/**
* require the PEAR and DB classes
*/
require_once 'PEAR.php';
require_once 'DB.php';
 
/**
* DB_QueryTool_Query class
*
* This class should be extended
*
* @category Database
* @package DB_QueryTool
* @author Wolfram Kriesing <wk@visionp.de>
* @author Paolo Panto <wk@visionp.de>
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @copyright 2003-2005 Wolfram Kriesing, Paolo Panto, Lorenzo Alberton
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/DB_QueryTool
*/
class DB_QueryTool_Query
{
// {{{ class vars
 
/**
* @var string the name of the primary column
*/
var $primaryCol = 'id';
 
/**
* @var string the current table the class works on
*/
var $table = '';
 
/**
* @var string the name of the sequence for this table
*/
var $sequenceName = null;
 
/**
* @var object the db-object, a PEAR::DB instance
*/
var $db = null;
 
/**
* @var string the where condition
* @access private
*/
var $_where = '';
 
/**
* @var string the order condition
* @access private
*/
var $_order = '';
 
/**
* @var string the having definition
* @access private
*/
var $_having = '';
 
/**
* @var array contains the join content
* the key is the join type, for now we have 'default' and 'left'
* inside each key 'table' contains the table
* key 'where' contains the where clause for the join
* @access private
*/
var $_join = array();
 
/**
* @var string which column to index the result by
* @access private
*/
var $_index = null;
 
/**
* @var string the group-by clause
* @access private
*/
var $_group = '';
 
/**
* @var array the limit
* @access private
*/
var $_limit = array();
 
/**
* @var string type of result to return
* @access private
*/
var $_resultType = 'none';
 
/**
* @var array the metadata temporary saved
* @access private
*/
var $_metadata = array();
 
/**
* @var string
* @access private
*/
var $_lastQuery = null;
 
/**
* @var string the rows that shall be selected
* @access private
*/
var $_select = '*';
 
/**
* @var string the rows that shall not be selected
* @access private
*/
var $_dontSelect = '';
 
/**
* @var array this array saves different modes in which this class works
* i.e. 'raw' means no quoting before saving/updating data
* @access private
*/
var $options = array(
'raw' => false,
'verbose' => true, // set this to false in a productive environment
// it will produce error-logs if set to true
'useCache' => false,
'logFile' => false,
);
 
/**
* this array contains information about the tables
* those are
* - 'name' => the real table name
* - 'shortName' => the short name used, so that when moving the table i.e.
* onto a provider's db and u have to rename the tables to
* longer names this name will be relevant, i.e. when
* autoJoining, i.e. a table name on your local machine is:
* 'user' but online it has to be 'applName_user' then the
* shortName will be used to determine if a column refers to
* another table, if the colName is 'user_id', it knows the
* shortName 'user' refers to the table 'applName_user'
*/
var $tableSpec = array();
 
/**
* this is the regular expression that shall be used to find a table's shortName
* in a column name, the string found by using this regular expression will be removed
* from the column name and it will be checked if it is a table name
* i.e. the default '/_id$/' would find the table name 'user' from the column name 'user_id'
*/
var $_tableNameToShortNamePreg = '/^.*_/';
 
/**
* @var array this array caches queries that have already been built once
* to reduce the execution time
*/
var $_queryCache = array();
 
/**
* The object that contains the log-instance
*/
var $_logObject = null;
 
/**
* Some internal data the logging needs
*/
var $_logData = array();
 
// }}}
// {{{ __construct()
 
/**
* this is the constructor, as it will be implemented in ZE2 (php5)
*
* @version 2002/04/02
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param object db-object
*/
/*
function __construct($dsn=false, $options=array())
{
if (!isset($options['autoConnect'])) {
$autoConnect = true;
} else {
$autoConnect = $options['autoConnect'];
}
if (isset($options['errorCallback'])) {
$this->setErrorCallback($options['errorCallback']);
}
if (isset($options['errorSetCallback'])) {
$this->setErrorSetCallback($options['errorSetCallback']);
}
if (isset($options['errorLogCallback'])) {
$this->setErrorLogCallback($options['errorLogCallback']);
}
 
if ($autoConnect && $dsn) {
$this->connect($dsn, $options);
}
//we would need to parse the dsn first ... i dont feel like now :-)
// oracle has all column names in upper case
//FIXXXME make the class work only with upper case when we work with oracle
//if ($this->db->phptype=='oci8' && !$this->primaryCol) {
// $this->primaryCol = 'ID';
//}
 
if ($this->sequenceName == null) {
$this->sequenceName = $this->table;
}
}
*/
 
// }}}
// {{{ DB_QueryTool_Query()
 
/**
* @version 2002/04/02
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param mixed $dsn DSN string, DSN array or DB object
* @param array $options
*/
function DB_QueryTool_Query($dsn=false, $options=array())
{
//$this->__construct($dsn, $options);
if (!isset($options['autoConnect'])) {
$autoConnect = true;
} else {
$autoConnect = $options['autoConnect'];
unset($options['autoConnect']);
}
if (isset($options['errorCallback'])) {
$this->setErrorCallback($options['errorCallback']);
unset($options['errorCallback']);
}
if (isset($options['errorSetCallback'])) {
$this->setErrorSetCallback($options['errorSetCallback']);
unset($options['errorSetCallback']);
}
if (isset($options['errorLogCallback'])) {
$this->setErrorLogCallback($options['errorLogCallback']);
unset($options['errorLogCallback']);
}
if ($autoConnect && $dsn) {
$this->connect($dsn, $options);
}
if (is_null($this->sequenceName)) {
$this->sequenceName = $this->table;
}
}
 
// }}}
// {{{ connect()
 
/**
* use this method if you want to connect manually
* @param mixed $dsn DSN string, DSN array or MDB object
* @param array $options
*/
function connect($dsn, $options=array())
{
if (is_object($dsn)) {
$res = $this->db =& $dsn;
} else {
$res = $this->db = DB::connect($dsn, $options);
}
if (DB::isError($res)) {
// FIXXME what shall we do here?
$this->_errorLog($res->getUserInfo());
} else {
$this->db->setFetchMode(DB_FETCHMODE_ASSOC);
}
}
 
// }}}
// {{{ getDbInstance()
 
/**
* @return reference to current DB instance
*/
function &getDbInstance()
{
return $this->db;
}
 
// }}}
// {{{ setDbInstance()
 
/**
* Setup using an existing connection.
* this also sets the DB_FETCHMODE_ASSOC since this class
* needs this to be set!
*
* @param object a reference to an existing DB-object
* @return void
*/
function setDbInstance(&$dbh)
{
$this->db =& $dbh;
$this->db->setFetchMode(DB_FETCHMODE_ASSOC);
}
 
// }}}
// {{{ get()
 
/**
* get the data of a single entry
* if the second parameter is only one column the result will be returned
* directly not as an array!
*
* @version 2002/03/05
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param integer the id of the element to retrieve
* @param string if this is given only one row shall be returned, directly, not an array
* @return mixed (1) an array of the retrieved data
* (2) if the second parameter is given and its only one column,
* only this column's data will be returned
* (3) false in case of failure
*/
function get($id, $column='')
{
$table = $this->table;
$getMethod = 'getRow';
if ($column && !strpos($column, ',')) { // if only one column shall be selected
$getMethod = 'getOne';
}
// we dont use 'setSelect' here, since this changes the setup of the class, we
// build the query directly
// if $column is '' then _buildSelect selects '*' anyway, so that's the same behaviour as before
$query['select'] = $this->_buildSelect($column);
$query['where'] = $this->_buildWhere($this->table.'.'.$this->primaryCol.'='.$id);
$queryString = $this->_buildSelectQuery($query);
 
return $this->returnResult($this->execute($queryString,$getMethod));
}
 
// }}}
// {{{ getMultiple()
 
/**
* gets the data of the given ids
*
* @version 2002/04/23
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param array this is an array of ids to retreive
* @param string the column to search in for
* @return mixed an array of the retreived data, or false in case of failure
* when failing an error is set in $this->_error
*/
function getMultiple($ids, $column='')
{
$col = $this->primaryCol;
if ($column) {
$col = $column;
}
// FIXXME if $ids has no table.col syntax and we are using joins, the table better be put in front!!!
$ids = $this->_quoteArray($ids);
 
$query['where'] = $this->_buildWhere($col.' IN ('.implode(',', $ids).')');
$queryString = $this->_buildSelectQuery($query);
 
return $this->returnResult($this->execute($queryString));
}
 
// }}}
// {{{ getAll()
 
/**
* get all entries from the DB
* for sorting use setOrder!!!, the last 2 parameters are deprecated
*
* @version 2002/03/05
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param int to start from
* @param int the number of rows to show
* @param string the DB-method to use, i dont know if we should leave this param here ...
* @return mixed an array of the retreived data, or false in case of failure
* when failing an error is set in $this->_error
*/
function getAll($from=0,$count=0,$method='getAll')
{
$query = array();
if ($count) {
$query = array('limit' => array($from, $count));
}
return $this->returnResult($this->execute($this->_buildSelectQuery($query), $method));
}
 
// }}}
// {{{ getCol()
 
/**
* this method only returns one column, so the result will be a one dimensional array
* this does also mean that using setSelect() should be set to *one* column, the one you want to
* have returned a most common use case for this could be:
* $table->setSelect('id');
* $ids = $table->getCol();
* OR
* $ids = $table->getCol('id');
* so ids will be an array with all the id's
*
* @version 2003/02/25
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the column that shall be retreived
* @param int to start from
* @param int the number of rows to show
* @return mixed an array of the retreived data, or false in case of failure
* when failing an error is set in $this->_error
*/
function getCol($column=null, $from=0, $count=0)
{
$query = array();
if (!is_null($column)) {
// by using _buildSelect() i can be sure that the table name will not be ambigious
// i.e. in a join, where all the joined tables have a col 'id'
// _buildSelect() will put the proper table name in front in case there is none
$query['select'] = $this->_buildSelect($column);
}
if ($count) {
$query['limit'] = array($from,$count);
}
return $this->returnResult($this->execute($this->_buildSelectQuery($query), 'getCol'));
}
 
// }}}
// {{{ getCount()
 
/**
* get the number of entries
*
* @version 2002/04/02
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param
* @return mixed an array of the retreived data, or false in case of failure
* when failing an error is set in $this->_error
*/
function getCount()
{
/* the following query works on mysql
SELECT count(DISTINCT image.id) FROM image2tree
RIGHT JOIN image ON image.id = image2tree.image_id
the reason why this is needed - i just wanted to get the number of rows that do exist if the result is grouped by image.id
the following query is what i tried first, but that returns the number of rows that have been grouped together
for each image.id
SELECT count(*) FROM image2tree
RIGHT JOIN image ON image.id = image2tree.image_id GROUP BY image.id
 
so that's why we do the following, i am not sure if that is standard SQL and absolutley correct!!!
*/
 
//FIXXME see comment above if this is absolutely correct!!!
if ($group = $this->_buildGroup()) {
$query['select'] = 'COUNT(DISTINCT '.$group.')';
$query['group'] = '';
} else {
$query['select'] = 'COUNT(*)';
}
 
$query['order'] = ''; // order is not of importance and might freak up the special group-handling up there, since the order-col is not be known
/*# FIXXME use the following line, but watch out, then it has to be used in every method, or this
# value will be used always, simply try calling getCount and getAll afterwards, getAll will return the count :-)
# if getAll doesn't use setSelect!!!
*/
//$this->setSelect('count(*)');
$queryString = $this->_buildSelectQuery($query, true);
 
return ($res = $this->execute($queryString, 'getOne')) ? $res : 0;
}
 
// }}}
// {{{ getDefaultValues()
 
/**
* return an empty element where all the array elements do already exist
* corresponding to the columns in the DB
*
* @version 2002/04/05
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @return array an empty, or pre-initialized element
*/
function getDefaultValues()
{
$ret = array();
// here we read all the columns from the DB and initialize them
// with '' to prevent PHP-warnings in case we use error_reporting=E_ALL
foreach ($this->metadata() as $aCol=>$x) {
$ret[$aCol] = '';
}
return $ret;
}
 
// }}}
// {{{ getEmptyElement()
 
/**
* this is just for BC
* @deprecated
*/
function getEmptyElement()
{
$this->getDefaultValues();
}
 
// }}}
// {{{ getQueryString()
 
/**
* Render the current query and return it as a string.
*
* @return string the current query
*/
function getQueryString()
{
$ret = $this->_buildSelectQuery();
if (is_string($ret)) {
$ret = trim($ret);
}
return $ret;
}
 
// }}}
// {{{ save()
 
/**
* save data, calls either update or add
* if the primaryCol is given in the data this method knows that the
* data passed to it are meant to be updated (call 'update'), otherwise it will
* call the method 'add'.
* If you dont like this behaviour simply stick with the methods 'add'
* and 'update' and ignore this one here.
* This method is very useful when you have validation checks that have to
* be done for both adding and updating, then you can simply overwrite this
* method and do the checks in here, and both cases will be validated first.
*
* @version 2002/03/11
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param array contains the new data that shall be saved in the DB
* @return mixed the data returned by either add or update-method
*/
function save($data)
{
if (!empty($data[$this->primaryCol])) {
return $this->update($data);
}
return $this->add($data);
}
 
// }}}
// {{{ update()
 
/**
* update the member data of a data set
*
* @version 2002/03/06
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param array contains the new data that shall be saved in the DB
* the id has to be given in the field with the key 'ID'
* @return mixed true on success, or false otherwise
*/
function update($newData)
{
$query = array();
// do only set the 'where' part in $query, if a primary column is given
// if not the default 'where' clause is used
if (isset($newData[$this->primaryCol])) {
$query['where'] = $this->primaryCol.'='.$newData[$this->primaryCol];
}
$newData = $this->_checkColumns($newData, 'update');
$values = array();
$raw = $this->getOption('raw');
foreach ($newData as $key => $aData) { // quote the data
//$values[] = "{$this->table}.$key=". ($raw ? $aData : $this->db->quote($aData));
$values[] = "$key=". ($raw ? $aData : $this->db->quote($aData));
}
 
$query['set'] = implode(',', $values);
//FIXXXME _buildUpdateQuery() seems to take joins into account, whcih is bullshit here
$updateString = $this->_buildUpdateQuery($query);
#print '$updateString = '.$updateString;
return $this->execute($updateString, 'query') ? true : false;
}
 
// }}}
// {{{ add()
 
/**
* add a new member in the DB
*
* @version 2002/04/02
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param array contains the new data that shall be saved in the DB
* @return mixed the inserted id on success, or false otherwise
*/
function add($newData)
{
// if no primary col is given, get next sequence value
if (empty($newData[$this->primaryCol])) {
if ($this->primaryCol) { // do only use the sequence if a primary column is given
// otherwise the data are written as given
$id = $this->db->nextId($this->sequenceName);
$newData[$this->primaryCol] = (int)$id;
} else {
// if no primary col is given return true on success
$id = true;
}
} else {
$id = $newData[$this->primaryCol];
}
 
//unset($newData[$this->primaryCol]);
 
$newData = $this->_checkColumns($newData, 'add');
$newData = $this->_quoteArray($newData);
 
$query = sprintf( 'INSERT INTO %s (%s) VALUES (%s)',
$this->table,
implode(', ', array_keys($newData)),
implode(', ', $newData)
);
return $this->execute($query, 'query') ? $id : false;
}
 
// }}}
// {{{ addMultiple()
 
/**
* adds multiple new members in the DB
*
* @version 2002/07/17
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param array contains an array of new data that shall be saved in the DB
* the key-value pairs have to be the same for all the data!!!
* @return mixed the inserted ids on success, or false otherwise
*/
function addMultiple($data)
{
if (!sizeof($data)) {
return false;
}
// the inserted ids which will be returned or if no primaryCol is given
// we return true by default
$retIds = $this->primaryCol ? array() : true;
$allData = array(); // each row that will be inserted
foreach ($data as $key => $aData) {
$aData = $this->_checkColumns($aData, 'add');
$aData = $this->_quoteArray($aData);
 
if (empty($aData[$this->primaryCol])) {
if ($this->primaryCol) { // do only use the sequence if a primary column is given
// otherwise the data are written as given
$retIds[] = $id = (int)$this->db->nextId($this->sequenceName);
$aData[$this->primaryCol] = $id;
}
} else {
$retIds[] = $aData[$this->primaryCol];
}
$allData[] = '('.implode(', ', $aData).')';
}
 
$query = sprintf( 'INSERT INTO %s (%s) VALUES %s',
$this->table,
implode(', ', array_keys($aData)), // use the keys of the last element built
implode(', ', $allData)
);
return $this->execute($query, 'query') ? $retIds : false;
}
 
// }}}
// {{{ remove()
 
/**
* removes a member from the DB
*
* @version 2002/04/08
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param mixed integer/string - the value of the column that shall be removed
* array - multiple columns that shall be matched, the second parameter will be ignored
* @param string the column to match the data against, only if $data is not an array
* @return boolean
*/
function remove($data, $whereCol='')
{
$raw = $this->getOption('raw');
 
if (is_array($data)) {
//FIXXME check $data if it only contains columns that really exist in the table
$wheres = array();
foreach ($data as $key => $val) {
$wheres[] = $key.'='. ($raw ? $val : $this->db->quote($val));
}
$whereClause = implode(' AND ',$wheres);
} else {
if (empty($whereCol)) {
$whereCol = $this->primaryCol;
}
$whereClause = $whereCol.'='. ($raw ? $data : $this->db->quote($data));
}
 
$query = sprintf( 'DELETE FROM %s WHERE %s',
$this->table,
$whereClause
);
return $this->execute($query, 'query') ? true : false;
// i think this method should return the ID's that it removed, this way we could simply use the result
// for further actions that depend on those id ... or? make stuff easier, see ignaz::imail::remove
}
 
// }}}
// {{{ removeAll()
 
/**
* empty a table
*
* @version 2002/06/17
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @return
*/
function removeAll()
{
$query = 'DELETE FROM '.$this->table;
return $this->execute($query, 'query') ? true : false;
}
 
// }}}
// {{{ removeMultiple()
 
/**
* remove the datasets with the given ids
*
* @version 2002/04/24
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param array the ids to remove
* @return
*/
function removeMultiple($ids, $colName='')
{
if (empty($colName)) {
$colName = $this->primaryCol;
}
$ids = $this->_quoteArray($ids);
 
$query = sprintf( 'DELETE FROM %s WHERE %s IN (%s)',
$this->table,
$colName,
implode(',', $ids)
);
return $this->execute($query, 'query') ? true : false;
}
 
// }}}
// {{{ removePrimary()
 
/**
* removes a member from the DB and calls the remove methods of the given objects
* so all rows in another table that refer to this table are erased too
*
* @version 2002/04/08
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param integer the value of the primary key
* @param string the column name of the tables with the foreign keys
* @param object just for convinience, so nobody forgets to call this method
* with at least one object as a parameter
* @return boolean
*/
function removePrimary($id, $colName, $atLeastOneObject)
{
$argCounter = 2; // we have 2 parameters that need to be given at least
// func_get_arg returns false and a warning if there are no more parameters, so
// we suppress the warning and check for false
while ($object = @func_get_arg($argCounter++)) {
//FIXXXME let $object also simply be a table name
if (!$object->remove($id, $colName)) {
//FIXXXME do this better
$this->_errorSet("Error removing '$colName=$id' from table {$object->table}.");
return false;
}
}
 
return ($this->remove($id) ? true : false);
}
 
// }}}
// {{{ setLimit()
 
/**
* @param integer $from
* @param integer $count
*/
function setLimit($from=0, $count=0)
{
if ($from==0 && $count==0) {
$this->_limit = array();
} else {
$this->_limit = array($from, $count);
}
}
 
// }}}
// {{{ getLimit()
 
/**
* @return array
*/
function getLimit()
{
return $this->_limit;
}
 
// }}}
// {{{ setWhere()
 
/**
* sets the where condition which is used for the current instance
*
* @version 2002/04/16
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the where condition, this can be complete like 'X=7 AND Y=8'
*/
function setWhere($whereCondition='')
{
$this->_where = $whereCondition;
//FIXXME parse the where condition and replace ambigious column names, such as "name='Deutschland'" with "country.name='Deutschland'"
// then the users dont have to write that explicitly and can use the same name as in the setOrder i.e. setOrder('name,_net_name,_netPrefix_prefix');
}
 
// }}}
// {{{ getWhere()
 
/**
* gets the where condition which is used for the current instance
*
* @version 2002/04/22
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @return string the where condition, this can be complete like 'X=7 AND Y=8'
*/
function getWhere()
{
return $this->_where;
}
 
// }}}
// {{{ addWhere()
 
/**
* only adds a string to the where clause
*
* @version 2002/07/22
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the where clause to add to the existing one
* @param string the condition for how to concatenate the new where clause
* to the existing one
*/
function addWhere($where, $condition='AND')
{
if ($this->getWhere()) {
$where = $this->getWhere().' '.$condition.' '.$where;
}
$this->setWhere($where);
}
 
// }}}
// {{{ addWhereSearch()
 
/**
* add a where-like clause which works like a search for the given string
* i.e. calling it like this:
* $this->addWhereSearch('name', 'otto hans')
* produces a where clause like this one
* LOWER(name) LIKE "%otto%hans%"
* so the search finds the given string
*
* @version 2002/08/14
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the column to search in for
* @param string the string to search for
*/
function addWhereSearch($column, $string, $condition='AND')
{
// if the column doesn't contain a tablename use the current table name
// in case it is a defined column to prevent ambiguous rows
if (strpos($column, '.') === false) {
$meta = $this->metadata();
if (isset($meta[$column])) {
$column = $this->table.".$column";
}
}
 
$string = $this->db->quote('%'.str_replace(' ', '%', strtolower($string)).'%');
$this->addWhere("LOWER($column) LIKE $string", $condition);
}
 
// }}}
// {{{ setOrder()
 
/**
* sets the order condition which is used for the current instance
*
* @version 2002/05/16
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the where condition, this can be complete like 'X=7 AND Y=8'
* @param boolean sorting order (TRUE => ASC, FALSE => DESC)
*/
function setOrder($orderCondition='', $desc=false)
{
$this->_order = $orderCondition .($desc ? ' DESC' : '');
}
 
// }}}
// {{{ addOrder()
 
/**
* Add a order parameter to the query.
*
* @version 2003/05/28
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the where condition, this can be complete like 'X=7 AND Y=8'
* @param boolean sorting order (TRUE => ASC, FALSE => DESC)
*/
function addOrder($orderCondition='', $desc=false)
{
$order = $orderCondition .($desc ? ' DESC' : '');
if ($this->_order) {
$this->_order = $this->_order.','.$order;
} else {
$this->_order = $order;
}
}
 
// }}}
// {{{ getOrder()
 
/**
* gets the order condition which is used for the current instance
*
* @version 2002/05/16
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @return string the order condition, this can be complete like 'ID,TIMESTAMP DESC'
*/
function getOrder()
{
return $this->_order;
}
 
// }}}
// {{{ setHaving()
 
/**
* sets the having definition
*
* @version 2003/06/05
* @access public
* @author Johannes Schaefer <johnschaefer@gmx.de>
* @param string the having definition
*/
function setHaving($having='')
{
$this->_having = $having;
}
 
// }}}
// {{{ getHaving()
 
/**
* gets the having definition which is used for the current instance
*
* @version 2003/06/05
* @access public
* @author Johannes Schaefer <johnschaefer@gmx.de>
* @return string the having definition
*/
function getHaving()
{
return $this->_having;
}
 
// }}}
// {{{ addHaving()
 
/**
* Extend the current having clause. This is very useful, when you are building
* this clause from different places and don't want to overwrite the currently
* set having clause, but extend it.
*
* @param string this is a having clause, i.e. 'column' or 'table.column' or 'MAX(column)'
* @param string the connection string, which usually stays the default, which is ',' (a comma)
*/
function addHaving($what='*', $connectString=' AND ')
{
if ($this->_having) {
$this->_having = $this->_having.$connectString.$what;
} else {
$this->_having = $what;
}
}
 
// }}}
// {{{ setJoin()
 
/**
* sets a join-condition
*
* @version 2002/06/10
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param mixed either a string or an array that contains
* the table(s) to join on the current table
* @param string the where clause for the join
*/
function setJoin($table=null, $where=null, $joinType='default')
{
//FIXXME make it possible to pass a table name as a string like this too 'user u'
// where u is the string that can be used to refer to this table in a where/order
// or whatever condition
// this way it will be possible to join tables with itself, like setJoin(array('user u','user u1'))
// this wouldnt work yet, but for doing so we would need to change the _build methods too!!!
// because they use getJoin('tables') and this simply returns all the tables in use
// but don't take care of the mentioned syntax
 
if (is_null($table) || is_null($where)) { // remove the join if not sufficient parameters are given
$this->_join[$joinType] = array();
return;
}
/* this causes problems if we use the order-by, since it doenst know the name to order it by ... :-)
// replace the table names with the internal name used for the join
// this way we can also join one table multiple times if it will be implemented one day
$this->_join[$table] = preg_replace('/'.$table.'/','j1',$where);
*/
$this->_join[$joinType][$table] = $where;
}
 
// }}}
// {{{ setJoin()
 
/**
* if you do a left join on $this->table you will get all entries
* from $this->table, also if there are no entries for them in the joined table
* if both parameters are not given the left-join will be removed
* NOTE: be sure to only use either a right or a left join
*
* @version 2002/07/22
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the table(s) to be left-joined
* @param string the where clause for the join
*/
function setLeftJoin($table=null, $where=null)
{
$this->setJoin($table, $where, 'left');
}
 
// }}}
// {{{ addLeftJoin()
 
/**
* @param string the table to be left-joined
* @param string the where clause for the join
* @param string the join type
*/
function addLeftJoin($table, $where, $type='left')
{
// init value, to prevent E_ALL-warning
if (!isset($this->_join[$type]) || !$this->_join[$type]) {
$this->_join[$type] = array();
}
$this->_join[$type][$table] = $where;
}
 
// }}}
// {{{ setRightJoin()
 
/**
* see setLeftJoin for further explaination on what a left/right join is
* NOTE: be sure to only use either a right or a left join
//FIXXME check if the above sentence is necessary and if sql doesnt allow the use of both
*
* @see setLeftJoin()
* @version 2002/09/04
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the table(s) to be right-joined
* @param string the where clause for the join
*/
function setRightJoin($table=null, $where=null)
{
$this->setJoin($table, $where, 'right');
}
 
// }}}
// {{{ getJoin()
 
/**
* gets the join-condition
*
* @access public
* @param string [null|''|'table'|'tables'|'right'|'left']
* @return array gets the join parameters
*/
function getJoin($what=null)
{
// if the user requests all the join data or if the join is empty, return it
if (is_null($what) || empty($this->_join)) {
return $this->_join;
}
 
$ret = array();
switch (strtolower($what)) {
case 'table':
case 'tables':
foreach ($this->_join as $aJoin) {
if (count($aJoin)) {
$ret = array_merge($ret, array_keys($aJoin));
}
}
break;
case 'right': // return right-join data only
case 'left': // return left join data only
if (count($this->_join[$what])) {
$ret = array_merge($ret, $this->_join[$what]);
}
break;
}
return $ret;
}
 
// }}}
// {{{ addJoin()
 
/**
* adds a table and a where clause that shall be used for the join
* instead of calling
* setJoin(array(table1,table2),'<where clause1> AND <where clause2>')
* you can also call
* setJoin(table1,'<where clause1>')
* addJoin(table2,'<where clause2>')
* or where it makes more sense is to build a query which is made out of a
* left join and a standard join
* setLeftJoin(table1,'<where clause1>')
* // results in ... FROM $this->table LEFT JOIN table ON <where clause1>
* addJoin(table2,'<where clause2>')
* // results in ... FROM $this->table,table2 LEFT JOIN table ON <where clause1> WHERE <where clause2>
*
* @access public
* @param string the table to be joined
* @param string the where clause for the join
* @param string the join type
*/
function addJoin($table, $where, $type='default')
{
if ($table == $this->table) {
return; //skip. Self joins are not supported.
}
// init value, to prevent E_ALL-warning
if (!isset($this->_join[$type]) || !$this->_join[$type]) {
$this->_join[$type] = array();
}
$this->_join[$type][$table] = $where;
}
 
// }}}
// {{{ setTable()
 
/**
* sets the table this class is currently working on
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the table name
*/
function setTable($table)
{
$this->table = $table;
}
 
// }}}
// {{{ getTable()
 
/**
* gets the table this class is currently working on
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @return string the table name
*/
function getTable()
{
return $this->table;
}
 
// }}}
// {{{ setGroup()
 
/**
* sets the group-by condition
*
* @version 2002/07/22
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the group condition
*/
function setGroup($group='')
{
$this->_group = $group;
//FIXXME parse the condition and replace ambigious column names, such as "name='Deutschland'" with "country.name='Deutschland'"
// then the users dont have to write that explicitly and can use the same name as in the setOrder i.e. setOrder('name,_net_name,_netPrefix_prefix');
}
 
// }}}
// {{{ getGroup()
 
/**
* gets the group condition which is used for the current instance
*
* @version 2002/07/22
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @return string the group condition
*/
function getGroup()
{
return $this->_group;
}
 
// }}}
// {{{ setSelect()
 
/**
* limit the result to return only the columns given in $what
* @param string fields that shall be selected
*/
function setSelect($what='*')
{
$this->_select = $what;
}
 
// }}}
// {{{ addSelect()
 
/**
* add a string to the select part of the query
*
* add a string to the select-part of the query and connects it to an existing
* string using the $connectString, which by default is a comma.
* (SELECT xxx FROM - xxx is the select-part of a query)
*
* @version 2003/01/08
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the string that shall be added to the select-part
* @param string the string to connect the new string with the existing one
* @return void
*/
function addSelect($what='*', $connectString=',')
{
// if the select string is not empty add the string, otherwise simply set it
if ($this->_select) {
$this->_select = $this->_select.$connectString.$what;
} else {
$this->_select = $what;
}
}
 
// }}}
// {{{ getSelect()
 
/**
* @return string
*/
function getSelect()
{
return $this->_select;
}
 
// }}}
// {{{ setDontSelect()
 
/**
* @param string
*/
function setDontSelect($what='')
{
$this->_dontSelect = $what;
}
 
// }}}
// {{{ getDontSelect()
 
/**
* @return string
*/
function getDontSelect()
{
return $this->_dontSelect;
}
 
// }}}
// {{{ reset()
 
/**
* reset all the set* settings; with no parameter given, it resets them all
*
* @version 2002/09/16
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @return void
*/
function reset($what=array())
{
if (!sizeof($what)) {
$what = array(
'select',
'dontSelect',
'group',
'having',
'limit',
'where',
'index',
'order',
'join',
'leftJoin',
'rightJoin'
);
}
 
foreach ($what as $aReset) {
$this->{'set'.ucfirst($aReset)}();
}
}
 
// }}}
// {{{ setOption()
 
/**
* set mode the class shall work in
* currently we have the modes:
* 'raw' does not quote the data before building the query
*
* @version 2002/09/17
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the mode to be set
* @param mixed the value of the mode
* @return void
*/
function setOption($option, $value)
{
$this->options[strtolower($option)] = $value;
}
 
// }}}
// {{{ getOption()
 
/**
* @return string
*/
function getOption($option)
{
return $this->options[strtolower($option)];
}
 
// }}}
// {{{ _quoteArray()
 
/**
* quotes all the data in this array if we are not in raw mode!
* @param array
*/
function _quoteArray($data)
{
if (!$this->getOption('raw')) {
foreach ($data as $key => $val) {
$data[$key] = $this->db->quote($val);
}
}
return $data;
}
 
// }}}
// {{{ _checkColumns()
 
/**
* checks if the columns which are given as the array's indexes really exist
* if not it will be unset anyway
*
* @version 2002/04/16
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the actual message, first word should always be the method name,
* to build the message like this: className::methodname
* @param integer the line number
*/
function _checkColumns($newData, $method='unknown')
{
if (!$meta = $this->metadata()) { // if no metadata available, return data as given
return $newData;
}
 
foreach ($newData as $colName => $x) {
if (!isset($meta[$colName])) {
$this->_errorLog("$method, column {$this->table}.$colName doesnt exist, value was removed before '$method'",__LINE__);
unset($newData[$colName]);
} else {
// if the current column exists, check the length too, not to write content that is too long
// prevent DB-errors here
// do only check the data length if this field is given
if (isset($meta[$colName]['len']) && ($meta[$colName]['len'] != -1) &&
($oldLength=strlen($newData[$colName])) > $meta[$colName]['len']
) {
$this->_errorLog("_checkColumns, had to trim column '$colName' from $oldLength to ".
$meta[$colName]['DATA_LENGTH'].' characters.', __LINE__);
$newData[$colName] = substr($newData[$colName], 0, $meta[$colName]['len']);
}
}
}
return $newData;
}
 
// }}}
// {{{ debug()
 
/**
* overwrite this method and i.e. print the query $string
* to see the final query
*
* @param string the query mostly
*/
function debug($string){}
 
//
//
// ONLY ORACLE SPECIFIC, not very nice since it is DB dependent, but we need it!!!
//
//
 
// }}}
// {{{ metadata()
 
/**
* !!!! query COPIED FROM db_oci8.inc - from PHPLIB !!!!
*
* @access public
* @see
* @version 2001/09
* @author PHPLIB
* @param
* @return
*/
function metadata($table='')
{
// is there an alias in the table name, then we have something like this: 'user ua'
// cut of the alias and return the table name
if (strpos($table, ' ') !== false) {
$split = explode(' ', trim($table));
$table = $split[0];
}
 
$full = false;
if (empty($table)) {
$table = $this->table;
}
// to prevent multiple selects for the same metadata
if (isset($this->_metadata[$table])) {
return $this->_metadata[$table];
}
 
// FIXXXME use oci8 implementation of newer PEAR::DB-version
if ($this->db->phptype == 'oci8') {
$count = 0;
$id = 0;
$res = array();
 
//# This is a RIGHT OUTER JOIN: "(+)", if you want to see, what
//# this query results try the following:
//// $table = new Table; $this->db = new my_DB_Sql; // you have to make
//// // your own class
//// $table->show_results($this->db->query(see query vvvvvv))
////
$res = $this->db->getAll("SELECT T.column_name,T.table_name,T.data_type,".
"T.data_length,T.data_precision,T.data_scale,T.nullable,".
"T.char_col_decl_length,I.index_name".
" FROM ALL_TAB_COLUMNS T,ALL_IND_COLUMNS I".
" WHERE T.column_name=I.column_name (+)".
" AND T.table_name=I.table_name (+)".
" AND T.table_name=UPPER('$table') ORDER BY T.column_id");
 
if (DB::isError($res)) {
//$this->_errorSet($res->getMessage());
// i think we only need to log here, since this method is never used
// directly for the user's functionality, which means if it fails it
// is most probably an appl error
$this->_errorLog($res->getUserInfo());
return false;
}
foreach ($res as $key=>$val) {
$res[$key]['name'] = $val['COLUMN_NAME'];
}
} else {
if (!is_object($this->db)) {
return false;
}
$res = $this->db->tableinfo($table);
if (DB::isError($res)) {
$this->_errorSet($res->getUserInfo());
return false;
}
}
 
$ret = array();
foreach ($res as $key => $val) {
$ret[$val['name']] = $val;
}
$this->_metadata[$table] = $ret;
return $ret;
}
 
 
 
//
// methods for building the query
//
 
// }}}
// {{{ _buildFrom()
 
/**
* build the from string
*
* @access private
* @return string the string added after FROM
*/
function _buildFrom()
{
$from = $this->table;
$join = $this->getJoin();
 
if (!$join) { // no join set
return $from;
}
// handle the standard join thingy
if (isset($join['default']) && count($join['default'])) {
$from .= ','.implode(',',array_keys($join['default']));
}
 
// handle left/right joins
foreach (array('left', 'right') as $joinType) {
if (isset($join[$joinType]) && count($join[$joinType])) {
foreach($join[$joinType] as $table => $condition) {
// replace the _TABLENAME_COLUMNNAME by TABLENAME.COLUMNNAME
// since oracle doesnt work with the _TABLENAME_COLUMNNAME which i think is strange
// FIXXME i think this should become deprecated since the setWhere should not be used like this: '_table_column' but 'table.column'
$regExp = '/_('.$table.')_([^\s]+)/';
$where = preg_replace($regExp, '$1.$2', $condition);
 
// add the table name before any column that has no table prefix
// since this might cause "unambiguous column" errors
if ($meta = $this->metadata()) {
foreach ($meta as $aCol=>$x) {
// this covers the LIKE,IN stuff: 'name LIKE "%you%"' 'id IN (2,3,4,5)'
$condition = preg_replace('/\s'.$aCol.'\s/', " {$this->table}.$aCol ", $condition);
// replace also the column names which are behind a '='
// and do this also if the aCol is at the end of the where clause
// that's what the $ is for
$condition = preg_replace('/=\s*'.$aCol.'(\s|$)/', "={$this->table}.$aCol ", $condition);
// replace if colName is first and possibly also if at the beginning of the where-string
$condition = preg_replace('/(^\s*|\s+)'.$aCol.'\s*=/', "$1{$this->table}.$aCol=", $condition);
}
}
$from .= ' '.strtoupper($joinType).' JOIN '.$table.' ON '.$condition;
}
}
}
return $from;
}
 
// }}}
// {{{ getTableShortName()
 
/**
* this method gets the short name for a table
*
* get the short name for a table, this is needed to properly build the
* 'AS' parts in the select query
* @param string the real table name
* @return string the table's short name
*/
function getTableShortName($table)
{
$tableSpec = $this->getTableSpec(false);
if (isset($tableSpec[$table]['shortName']) && $tableSpec[$table]['shortName']) {
//print "$table ... ".$tableSpec[$table]['shortName'].'<br>';
return $tableSpec[$table]['shortName'];
}
 
$possibleTableShortName = preg_replace($this->_tableNameToShortNamePreg, '', $table);
//print "$table ... $possibleTableShortName<br>";
return $possibleTableShortName;
}
 
// }}}
// {{{ getTableSpec()
 
/**
* gets the tableSpec either indexed by the short name or the name
* returns the array for the tables given as parameter or if no
* parameter given for all tables that exist in the tableSpec
*
* @param array table names (not the short names!)
* @param boolean if true the table is returned indexed by the shortName
* otherwise indexed by the name
* @return array the tableSpec indexed
*/
function getTableSpec($shortNameIndexed=true, $tables=array())
{
$newSpec = array();
foreach ($this->tableSpec as $aSpec) {
if (sizeof($tables)==0 || in_array($aSpec['name'],$tables)) {
if ($shortNameIndexed) {
$newSpec[$aSpec['shortName']] = $aSpec;
} else {
$newSpec[$aSpec['name']] = $aSpec;
}
}
}
return $newSpec;
}
 
// }}}
// {{{ _buildSelect()
 
/**
* build the 'SELECT <what> FROM ... 'for a select
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string if given use this string
* @return string the what-clause
*/
function _buildSelect($what=null)
{
// what has preference, that means if what is set it is used
// this is only because the methods like 'get' pass an individually built value, which
// is supposed to be used, but usually it's generically build using the 'getSelect' values
if (empty($what) && $this->getSelect()) {
$what = $this->getSelect();
}
 
//
// replace all the '*' by the real column names, and take care of the dontSelect-columns!
//
$dontSelect = $this->getDontSelect();
$dontSelect = $dontSelect ? explode(',', $dontSelect) : array(); // make sure dontSelect is an array
 
// here we will replace all the '*' and 'table.*' by all the columns that this table
// contains. we do this so we can easily apply the 'dontSelect' values.
// and so we can also handle queries like: 'SELECT *,count() FROM ' and 'SELECT table.*,x FROM ' too
if (strpos($what, '*') !== false) {
// subpattern 1 get all the table names, that are written like this: 'table.*' including '*'
// for '*' the tablename will be ''
preg_match_all('/([^,]*)(\.)?\*\s*(,|$)/U', $what, $res);
//print "$what ... ";print_r($res);print "<br>";
$selectAllFromTables = array_unique($res[1]); // make the table names unique, so we do it all just once for each table
$tables = array();
if (in_array('', $selectAllFromTables)) { // was there a '*' ?
// get all the tables that we need to process, depending on if joined or not
$tables = $this->getJoin() ?
array_merge($this->getJoin('tables'), array($this->table)) : // get the joined tables and this->table
array($this->table); // create an array with only this->table
} else {
$tables = $selectAllFromTables;
}
 
$cols = array();
foreach ($tables as $aTable) { // go thru all the tables and get all columns for each, and handle 'dontSelect'
if ($meta = $this->metadata($aTable)) {
foreach ($meta as $colName => $x) {
// handle the dontSelect's
if (in_array($colName, $dontSelect) || in_array("$aTable.$colName", $dontSelect)) {
continue;
}
 
// build the AS clauses
// put " around them to enable use of reserved words, i.e. SELECT table.option as option FROM...
// and 'option' actually is a reserved word, at least in mysql
// put double quotes around them, since pgsql doesnt work with single quotes
// but don't do this for ibase because it doesn't work!
if ($aTable == $this->table) {
if ($this->db->phptype == 'ibase') {
$cols[$aTable][] = $this->table. '.' .$colName . ' AS '. $colName;
} else {
$cols[$aTable][] = $this->table. '.' .$colName . ' AS "'. $colName .'"';
}
} else {
$cols[$aTable][] = "$aTable.$colName AS \"_".$this->getTableShortName($aTable)."_$colName\"";
}
}
}
}
 
// put the extracted select back in the $what
// that means replace 'table.*' by the i.e. 'table.id AS _table_id'
// or if it is the table of this class replace 'table.id AS id'
if (in_array('', $selectAllFromTables)) {
$allCols = array();
foreach ($cols as $aTable) {
$allCols[] = implode(',', $aTable);
}
$what = preg_replace('/(^|,)\*($|,)/', '$1'.implode(',',$allCols).'$2', $what);
// remove all the 'table.*' since we have selected all anyway (because there was a '*' in the select)
$what = preg_replace('/[^,]*(\.)?\*\s*(,|$)/U', '', $what);
} else {
foreach ($cols as $tableName => $aTable) {
if (is_array($aTable) && sizeof($aTable)) {
// replace all the 'table.*' by their select of each column
$what = preg_replace('/(^|,)\s*'.$tableName.'\.\*\s*($|,)/', '$1'.implode(',',$aTable).'$2', $what);
}
}
}
}
 
if ($this->getJoin()) {
// replace all 'column' by '$this->table.column' to prevent ambigious errors
$metadata = $this->metadata();
if (is_array($metadata)) {
foreach ($metadata as $aCol => $x) {
// handle ',id as xid,MAX(id),id' etc.
// FIXXME do this better!!!
$what = preg_replace( "/(^|,|\()(\s*)$aCol(\)|\s|,|as|$)/i",
// $2 is actually just to keep the spaces, is not really
// necessary, but this way the test works independent of this functionality here
"$1$2{$this->table}.$aCol$3",
$what);
}
}
// replace all 'joinedTable.columnName' by '_joinedTable_columnName'
// this actually only has an effect if there was no 'table.*' for 'table'
// if that was there, then it has already been done before
foreach ($this->getJoin('tables') as $aTable) {
if ($meta = $this->metadata($aTable)) {
foreach ($meta as $aCol=>$x) {
// dont put the 'AS' behind it if there is already one
if (preg_match("/$aTable.$aCol\s*as/i",$what)) {
continue;
}
// this covers a ' table.colName ' surrounded by spaces, and replaces it by ' table.colName AS _table_colName'
$what = preg_replace('/\s'.$aTable.'.'.$aCol.'\s/', " $aTable.$aCol AS _".$this->getTableShortName($aTable)."_$aCol ", $what);
// replace also the column names which are behind a ','
// and do this also if the aCol is at the end that's what the $ is for
$what = preg_replace('/,\s*'.$aTable.'.'.$aCol.'(,|\s|$)/', ",$aTable.$aCol AS _".$this->getTableShortName($aTable)."_$aCol$1", $what);
// replace if colName is first and possibly also if at the beginning of the where-string
$what = preg_replace('/(^\s*|\s+)'.$aTable.'.'.$aCol.'\s*,/', "$1$aTable.$aCol AS _".$this->getTableShortName($aTable)."_$aCol,", $what);
}
}
}
}
return $what;
}
 
// }}}
// {{{ _buildWhere()
 
/**
* Build WHERE clause
*
* @param string $where WHERE clause
* @return string $where WHERE clause after processing
* @access private
*/
function _buildWhere($where='')
{
$where = trim($where);
$originalWhere = $this->getWhere();
if ($originalWhere) {
if (!empty($where)) {
$where = $originalWhere.' AND '.$where;
} else {
$where = $originalWhere;
}
}
$where = trim($where);
 
if ($join = $this->getJoin()) { // is join set?
// only those where conditions in the default-join have to be added here
// left-join conditions are added behind 'ON', the '_buildJoin()' does that
if (isset($join['default']) && count($join['default'])) {
// we have to add this join-where clause here
// since at least in mysql a query like: select * from tableX JOIN tableY ON ...
// doesnt work, may be that's even SQL-standard...
if (!empty($where)) {
$where = implode(' AND ', $join['default']).' AND '.$where;
} else {
$where = implode(' AND ', $join['default']);
}
}
// replace the _TABLENAME_COLUMNNAME by TABLENAME.COLUMNNAME
// since oracle doesnt work with the _TABLENAME_COLUMNNAME which i think is strange
// FIXXME i think this should become deprecated since the setWhere should not be used like this: '_table_column' but 'table.column'
$regExp = '/_('.implode('|', $this->getJoin('tables')).')_([^\s]+)/';
$where = preg_replace($regExp, '$1.$2', $where);
// add the table name before any column that has no table prefix
// since this might cause "unambigious column" errors
if ($meta = $this->metadata()) {
foreach ($meta as $aCol => $x) {
// this covers the LIKE,IN stuff: 'name LIKE "%you%"' 'id IN (2,3,4,5)'
$where = preg_replace('/\s'.$aCol.'\s/', " {$this->table}.$aCol ", $where);
// replace also the column names which are behind a '='
// and do this also if the aCol is at the end of the where clause
// that's what the $ is for
$where = preg_replace('/([=<>])\s*'.$aCol.'(\s|$)/', "$1{$this->table}.$aCol ", $where);
// replace if colName is first and possibly also if at the beginning of the where-string
$where = preg_replace('/(^\s*|\s+)'.$aCol.'\s*([=<>])/', "$1{$this->table}.$aCol$2", $where);
}
}
}
return $where;
}
 
// }}}
// {{{ _buildOrder()
 
/**
*
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param
* @return
*/
function _buildOrder()
{
$order = $this->getOrder();
// replace 'column' by '$this->table.column' if the column is defined for $this->table
if ($meta = $this->metadata()) {
foreach ($meta as $aCol=>$x) {
$order = preg_replace('/(^\s*|\s+|,)'.$aCol.'\s*(,)?/U', "$1{$this->table}.$aCol$2", $order);
}
}
return $order;
}
 
// }}}
// {{{ _buildGroup()
 
/**
* Build the group-clause, replace 'column' by 'table.column'.
*
* @access public
* @param void
* @return string the rendered group clause
*/
function _buildGroup()
{
$group = $this->getGroup();
// replace 'column' by '$this->table.column' if the column is defined for $this->table
if ($meta = $this->metadata()) {
foreach ($meta as $aCol => $x) {
$group = preg_replace('/(^\s*|\s+|,)'.$aCol.'\s*(,)?/U', "$1{$this->table}.$aCol$2", $group);
}
}
return $group;
}
 
// }}}
// {{{ _buildHaving()
 
/**
*
* @version 2003/06/05
* @access public
* @author Johannes Schaefer <johnschaefer@gmx.de>
* @param
* @return string the having clause
*/
function _buildHaving()
{
$having = $this->getHaving();
// replace 'column' by '$this->table.column' if the column is defined for $this->table
if ($meta = $this->metadata()) {
foreach ($meta as $aCol => $x) {
$having = preg_replace('/(^\s*|\s+|,)'.$aCol.'\s*(,)?/U',"$1{$this->table}.$aCol$2",$having);
}
}
return $having;
}
 
// }}}
// {{{ _buildHaving()
 
/**
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param array this array contains the elements of the query,
* indexed by their key, which are: 'select','from','where', etc.
* @param boolean whether this method is called via getCount() or not.
* @return
*/
function _buildSelectQuery($query=array(), $isCalledViaGetCount = false)
{
/*FIXXXME finish this
$cacheKey = md5(serialize(????));
if (isset($this->_queryCache[$cacheKey])) {
$this->_errorLog('using cached query',__LINE__);
return $this->_queryCache[$cacheKey];
}
*/
$where = isset($query['where']) ? $query['where'] : $this->_buildWhere();
if ($where) {
$where = 'WHERE '.$where;
}
$order = isset($query['order']) ? $query['order'] : $this->_buildOrder();
if ($order) {
$order = 'ORDER BY '.$order;
}
$group = isset($query['group']) ? $query['group'] : $this->_buildGroup();
if ($group) {
$group = 'GROUP BY '.$group;
}
$having = isset($query['having']) ? $query['having'] : $this->_buildHaving();
if ($having) {
$having = 'HAVING '.$having;
}
$queryString = sprintf( 'SELECT %s FROM %s %s %s %s %s',
isset($query['select']) ? $query['select'] : $this->_buildSelect(),
isset($query['from']) ? $query['from'] : $this->_buildFrom(),
$where,
$group,
$having,
$order
);
// $query['limit'] has preference!
$limit = isset($query['limit']) ? $query['limit'] : $this->_limit;
if (!$isCalledViaGetCount && @$limit[1]) { // is there a count set?
$queryString=$this->db->modifyLimitQuery($queryString,$limit[0],$limit[1]);
if (DB::isError($queryString)) {
$this->_errorSet('DB_QueryTool::db::modifyLimitQuery failed '.$queryString->getMessage());
$this->_errorLog($queryString->getUserInfo());
return false;
}
}
// $this->_queryCache[$cacheKey] = $queryString;
return $queryString;
}
 
// }}}
// {{{ _buildUpdateQuery()
 
/**
* this simply builds an update query.
*
* @param array the parameter array might contain the following indexes
* 'where' the where clause to be added, i.e.
* UPDATE table SET x=1 WHERE y=0
* here the 'where' part simply would be 'y=0'
* 'set' the actual data to be updated
* in the example above, that would be 'x=1'
* @return string the resulting query
*/
function _buildUpdateQuery($query=array())
{
$where = isset($query['where']) ? $query['where'] : $this->_buildWhere();
if ($where) {
$where = 'WHERE '.$where;
}
 
$updateString = sprintf('UPDATE %s SET %s %s',
$this->table,
$query['set'],
$where
);
return $updateString;
}
 
// }}}
// {{{ execute()
 
/**
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param
* @param string query method
* @return boolean
*/
function execute($query=null, $method='getAll')
{
$this->writeLog();
if (is_null($query)) {
$query = $this->_buildSelectQuery();
}
$this->writeLog('query built: '.$query);
 
// FIXXME on ORACLE this doesnt work, since we return joined columns as _TABLE_COLNAME and the _ in front
// doesnt work on oracle, add a letter before it!!!
$this->_lastQuery = $query;
 
$this->debug($query);
$this->writeLog('start query');
if (DB::isError($res = $this->db->$method($query))) {
$this->writeLog('end query (failed)');
if ($this->getOption('verbose')) {
$this->_errorSet($res->getMessage());
} else {
$this->_errorLog($res->getMessage());
}
$this->_errorLog($res->getUserInfo(), __LINE__);
return false;
} else {
$this->writeLog('end query');
}
$res = $this->_makeIndexed($res);
return $res;
}
 
// }}}
// {{{ writeLog()
 
/**
* Write events to the logfile.
*
* It does some additional work, like time measuring etc. to
* see some additional info
*
*/
function writeLog($text='START')
{
//its still really a quicky.... 'refactor' (nice word) that
if (!isset($this->options['logfile'])) {
return;
}
 
include_once 'Log.php';
if (!class_exists('Log')) {
return;
}
if (!$this->_logObject) {
$this->_logObject =& Log::factory('file', $this->options['logfile']);
}
 
if ($text==='start query' || $text==='end query') {
$bytesSent = $this->db->getAll("SHOW STATUS like 'Bytes_sent'");
$bytesSent = $bytesSent[0]['Value'];
}
if ($text==='START') {
$startTime = split(' ', microtime());
$this->_logData['startTime'] = $startTime[1] + $startTime[0];
}
if ($text==='start query') {
$this->_logData['startBytesSent'] = $bytesSent;
$startTime = split(' ', microtime());
$this->_logData['startQueryTime'] = $startTime[1] + $startTime[0];
return;
}
if ($text==='end query') {
$text .= ' result size: '.((int)$bytesSent-(int)$this->_logData['startBytesSent']).' bytes';
$endTime = split(' ', microtime());
$endTime = $endTime[1] + $endTime[0];
$text .= ', took: '.(($endTime - $this->_logData['startQueryTime'])).' seconds';
}
if (strpos($text, 'query built')===0) {
$endTime = split(' ', microtime());
$endTime = $endTime[1] + $endTime[0];
$this->writeLog('query building took: '.(($endTime - $this->_logData['startTime'])).' seconds');
}
$this->_logObject->log($text);
 
if (strpos($text, 'end query')===0) {
$endTime = split(' ', microtime());
$endTime = $endTime[1] + $endTime[0];
$text = 'time over all: '.(($endTime - $this->_logData['startTime'])).' seconds';
$this->_logObject->log($text);
}
}
 
// }}}
// {{{ returnResult()
 
/**
* Return the chosen result type
*
* @version 2004/04/28
* @access public
* @param object reference
* @return mixed
*/
function returnResult(&$result)
{
if ($this->_resultType == 'none') {
return $result;
}
if ($result === false) {
return false;
}
//what about allowing other (custom) result types?
switch (strtolower($this->_resultType)) {
case 'object': return new DB_QueryTool_Result_Object($result);
case 'array':
default: return new DB_QueryTool_Result($result);
}
}
 
// }}}
// {{{ _makeIndexed()
 
/**
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param mixed
* @return mixed
*/
function &_makeIndexed(&$data)
{
// we can only return an indexed result if the result has a number of columns
if (is_array($data) && sizeof($data) && $key = $this->getIndex()) {
// build the string to evaluate which might be made up out of multiple indexes of a result-row
$evalString = '$val[\''.implode('\'].\',\'.$val[\'',explode(',',$key)).'\']'; //"
 
$indexedData = array();
//FIXXME actually we also need to check ONCE if $val is an array, so to say if $data is 2-dimensional
foreach ($data as $val) {
eval("\$keyValue = $evalString;"); // get the actual real (string-)key (string if multiple cols are used as index)
$indexedData[$keyValue] = $val;
}
unset($data);
return $indexedData;
}
 
return $data;
}
 
// }}}
// {{{ setIndex()
 
/**
* format the result to be indexed by $key
* NOTE: be careful, when using this you should be aware, that if you
* use an index which's value appears multiple times you may loose data
* since a key cant exist multiple times!!
* the result for a result to be indexed by a key(=columnName)
* (i.e. 'relationtoMe') which's values are 'brother' and 'sister'
* or alike normally returns this:
* $res['brother'] = array('name'=>'xxx')
* $res['sister'] = array('name'=>'xxx')
* but if the column 'relationtoMe' contains multiple entries for 'brother'
* then the returned dataset will only contain one brother, since the
* value from the column 'relationtoMe' is used
* and which 'brother' you get depends on a lot of things, like the sortorder,
* how the db saves the data, and whatever else
*
* you can also set indexes which depend on 2 columns, simply pass the parameters like
* 'table1.id,table2.id' it will be used as a string for indexing the result
* and the index will be built using the 2 values given, so a possible
* index might be '1,2' or '2108,29389' this way you can access data which
* have 2 primary keys. Be sure to remember that the index is a string!
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param
* @return
*/
function setIndex($key=null)
{
if ($this->getJoin()) { // is join set?
// replace TABLENAME.COLUMNNAME by _TABLENAME_COLUMNNAME
// since this is only the result-keys can be used for indexing :-)
$regExp = '/('.implode('|', $this->getJoin('tables')).')\.([^\s]+)/';
$key = preg_replace($regExp, '_$1_$2', $key);
 
// remove the table name if it is in front of '<$this->table>.columnname'
// since the key doesnt contain it neither
if ($meta = $this->metadata()) {
foreach ($meta as $aCol => $x) {
$key = preg_replace('/'.$this->table.'\.'.$aCol.'/', $aCol, $key);
}
}
}
$this->_index = $key;
}
 
// }}}
// {{{ getIndex()
 
/**
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param
* @return
*/
function getIndex()
{
return $this->_index;
}
 
// }}}
// {{{ useResult()
 
/**
* Choose the type of the returned result
*
* @version 2004/04/28
* @access public
* @param string $type ['array' | 'object' | 'none']
* For BC reasons, $type=true is equal to 'array',
* $type=false is equal to 'none'
*/
function useResult($type='array')
{
if ($type === true) {
$type = 'array';
} elseif ($type === false) {
$type = 'none';
}
switch (strtolower($type)) {
case 'array':
$this->_resultType = 'array';
require_once 'DB/QueryTool/Result.php';
break;
case 'object':
$this->_resultType = 'object';
require_once 'DB/QueryTool/Result/Object.php';
break;
default:
$this->_resultType = 'none';
}
}
 
// }}}
// {{{ setErrorCallback()
 
/**
* set both callbacks
* @param string
*/
function setErrorCallback($param='')
{
$this->setErrorLogCallback($param);
$this->setErrorSetCallback($param);
}
 
// }}}
// {{{ setErrorLogCallback()
 
/**
* @param string
*/
function setErrorLogCallback($param='')
{
$errorLogCallback = &PEAR::getStaticProperty('DB_QueryTool','_errorLogCallback');
$errorLogCallback = $param;
}
 
// }}}
// {{{ setErrorSetCallback()
 
/**
* @param string
*/
function setErrorSetCallback($param='')
{
$errorSetCallback = &PEAR::getStaticProperty('DB_QueryTool','_errorSetCallback');
$errorSetCallback = $param;
}
 
// }}}
// {{{ _errorLog()
 
/**
* sets error log and adds additional info
*
* @version 2002/04/16
* @access public
* @author Wolfram Kriesing <wk@visionp.de>
* @param string the actual message, first word should always be the method name,
* to build the message like this: className::methodname
* @param integer the line number
*/
function _errorLog($msg, $line='unknown')
{
$this->_errorHandler('log', $msg, $line);
/*
if ($this->getOption('verbose') == true)
{
$this->_errorLog(get_class($this)."::$msg ($line)");
return;
}
 
if ($this->_errorLogCallback)
call_user_func($this->_errorLogCallback, $msg);
*/
}
 
// }}}
// {{{ _errorSet()
 
/**
* @param string
* @param string
*/
function _errorSet($msg, $line='unknown')
{
$this->_errorHandler('set', $msg, $line);
}
 
// }}}
// {{{ _errorHandler()
 
/**
* @param
* @param string
* @param string
*/
function _errorHandler($logOrSet, $msg, $line='unknown')
{
/* what did i do this for?
if ($this->getOption('verbose') == true)
{
$this->_errorHandler($logOrSet, get_class($this)."::$msg ($line)");
return;
}
*/
 
$msg = get_class($this)."::$msg ($line)";
 
$logOrSet = ucfirst($logOrSet);
$callback = &PEAR::getStaticProperty('DB_QueryTool','_error'.$logOrSet.'Callback');
//var_dump($callback);
//if ($callback)
// call_user_func($callback, $msg);
// else
// ?????
 
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/QueryTool/Result/Object.php
New file
0,0 → 1,89
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the DB_QueryTool_Result_Row and DB_QueryTool_Result_Object classes
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_QueryTool
* @author Roman Dostovalov, Com-tec-so S.A.<roman.dostovalov@ctco.lv>
* @copyright 2004-2005 Roman Dostovalov
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Object.php,v 1.3 2005/02/25 16:38:28 quipo Exp $
* @link http://pear.php.net/package/DB_QueryTool
*/
 
/**
* Include parent class
*/
require_once 'DB/QueryTool/Result.php';
 
/**
* DB_QueryTool_Result_Row class
*
* @category Database
* @package DB_QueryTool
* @author Roman Dostovalov, Com-tec-so S.A.<roman.dostovalov@ctco.lv>
* @copyright 2004-2005 Roman Dostovalov
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/DB_QueryTool
*/
class DB_QueryTool_Result_Row
{
/**
* create object properties from the array
* @param array
*/
function DB_QueryTool_Result_Row($arr)
{
foreach ($arr as $key => $value) {
$this->$key = $value;
}
}
}
 
// -----------------------------------------------------------------------------
 
/**
* DB_QueryTool_Result_Object class
*
* @category Database
* @package DB_QueryTool
* @author Roman Dostovalov, Com-tec-so S.A.<roman.dostovalov@ctco.lv>
* @copyright 2004-2005 Roman Dostovalov
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/DB_QueryTool
*/
class DB_QueryTool_Result_Object extends DB_QueryTool_Result
{
// {{{ fetchRow
 
/**
* This function emulates PEAR::DB fetchRow() method
* With this function DB_QueryTool can transparently replace PEAR::DB
*
* @todo implement fetchmode support?
* @access public
* @return void
*/
function fetchRow()
{
$arr = $this->getNext();
if (!PEAR::isError($arr)) {
$row = new DB_QueryTool_Result_Row($arr);
return $row;
}
return false;
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/QueryTool/Result.php
New file
0,0 → 1,261
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the DB_QueryTool_Result class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_QueryTool
* @author Wolfram Kriesing <wk@visionp.de>
* @author Paolo Panto <wk@visionp.de>
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @copyright 2003-2005 Wolfram Kriesing, Paolo Panto, Lorenzo Alberton
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Result.php,v 1.8 2005/02/25 16:38:28 quipo Exp $
* @link http://pear.php.net/package/DB_QueryTool
*/
 
/**
* DB_QueryTool_Result class
*
* This result actually contains the 'data' itself, the number of rows
* returned and some additional info
* using ZE2 you can also get retrieve data from the result doing the following:
* <DB_QueryTool_Common-instance>->getAll()->getCount()
* or
* <DB_QueryTool_Common-instance>->getAll()->getData()
*
* @category Database
* @package DB_QueryTool
* @author Wolfram Kriesing <wk@visionp.de>
* @author Paolo Panto <wk@visionp.de>
* @author Lorenzo Alberton <l dot alberton at quipo dot it>
* @copyright 2003-2005 Wolfram Kriesing, Paolo Panto, Lorenzo Alberton
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/DB_QueryTool
*/
class DB_QueryTool_Result
{
// {{{ class vars
 
/**
* @var array
*/
var $_data = array();
 
/**
* @var array
*/
var $_dataKeys = array();
 
/**
* @var integer
*/
var $_count = 0;
 
/**
* the counter for the methods getFirst, getNext
* @var array
*/
var $_counter = null;
 
// }}}
// {{{ DB_QueryTool_Result()
 
/**
* create a new instance of result with the data returned by the query
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wolfram@kriesing.de>
* @param array the data returned by the result
*/
function DB_QueryTool_Result($data)
{
if (!count($data)) {
$this->_count = 0;
} else {
list($firstElement) = $data;
if (is_array($firstElement)) { // is the array a collection of rows?
$this->_count = sizeof($data);
} else {
if (sizeof($data) > 0) {
$this->_count = 1;
} else {
$this->_count = 0;
}
}
}
$this->_data = $data;
}
 
// }}}
// {{{ numRows
 
/**
* return the number of rows returned. This is an alias for getCount().
*
* @access public
* @return integer
*/
function numRows()
{
return $this->_count;
}
 
// }}}
// {{{ getCount()
 
/**
* return the number of rows returned
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wolfram@kriesing.de>
* @return integer the number of rows returned
*/
function getCount()
{
return $this->_count;
}
 
// }}}
// {{{ getData()
 
/**
* get all the data returned
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wolfram@kriesing.de>
* @param string $key
* @return mixed array or PEAR_Error
*/
function getData($key=null)
{
if (is_null($key)) {
return $this->_data;
}
if ($this->_data[$key]) {
return $this->_data[$key];
}
return new PEAR_Error("there is no element with the key '$key'!");
}
 
// }}}
// {{{ getFirst()
 
/**
* get the first result set
* we are not using next, current, and reset, since those ignore keys
* which are empty or 0
*
* @version 2002/07/11
* @access public
* @author Wolfram Kriesing <wolfram@kriesing.de>
* @return mixed
*/
function getFirst()
{
if ($this->getCount() > 0) {
$this->_dataKeys = array_keys($this->_data);
$this->_counter = 0;
return $this->_data[$this->_dataKeys[$this->_counter]];
}
return new PEAR_Error('There are no elements!');
}
 
// }}}
// {{{ getNext()
 
/**
* Get next result set. If getFirst() has never been called before,
* it calls that method.
* @return mixed
* @access public
*/
function getNext()
{
if (!$this->initDone()) {
return $this->getFirst();
}
if ($this->hasMore()) {
$this->_counter++;
return $this->_data[$this->_dataKeys[$this->_counter]];
}
return new PEAR_Error('there are no more elements!');
}
 
// }}}
// {{{ hasMore()
 
/**
* check if there are other rows
*
* @return boolean
* @access public
*/
function hasMore()
{
if ($this->_counter+1 < $this->getCount()) {
return true;
}
return false;
}
 
// }}}
// {{{ fetchRow
 
/**
* This function emulates PEAR::DB fetchRow() method.
* With this method, DB_QueryTool can transparently replace PEAR_DB
*
* @todo implement fetchmode support?
* @access public
* @return void
*/
function fetchRow()
{
if ($this->hasMore()) {
$arr = $this->getNext();
if (!PEAR::isError($arr)) {
return $arr;
}
}
return false;
}
 
// }}}
// {{{ initDone
 
/**
* Helper method. Check if $this->_dataKeys has been initialized
*
* @return boolean
* @access private
*/
function initDone()
{
return (
isset($this->_dataKeys) &&
is_array($this->_dataKeys) &&
count($this->_dataKeys)
);
}
 
// }}}
 
#TODO
#function getPrevious()
#function getLast()
 
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/QueryTool/EasyJoin.php
New file
0,0 → 1,135
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the DB_QueryTool_EasyJoin class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_QueryTool
* @author Wolfram Kriesing <wk@visionp.de>
* @author Paolo Panto <wk@visionp.de>
* @copyright 2003-2005 Wolfram Kriesing, Paolo Panto
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: EasyJoin.php,v 1.9 2005/02/27 17:15:05 quipo Exp $
* @link http://pear.php.net/package/DB_QueryTool
*/
 
/**
* require the DB_QueryTool_Query class
*/
require_once 'DB/QueryTool/Query.php';
 
/**
* DB_QueryTool_EasyJoin class
*
* @category Database
* @package DB_QueryTool
* @author Wolfram Kriesing <wk@visionp.de>
* @copyright 2003-2005 Wolfram Kriesing
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/DB_QueryTool
*/
class DB_QueryTool_EasyJoin extends DB_QueryTool_Query
{
// {{{ class vars
 
/**
* This is the regular expression that shall be used to find a table's shortName
* in a column name, the string found by using this regular expression will be removed
* from the column name and it will be checked if it is a table name
* i.e. the default '/_id$/' would find the table name 'user' from the column name 'user_id'
*
* @var string regexp
*/
var $_tableNamePreg = '/_id$/';
 
/**
* This is to find the column name that is referred by it, so the default find
* from 'user_id' the column 'id' which will be used to refer to the 'user' table
*
* @var string regexp
*/
var $_columnNamePreg = '/^.*_/';
 
// }}}
// {{{ __construct()
 
/**
* call parent constructor
* @param mixed $dsn DSN string, DSN array or DB object
* @param array $options
*/
function __construct($dsn=false, $options=array())
{
parent::DB_QueryTool_Query($dsn, $options);
}
 
// }}}
// {{{ autoJoin()
 
/**
* Join the given tables, using the column names, to find out how to join the tables;
* i.e., if table1 has a column named &quot;table2_id&quot;, this method will join
* &quot;WHERE table1.table2_id=table2.id&quot;.
* All joins made here are only concatenated via AND.
* @param array $tables
*/
function autoJoin($tables)
{
// FIXXME if $tables is empty autoJoin all available tables that have a relation
// to $this->table, starting to search in $this->table
settype($tables, 'array');
// add this->table to the tables array, so we go thru the current table first
$tables = array_merge(array($this->table), $tables);
 
$shortNameIndexed = $this->getTableSpec(true, $tables);
$nameIndexed = $this->getTableSpec(false, $tables);
 
//print_r($shortNameIndexed);
//print_r($tables); print '<br><br>';
if (sizeof($shortNameIndexed) != sizeof($tables)) {
$this->_errorLog("autoJoin-ERROR: not all the tables are in the tableSpec!<br />");
}
 
$joinTables = array();
$joinConditions = array();
foreach ($tables as $aTable) { // go through $this->table and all the given tables
if ($metadata = $this->metadata($aTable))
foreach ($metadata as $aCol => $x) { // go through each row to check which might be related to $aTable
$possibleTableShortName = preg_replace($this->_tableNamePreg, '' , $aCol);
$possibleColumnName = preg_replace($this->_columnNamePreg, '' , $aCol);
//print "$aTable.$aCol .... possibleTableShortName=$possibleTableShortName .... possibleColumnName=$possibleColumnName<br />";
if (isset($shortNameIndexed[$possibleTableShortName])) {
// are the tables given in the tableSpec?
if (!$shortNameIndexed[$possibleTableShortName]['name'] ||
!$nameIndexed[$aTable]['name']) {
// its an error of the developer, so log the error, dont show it to the end user
$this->_errorLog("autoJoin-ERROR: '$aTable' is not given in the tableSpec!<br />");
} else {
// do only join different table.col combination,
// we should not join stuff like 'question.question=question.question'
// this would be quite stupid, but it used to be :-(
if ($shortNameIndexed[$possibleTableShortName]['name'] != $aTable ||
$possibleColumnName != $aCol
) {
$where = $shortNameIndexed[$possibleTableShortName]['name'].".$possibleColumnName=$aTable.$aCol";
$this->addJoin($nameIndexed[$aTable]['name'], $where);
$this->addJoin($shortNameIndexed[$possibleTableShortName]['name'], $where);
}
}
}
}
}
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/dbase.php
New file
0,0 → 1,510
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's dbase extension
* for interacting with dBase databases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: dbase.php,v 1.39 2005/02/19 23:25:25 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's dbase extension
* for interacting with dBase databases
*
* These methods overload the ones declared in DB_common.
*
* @category Database
* @package DB
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_dbase extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'dbase';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'dbase';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => false,
'new_link' => false,
'numrows' => true,
'pconnect' => false,
'prepare' => false,
'ssl' => false,
'transactions' => false,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* A means of emulating result resources
* @var array
*/
var $res_row = array();
 
/**
* The quantity of results so far
*
* For emulating result resources.
*
* @var integer
*/
var $result = 0;
 
/**
* Maps dbase data type id's to human readable strings
*
* The human readable values are based on the output of PHP's
* dbase_get_header_info() function.
*
* @var array
* @since Property available since Release 1.7.0
*/
var $types = array(
'C' => 'character',
'D' => 'date',
'L' => 'boolean',
'M' => 'memo',
'N' => 'number',
);
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_dbase()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database and create it if it doesn't exist
*
* Don't call this method directly. Use DB::connect() instead.
*
* PEAR DB's dbase driver supports the following extra DSN options:
* + mode An integer specifying the read/write mode to use
* (0 = read only, 1 = write only, 2 = read/write).
* Available since PEAR DB 1.7.0.
* + fields An array of arrays that PHP's dbase_create() function needs
* to create a new database. This information is used if the
* dBase file specified in the "database" segment of the DSN
* does not exist. For more info, see the PHP manual's
* {@link http://php.net/dbase_create dbase_create()} page.
* Available since PEAR DB 1.7.0.
*
* Example of how to connect and establish a new dBase file if necessary:
* <code>
* require_once 'DB.php';
*
* $dsn = array(
* 'phptype' => 'dbase',
* 'database' => '/path/and/name/of/dbase/file',
* 'mode' => 2,
* 'fields' => array(
* array('a', 'N', 5, 0),
* array('b', 'C', 40),
* array('c', 'C', 255),
* array('d', 'C', 20),
* ),
* );
* $options = array(
* 'debug' => 2,
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
* </code>
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('dbase')) {
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
/*
* Turn track_errors on for entire script since $php_errormsg
* is the only way to find errors from the dbase extension.
*/
ini_set('track_errors', 1);
$php_errormsg = '';
 
if (!file_exists($dsn['database'])) {
$this->dsn['mode'] = 2;
if (empty($dsn['fields']) || !is_array($dsn['fields'])) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
'the dbase file does not exist and '
. 'it could not be created because '
. 'the "fields" element of the DSN '
. 'is not properly set');
}
$this->connection = @dbase_create($dsn['database'],
$dsn['fields']);
if (!$this->connection) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
'the dbase file does not exist and '
. 'the attempt to create it failed: '
. $php_errormsg);
}
} else {
if (!isset($this->dsn['mode'])) {
$this->dsn['mode'] = 0;
}
$this->connection = @dbase_open($dsn['database'],
$this->dsn['mode']);
if (!$this->connection) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$php_errormsg);
}
}
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @dbase_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ &query()
 
function &query($query = null)
{
// emulate result resources
$this->res_row[(int)$this->result] = 0;
$tmp =& new DB_result($this, $this->result++);
return $tmp;
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum === null) {
$rownum = $this->res_row[(int)$result]++;
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @dbase_get_record_with_names($this->connection, $rownum);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @dbase_get_record($this->connection, $rownum);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($foo)
{
return @dbase_numfields($this->connection);
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
function numRows($foo)
{
return @dbase_numrecords($this->connection);
}
 
// }}}
// {{{ quoteSmart()
 
/**
* Formats input so it can be safely used in a query
*
* @param mixed $in the data to be formatted
*
* @return mixed the formatted data. The format depends on the input's
* PHP type:
* + null = the string <samp>NULL</samp>
* + boolean = <samp>T</samp> if true or
* <samp>F</samp> if false. Use the <kbd>Logical</kbd>
* data type.
* + integer or double = the unquoted number
* + other (including strings and numeric strings) =
* the data with single quotes escaped by preceeding
* single quotes then the whole string is encapsulated
* between single quotes
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
function quoteSmart($in)
{
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
return $in ? 'T' : 'F';
} elseif (is_null($in)) {
return 'NULL';
} else {
return "'" . $this->escapeSimple($in) . "'";
}
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about the current database
*
* @param mixed $result THIS IS UNUSED IN DBASE. The current database
* is examined regardless of what is provided here.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::tableInfo()
* @since Method available since Release 1.7.0
*/
function tableInfo($result = null, $mode = null)
{
if (function_exists('dbase_get_header_info')) {
$id = @dbase_get_header_info($this->connection);
if (!$id && $php_errormsg) {
return $this->raiseError(DB_ERROR,
null, null, null,
$php_errormsg);
}
} else {
/*
* This segment for PHP 4 is loosely based on code by
* Hadi Rusiah <deegos@yahoo.com> in the comments on
* the dBase reference page in the PHP manual.
*/
$db = @fopen($this->dsn['database'], 'r');
if (!$db) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$php_errormsg);
}
 
$id = array();
$i = 0;
 
$line = fread($db, 32);
while (!feof($db)) {
$line = fread($db, 32);
if (substr($line, 0, 1) == chr(13)) {
break;
} else {
$pos = strpos(substr($line, 0, 10), chr(0));
$pos = ($pos == 0 ? 10 : $pos);
$id[$i] = array(
'name' => substr($line, 0, $pos),
'type' => $this->types[substr($line, 11, 1)],
'length' => ord(substr($line, 16, 1)),
'precision' => ord(substr($line, 17, 1)),
);
}
$i++;
}
 
fclose($db);
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$res = array();
$count = count($id);
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
$res[$i] = array(
'table' => $this->dsn['database'],
'name' => $case_func($id[$i]['name']),
'type' => $id[$i]['type'],
'len' => $id[$i]['length'],
'flags' => ''
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
return $res;
}
 
// }}}
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/mysqli.php
New file
0,0 → 1,1076
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* The PEAR DB driver for PHP's mysqli extension
* for interacting with MySQL databases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: mysqli.php,v 1.69 2005/03/04 23:12:36 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the DB_common class so it can be extended from
*/
require_once 'DB/common.php';
 
/**
* The methods PEAR DB uses to interact with PHP's mysqli extension
* for interacting with MySQL databases
*
* This is for MySQL versions 4.1 and above. Requires PHP 5.
*
* Note that persistent connections no longer exist.
*
* These methods overload the ones declared in DB_common.
*
* @category Database
* @package DB
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
* @since Class functional since Release 1.6.3
*/
class DB_mysqli extends DB_common
{
// {{{ properties
 
/**
* The DB driver type (mysql, oci8, odbc, etc.)
* @var string
*/
var $phptype = 'mysqli';
 
/**
* The database syntax variant to be used (db2, access, etc.), if any
* @var string
*/
var $dbsyntax = 'mysqli';
 
/**
* The capabilities of this DB implementation
*
* The 'new_link' element contains the PHP version that first provided
* new_link support for this DBMS. Contains false if it's unsupported.
*
* Meaning of the 'limit' element:
* + 'emulate' = emulate with fetch row by number
* + 'alter' = alter the query
* + false = skip rows
*
* @var array
*/
var $features = array(
'limit' => 'alter',
'new_link' => false,
'numrows' => true,
'pconnect' => false,
'prepare' => false,
'ssl' => true,
'transactions' => true,
);
 
/**
* A mapping of native error codes to DB error codes
* @var array
*/
var $errorcode_map = array(
1004 => DB_ERROR_CANNOT_CREATE,
1005 => DB_ERROR_CANNOT_CREATE,
1006 => DB_ERROR_CANNOT_CREATE,
1007 => DB_ERROR_ALREADY_EXISTS,
1008 => DB_ERROR_CANNOT_DROP,
1022 => DB_ERROR_ALREADY_EXISTS,
1044 => DB_ERROR_ACCESS_VIOLATION,
1046 => DB_ERROR_NODBSELECTED,
1048 => DB_ERROR_CONSTRAINT,
1049 => DB_ERROR_NOSUCHDB,
1050 => DB_ERROR_ALREADY_EXISTS,
1051 => DB_ERROR_NOSUCHTABLE,
1054 => DB_ERROR_NOSUCHFIELD,
1061 => DB_ERROR_ALREADY_EXISTS,
1062 => DB_ERROR_ALREADY_EXISTS,
1064 => DB_ERROR_SYNTAX,
1091 => DB_ERROR_NOT_FOUND,
1100 => DB_ERROR_NOT_LOCKED,
1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
1142 => DB_ERROR_ACCESS_VIOLATION,
1146 => DB_ERROR_NOSUCHTABLE,
1216 => DB_ERROR_CONSTRAINT,
1217 => DB_ERROR_CONSTRAINT,
);
 
/**
* The raw database connection created by PHP
* @var resource
*/
var $connection;
 
/**
* The DSN information for connecting to a database
* @var array
*/
var $dsn = array();
 
 
/**
* Should data manipulation queries be committed automatically?
* @var bool
* @access private
*/
var $autocommit = true;
 
/**
* The quantity of transactions begun
*
* {@internal While this is private, it can't actually be designated
* private in PHP 5 because it is directly accessed in the test suite.}}
*
* @var integer
* @access private
*/
var $transaction_opcount = 0;
 
/**
* The database specified in the DSN
*
* It's a fix to allow calls to different databases in the same script.
*
* @var string
* @access private
*/
var $_db = '';
 
/**
* Array for converting MYSQLI_*_FLAG constants to text values
* @var array
* @access public
* @since Property available since Release 1.6.5
*/
var $mysqli_flags = array(
MYSQLI_NOT_NULL_FLAG => 'not_null',
MYSQLI_PRI_KEY_FLAG => 'primary_key',
MYSQLI_UNIQUE_KEY_FLAG => 'unique_key',
MYSQLI_MULTIPLE_KEY_FLAG => 'multiple_key',
MYSQLI_BLOB_FLAG => 'blob',
MYSQLI_UNSIGNED_FLAG => 'unsigned',
MYSQLI_ZEROFILL_FLAG => 'zerofill',
MYSQLI_AUTO_INCREMENT_FLAG => 'auto_increment',
MYSQLI_TIMESTAMP_FLAG => 'timestamp',
MYSQLI_SET_FLAG => 'set',
// MYSQLI_NUM_FLAG => 'numeric', // unnecessary
// MYSQLI_PART_KEY_FLAG => 'multiple_key', // duplicatvie
MYSQLI_GROUP_FLAG => 'group_by'
);
 
/**
* Array for converting MYSQLI_TYPE_* constants to text values
* @var array
* @access public
* @since Property available since Release 1.6.5
*/
var $mysqli_types = array(
MYSQLI_TYPE_DECIMAL => 'decimal',
MYSQLI_TYPE_TINY => 'tinyint',
MYSQLI_TYPE_SHORT => 'int',
MYSQLI_TYPE_LONG => 'int',
MYSQLI_TYPE_FLOAT => 'float',
MYSQLI_TYPE_DOUBLE => 'double',
// MYSQLI_TYPE_NULL => 'DEFAULT NULL', // let flags handle it
MYSQLI_TYPE_TIMESTAMP => 'timestamp',
MYSQLI_TYPE_LONGLONG => 'bigint',
MYSQLI_TYPE_INT24 => 'mediumint',
MYSQLI_TYPE_DATE => 'date',
MYSQLI_TYPE_TIME => 'time',
MYSQLI_TYPE_DATETIME => 'datetime',
MYSQLI_TYPE_YEAR => 'year',
MYSQLI_TYPE_NEWDATE => 'date',
MYSQLI_TYPE_ENUM => 'enum',
MYSQLI_TYPE_SET => 'set',
MYSQLI_TYPE_TINY_BLOB => 'tinyblob',
MYSQLI_TYPE_MEDIUM_BLOB => 'mediumblob',
MYSQLI_TYPE_LONG_BLOB => 'longblob',
MYSQLI_TYPE_BLOB => 'blob',
MYSQLI_TYPE_VAR_STRING => 'varchar',
MYSQLI_TYPE_STRING => 'char',
MYSQLI_TYPE_GEOMETRY => 'geometry',
);
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function DB_mysqli()
{
$this->DB_common();
}
 
// }}}
// {{{ connect()
 
/**
* Connect to the database server, log in and open the database
*
* Don't call this method directly. Use DB::connect() instead.
*
* PEAR DB's mysqli driver supports the following extra DSN options:
* + When the 'ssl' $option passed to DB::connect() is true:
* + key The path to the key file.
* + cert The path to the certificate file.
* + ca The path to the certificate authority file.
* + capath The path to a directory that contains trusted SSL
* CA certificates in pem format.
* + cipher The list of allowable ciphers for SSL encryption.
*
* Example of how to connect using SSL:
* <code>
* require_once 'DB.php';
*
* $dsn = array(
* 'phptype' => 'mysqli',
* 'username' => 'someuser',
* 'password' => 'apasswd',
* 'hostspec' => 'localhost',
* 'database' => 'thedb',
* 'key' => 'client-key.pem',
* 'cert' => 'client-cert.pem',
* 'ca' => 'cacert.pem',
* 'capath' => '/path/to/ca/dir',
* 'cipher' => 'AES',
* );
*
* $options = array(
* 'ssl' => true,
* );
*
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
* </code>
*
* @param array $dsn the data source name
* @param bool $persistent should the connection be persistent?
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function connect($dsn, $persistent = false)
{
if (!PEAR::loadExtension('mysqli')) {
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
}
 
$this->dsn = $dsn;
if ($dsn['dbsyntax']) {
$this->dbsyntax = $dsn['dbsyntax'];
}
 
$ini = ini_get('track_errors');
ini_set('track_errors', 1);
$php_errormsg = '';
 
if ($this->getOption('ssl') === true) {
$init = mysqli_init();
mysqli_ssl_set(
$init,
empty($dsn['key']) ? null : $dsn['key'],
empty($dsn['cert']) ? null : $dsn['cert'],
empty($dsn['ca']) ? null : $dsn['ca'],
empty($dsn['capath']) ? null : $dsn['capath'],
empty($dsn['cipher']) ? null : $dsn['cipher']
);
if ($this->connection = @mysqli_real_connect(
$init,
$dsn['hostspec'],
$dsn['username'],
$dsn['password'],
$dsn['database'],
$dsn['port'],
$dsn['socket']))
{
$this->connection = $init;
}
} else {
$this->connection = @mysqli_connect(
$dsn['hostspec'],
$dsn['username'],
$dsn['password'],
$dsn['database'],
$dsn['port'],
$dsn['socket']
);
}
 
ini_set('track_errors', $ini);
 
if (!$this->connection) {
if (($err = @mysqli_connect_error()) != '') {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$err);
} else {
return $this->raiseError(DB_ERROR_CONNECT_FAILED,
null, null, null,
$php_errormsg);
}
}
 
if ($dsn['database']) {
$this->_db = $dsn['database'];
}
 
return DB_OK;
}
 
// }}}
// {{{ disconnect()
 
/**
* Disconnects from the database server
*
* @return bool TRUE on success, FALSE on failure
*/
function disconnect()
{
$ret = @mysqli_close($this->connection);
$this->connection = null;
return $ret;
}
 
// }}}
// {{{ simpleQuery()
 
/**
* Sends a query to the database server
*
* @param string the SQL query string
*
* @return mixed + a PHP result resrouce for successful SELECT queries
* + the DB_OK constant for other successful queries
* + a DB_Error object on failure
*/
function simpleQuery($query)
{
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
if ($this->_db) {
if (!@mysqli_select_db($this->connection, $this->_db)) {
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
}
}
if (!$this->autocommit && $ismanip) {
if ($this->transaction_opcount == 0) {
$result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=0');
$result = @mysqli_query($this->connection, 'BEGIN');
if (!$result) {
return $this->mysqliRaiseError();
}
}
$this->transaction_opcount++;
}
$result = @mysqli_query($this->connection, $query);
if (!$result) {
return $this->mysqliRaiseError();
}
if (is_object($result)) {
return $result;
}
return DB_OK;
}
 
// }}}
// {{{ nextResult()
 
/**
* Move the internal mysql result pointer to the next available result.
*
* This method has not been implemented yet.
*
* @param resource $result a valid sql result resource
* @return false
* @access public
*/
function nextResult($result)
{
return false;
}
 
// }}}
// {{{ fetchInto()
 
/**
* Places a row from the result set into the given array
*
* Formating of the array and the data therein are configurable.
* See DB_result::fetchInto() for more information.
*
* This method is not meant to be called directly. Use
* DB_result::fetchInto() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result the query result resource
* @param array $arr the referenced array to put the data in
* @param int $fetchmode how the resulting array should be indexed
* @param int $rownum the row number to fetch (0 = first row)
*
* @return mixed DB_OK on success, NULL when the end of a result set is
* reached or on failure
*
* @see DB_result::fetchInto()
*/
function fetchInto($result, &$arr, $fetchmode, $rownum = null)
{
if ($rownum !== null) {
if (!@mysqli_data_seek($result, $rownum)) {
return null;
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @mysqli_fetch_array($result, MYSQLI_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
} else {
$arr = @mysqli_fetch_row($result);
}
if (!$arr) {
return null;
}
if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
/*
* Even though this DBMS already trims output, we do this because
* a field might have intentional whitespace at the end that
* gets removed by DB_PORTABILITY_RTRIM under another driver.
*/
$this->_rtrimArrayValues($arr);
}
if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
$this->_convertNullArrayValuesToEmpty($arr);
}
return DB_OK;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set
*
* This method is not meant to be called directly. Use
* DB_result::free() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return @mysqli_free_result($result);
}
 
// }}}
// {{{ numCols()
 
/**
* Gets the number of columns in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numCols() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of columns. A DB_Error object on failure.
*
* @see DB_result::numCols()
*/
function numCols($result)
{
$cols = @mysqli_num_fields($result);
if (!$cols) {
return $this->mysqliRaiseError();
}
return $cols;
}
 
// }}}
// {{{ numRows()
 
/**
* Gets the number of rows in a result set
*
* This method is not meant to be called directly. Use
* DB_result::numRows() instead. It can't be declared "protected"
* because DB_result is a separate object.
*
* @param resource $result PHP's query result resource
*
* @return int the number of rows. A DB_Error object on failure.
*
* @see DB_result::numRows()
*/
function numRows($result)
{
$rows = @mysqli_num_rows($result);
if ($rows === null) {
return $this->mysqliRaiseError();
}
return $rows;
}
 
// }}}
// {{{ autoCommit()
 
/**
* Enables or disables automatic commits
*
* @param bool $onoff true turns it on, false turns it off
*
* @return int DB_OK on success. A DB_Error object if the driver
* doesn't support auto-committing transactions.
*/
function autoCommit($onoff = false)
{
// XXX if $this->transaction_opcount > 0, we should probably
// issue a warning here.
$this->autocommit = $onoff ? true : false;
return DB_OK;
}
 
// }}}
// {{{ commit()
 
/**
* Commits the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function commit()
{
if ($this->transaction_opcount > 0) {
if ($this->_db) {
if (!@mysqli_select_db($this->connection, $this->_db)) {
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
}
}
$result = @mysqli_query($this->connection, 'COMMIT');
$result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1');
$this->transaction_opcount = 0;
if (!$result) {
return $this->mysqliRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
if ($this->transaction_opcount > 0) {
if ($this->_db) {
if (!@mysqli_select_db($this->connection, $this->_db)) {
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
}
}
$result = @mysqli_query($this->connection, 'ROLLBACK');
$result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1');
$this->transaction_opcount = 0;
if (!$result) {
return $this->mysqliRaiseError();
}
}
return DB_OK;
}
 
// }}}
// {{{ affectedRows()
 
/**
* Determines the number of rows affected by a data maniuplation query
*
* 0 is returned for queries that don't manipulate data.
*
* @return int the number of rows. A DB_Error object on failure.
*/
function affectedRows()
{
if (DB::isManip($this->last_query)) {
return @mysqli_affected_rows($this->connection);
} else {
return 0;
}
}
 
// }}}
// {{{ nextId()
 
/**
* Returns the next free id in a sequence
*
* @param string $seq_name name of the sequence
* @param boolean $ondemand when true, the seqence is automatically
* created if it does not exist
*
* @return int the next id number in the sequence.
* A DB_Error object on failure.
*
* @see DB_common::nextID(), DB_common::getSequenceName(),
* DB_mysqli::createSequence(), DB_mysqli::dropSequence()
*/
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
do {
$repeat = 0;
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query('UPDATE ' . $seqname
. ' SET id = LAST_INSERT_ID(id + 1)');
$this->popErrorHandling();
if ($result === DB_OK) {
// COMMON CASE
$id = @mysqli_insert_id($this->connection);
if ($id != 0) {
return $id;
}
 
// EMPTY SEQ TABLE
// Sequence table must be empty for some reason,
// so fill it and return 1
// Obtain a user-level lock
$result = $this->getOne('SELECT GET_LOCK('
. "'${seqname}_lock', 10)");
if (DB::isError($result)) {
return $this->raiseError($result);
}
if ($result == 0) {
return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED);
}
 
// add the default value
$result = $this->query('REPLACE INTO ' . $seqname
. ' (id) VALUES (0)');
if (DB::isError($result)) {
return $this->raiseError($result);
}
 
// Release the lock
$result = $this->getOne('SELECT RELEASE_LOCK('
. "'${seqname}_lock')");
if (DB::isError($result)) {
return $this->raiseError($result);
}
// We know what the result will be, so no need to try again
return 1;
 
} elseif ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE)
{
// ONDEMAND TABLE CREATION
$result = $this->createSequence($seq_name);
 
// Since createSequence initializes the ID to be 1,
// we do not need to retrieve the ID again (or we will get 2)
if (DB::isError($result)) {
return $this->raiseError($result);
} else {
// First ID of a newly created sequence is 1
return 1;
}
 
} elseif (DB::isError($result) &&
$result->getCode() == DB_ERROR_ALREADY_EXISTS)
{
// BACKWARDS COMPAT
// see _BCsequence() comment
$result = $this->_BCsequence($seqname);
if (DB::isError($result)) {
return $this->raiseError($result);
}
$repeat = 1;
}
} while ($repeat);
 
return $this->raiseError($result);
}
 
/**
* Creates a new sequence
*
* @param string $seq_name name of the new sequence
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::createSequence(), DB_common::getSequenceName(),
* DB_mysqli::nextID(), DB_mysqli::dropSequence()
*/
function createSequence($seq_name)
{
$seqname = $this->getSequenceName($seq_name);
$res = $this->query('CREATE TABLE ' . $seqname
. ' (id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'
. ' PRIMARY KEY(id))');
if (DB::isError($res)) {
return $res;
}
// insert yields value 1, nextId call will generate ID 2
return $this->query("INSERT INTO ${seqname} (id) VALUES (0)");
}
 
// }}}
// {{{ dropSequence()
 
/**
* Deletes a sequence
*
* @param string $seq_name name of the sequence to be deleted
*
* @return int DB_OK on success. A DB_Error object on failure.
*
* @see DB_common::dropSequence(), DB_common::getSequenceName(),
* DB_mysql::nextID(), DB_mysql::createSequence()
*/
function dropSequence($seq_name)
{
return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name));
}
 
// }}}
// {{{ _BCsequence()
 
/**
* Backwards compatibility with old sequence emulation implementation
* (clean up the dupes)
*
* @param string $seqname the sequence name to clean up
*
* @return bool true on success. A DB_Error object on failure.
*
* @access private
*/
function _BCsequence($seqname)
{
// Obtain a user-level lock... this will release any previous
// application locks, but unlike LOCK TABLES, it does not abort
// the current transaction and is much less frequently used.
$result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
if (DB::isError($result)) {
return $result;
}
if ($result == 0) {
// Failed to get the lock, can't do the conversion, bail
// with a DB_ERROR_NOT_LOCKED error
return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED);
}
 
$highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}");
if (DB::isError($highest_id)) {
return $highest_id;
}
 
// This should kill all rows except the highest
// We should probably do something if $highest_id isn't
// numeric, but I'm at a loss as how to handle that...
$result = $this->query('DELETE FROM ' . $seqname
. " WHERE id <> $highest_id");
if (DB::isError($result)) {
return $result;
}
 
// If another thread has been waiting for this lock,
// it will go thru the above procedure, but will have no
// real effect
$result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')");
if (DB::isError($result)) {
return $result;
}
return true;
}
 
// }}}
// {{{ quoteIdentifier()
 
/**
* Quotes a string so it can be safely used as a table or column name
*
* MySQL can't handle the backtick character (<kbd>`</kbd>) in
* table or column names.
*
* @param string $str identifier name to be quoted
*
* @return string quoted identifier string
*
* @see DB_common::quoteIdentifier()
* @since Method available since Release 1.6.0
*/
function quoteIdentifier($str)
{
return '`' . $str . '`';
}
 
// }}}
// {{{ escapeSimple()
 
/**
* Escapes a string according to the current DBMS's standards
*
* @param string $str the string to be escaped
*
* @return string the escaped string
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
function escapeSimple($str)
{
return @mysqli_real_escape_string($this->connection, $str);
}
 
// }}}
// {{{ modifyLimitQuery()
 
/**
* Adds LIMIT clauses to a query string according to current DBMS standards
*
* @param string $query the query to modify
* @param int $from the row to start to fetching (0 = the first row)
* @param int $count the numbers of rows to fetch
* @param mixed $params array, string or numeric data to be used in
* execution of the statement. Quantity of items
* passed must match quantity of placeholders in
* query: meaning 1 placeholder for non-array
* parameters or 1 placeholder per array element.
*
* @return string the query string with LIMIT clauses added
*
* @access protected
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
if (DB::isManip($query)) {
return $query . " LIMIT $count";
} else {
return $query . " LIMIT $from, $count";
}
}
 
// }}}
// {{{ mysqliRaiseError()
 
/**
* Produces a DB_Error object regarding the current problem
*
* @param int $errno if the error is being manually raised pass a
* DB_ERROR* constant here. If this isn't passed
* the error information gathered from the DBMS.
*
* @return object the DB_Error object
*
* @see DB_common::raiseError(),
* DB_mysqli::errorNative(), DB_common::errorCode()
*/
function mysqliRaiseError($errno = null)
{
if ($errno === null) {
if ($this->options['portability'] & DB_PORTABILITY_ERRORS) {
$this->errorcode_map[1022] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL;
$this->errorcode_map[1062] = DB_ERROR_CONSTRAINT;
} else {
// Doing this in case mode changes during runtime.
$this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS;
$this->errorcode_map[1048] = DB_ERROR_CONSTRAINT;
$this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS;
}
$errno = $this->errorCode(mysqli_errno($this->connection));
}
return $this->raiseError($errno, null, null, null,
@mysqli_errno($this->connection) . ' ** ' .
@mysqli_error($this->connection));
}
 
// }}}
// {{{ errorNative()
 
/**
* Gets the DBMS' native error code produced by the last query
*
* @return int the DBMS' error code
*/
function errorNative()
{
return @mysqli_errno($this->connection);
}
 
// }}}
// {{{ tableInfo()
 
/**
* Returns information about a table or a result set
*
* @param object|string $result DB_result object from a query or a
* string containing the name of a table.
* While this also accepts a query result
* resource identifier, this behavior is
* deprecated.
* @param int $mode a valid tableInfo mode
*
* @return array an associative array with the information requested.
* A DB_Error object on failure.
*
* @see DB_common::setOption()
*/
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @mysqli_query($this->connection,
"SELECT * FROM $result LIMIT 0");
$got_string = true;
} elseif (isset($result->result)) {
/*
* Probably received a result object.
* Extract the result resource identifier.
*/
$id = $result->result;
$got_string = false;
} else {
/*
* Probably received a result resource identifier.
* Copy it.
* Deprecated. Here for compatibility only.
*/
$id = $result;
$got_string = false;
}
 
if (!is_a($id, 'mysqli_result')) {
return $this->mysqliRaiseError(DB_ERROR_NEED_MORE_DATA);
}
 
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) {
$case_func = 'strtolower';
} else {
$case_func = 'strval';
}
 
$count = @mysqli_num_fields($id);
$res = array();
 
if ($mode) {
$res['num_fields'] = $count;
}
 
for ($i = 0; $i < $count; $i++) {
$tmp = @mysqli_fetch_field($id);
 
$flags = '';
foreach ($this->mysqli_flags as $const => $means) {
if ($tmp->flags & $const) {
$flags .= $means . ' ';
}
}
if ($tmp->def) {
$flags .= 'default_' . rawurlencode($tmp->def);
}
$flags = trim($flags);
 
$res[$i] = array(
'table' => $case_func($tmp->table),
'name' => $case_func($tmp->name),
'type' => isset($this->mysqli_types[$tmp->type])
? $this->mysqli_types[$tmp->type]
: 'unknown',
'len' => $tmp->max_length,
'flags' => $flags,
);
 
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
}
if ($mode & DB_TABLEINFO_ORDERTABLE) {
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
}
}
 
// free the result only if we were called on a table
if ($got_string) {
@mysqli_free_result($id);
}
return $res;
}
 
// }}}
// {{{ getSpecialQuery()
 
/**
* Obtains the query string needed for listing a given type of objects
*
* @param string $type the kind of objects you want to retrieve
*
* @return string the SQL query string or null if the driver doesn't
* support the object type requested
*
* @access protected
* @see DB_common::getListOf()
*/
function getSpecialQuery($type)
{
switch ($type) {
case 'tables':
return 'SHOW TABLES';
case 'users':
return 'SELECT DISTINCT User FROM mysql.user';
case 'databases':
return 'SHOW DATABASES';
default:
return null;
}
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/DB/ldap.php
New file
0,0 → 1,994
<?php
//
// Pear DB LDAP - Database independent query interface definition
// for PHP's LDAP extension.
//
// Copyright (c) 2002-2003 Ludovico Magnocavallo <ludo@sumatrasolutions.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Contributors
// - Piotr Roszatycki <dexter@debian.org>
// DB_ldap::base() method, support for LDAP sequences, various fixes
// - Aaron Spencer Hawley <aaron dot hawley at uvm dot edu>
// fix to use port number if present in DB_ldap->connect()
//
// $Id: ldap.php,v 1.22 2005/06/16 19:17:54 ludoo Exp $
//
 
require_once 'DB.php';
require_once 'DB/common.php';
 
define("DB_ERROR_BIND_FAILED", -26);
define("DB_ERROR_UNKNOWN_LDAP_ACTION", -27);
 
/**
* LDAP result class
*
* LDAP_result extends DB_result to provide specific LDAP
* result methods.
*
* @version 1.0
* @author Ludovico Magnocavallo <ludo@sumatrasolutions.com>
* @package DB
*/
 
class LDAP_result extends DB_result
{
 
// {{{ properties
 
/**
* data returned from ldap_entries()
* @access private
*/
var $_entries = null;
/**
* result rows as hash of records
* @access private
*/
var $_recordset = null;
/**
* current record as hash
* @access private
*/
var $_record = null;
 
// }}}
// {{{ constructor
 
/**
* class constructor, calls DB_result constructor
* @param ref $dbh reference to the db instance
* @param resource $result ldap command result
*/
function LDAP_result(&$dbh, $result)
{
$this->DB_result($dbh, $result);
}
 
/**
* fetch rows of data into $this->_recordset
*
* called once as soon as something needs to be returned
* @access private
* @param resource $result ldap command result
* @return boolean true
*/
function getRows() {
if ($this->_recordset === null) {
// begin processing result into recordset
$this->_entries = ldap_get_entries($this->dbh->connection, $this->result);
$this->row_counter = $this->_entries['count'];
$i = 1;
$rs_template = array();
if (count($this->dbh->attributes) > 0) {
reset($this->dbh->attributes);
while (list($a_index, $a_name) = each($this->dbh->attributes)) $rs_template[$a_name] = '';
}
while (list($entry_idx, $entry) = each($this->_entries)) {
// begin first loop, iterate through entries
if (!empty($this->dbh->limit_from) && ($i < $this->dbh->limit_from)) continue;
if (!empty($this->dbh->limit_count) && ($i > $this->dbh->limit_count)) break;
$rs = $rs_template;
if (!is_array($entry)) continue;
while (list($attr, $attr_values) = each($entry)) {
// begin second loop, iterate through attributes
if (is_int($attr) || $attr == 'count') continue;
if (is_string($attr_values)) $rs[$attr] = $attr_values;
else {
$value = '';
while (list($value_idx, $attr_value) = each($attr_values)) {
// begin third loop, iterate through attribute values
if (!is_int($value_idx)) continue;
if (empty($value)) $value = $attr_value;
else {
if (is_array($value)) $value[] = $attr_value;
else $value = array($value, $attr_value);
}
// else $value .= "\n$attr_value";
// end third loop
}
$rs[$attr] = $value;
}
// end second loop
}
reset($rs);
$this->_recordset[$entry_idx] = $rs;
$i++;
// end first loop
}
$this->_entries = null;
if (!is_array($this->_recordset))
$this->_recordset = array();
if (!empty($this->dbh->sorting)) {
$sorting_method = (!empty($this->dbh->sorting_method) ? $this->dbh->sorting_method : 'cmp');
uksort($this->_recordset, array(&$this, $sorting_method));
}
reset($this->_recordset);
// end processing result into recordset
}
return DB_OK;
}
 
 
/**
* Fetch and return a row of data (it uses driver->fetchInto for that)
* @param int $fetchmode format of fetched row
* @param int $rownum the row number to fetch
*
* @return array a row of data, NULL on no more rows or PEAR_Error on error
*
* @access public
*/
function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
{
$this->getRows();
if (count($this->_recordset) == 0) return null;
if ($this->_record !== null) $this->_record = next($this->_recordset);
else $this->_record = current($this->_recordset);
$row = $this->_record;
return $row;
}
 
 
/**
* Fetch a row of data into an existing variable.
*
* @param mixed $arr reference to data containing the row
* @param integer $fetchmode format of fetched row
* @param integer $rownum the row number to fetch
*
* @return mixed DB_OK on success, NULL on no more rows or
* a DB_Error object on error
*
* @access public
*/
 
function fetchInto(&$ar, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null)
{
$this->getRows();
if ($this->_record !== null) $this->_record = next($this->_recordset);
else $this->_record = current($this->_recordset);
$ar = $this->_record;
if (!$ar) {
return null;
}
return DB_OK;
}
 
/**
* return all records
*
* returns a hash of all records, basically returning
* a copy of $this->_recordset
* @param integer $fetchmode format of fetched row
* @param integer $rownum the row number to fetch (not used, here for interface compatibility)
*
* @return mixed DB_OK on success, NULL on no more rows or
* a DB_Error object on error
*
* @access public
*/
function fetchAll($fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null)
{
$this->getRows();
return($this->_recordset);
}
 
/**
* Get the the number of columns in a result set.
*
* @return int the number of columns, or a DB error
*
* @access public
*/
function numCols($result)
{
$this->getRows();
return(count(array_keys($this->_record)));
}
 
function cmp($a, $b)
{
return(strcmp(strtolower($this->_recordset[$a][$this->dbh->sorting]), strtolower($this->_recordset[$b][$this->dbh->sorting])));
}
 
/**
* Get the number of rows in a result set.
*
* @return int the number of rows, or a DB error
*
* @access public
*/
function numRows()
{
$this->getRows();
return $this->row_counter;
}
 
/**
* Get the next result if a batch of queries was executed.
*
* @return bool true if a new result is available or false if not.
*
* @access public
*/
function nextResult()
{
return $this->dbh->nextResult($this->result);
}
 
/**
* Frees the resources allocated for this result set.
* @return int error code
*
* @access public
*/
function free()
{
$this->_recordset = null;
$this->_record = null;
ldap_free_result($this->result);
$this->result = null;
return true;
}
 
/**
* @deprecated
*/
function tableInfo($mode = null)
{
return $this->dbh->tableInfo($this->result, $mode);
}
 
/**
* returns the actual rows number
* @return integer
*/
function getRowCounter()
{
$this->getRows();
return $this->row_counter;
}
}
 
/**
* LDAP DB interface class
*
* LDAP extends DB_common to provide DB compliant
* access to LDAP servers
*
* @version 1.0
* @author Ludovico Magnocavallo <ludo@sumatrasolutions.com>
* @package DB
*/
 
class DB_ldap extends DB_common
{
// {{{ properties
 
/**
* LDAP connection
* @access private
*/
var $connection;
/**
* base dn
* @access private
*/
var $base = '';
/**
* default base dn
* @access private
*/
var $d_base = '';
/**
* query base dn
* @access private
*/
var $q_base = '';
/**
* array of LDAP actions that only manipulate data
* returning a true/false value
* @access private
*/
var $manip = array('add', 'compare', 'delete', 'modify', 'mod_add', 'mod_del', 'mod_replace', 'rename');
/**
* store the default real LDAP action to perform
* @access private
*/
var $action = 'search';
/**
* store the real LDAP action to perform
* (ie PHP ldap function to call) for a query
* @access private
*/
var $q_action = '';
/**
* store optional parameters passed
* to the real LDAP action
* @access private
*/
var $q_params = array();
 
// }}}
 
/**
* Constructor, calls DB_common constructor
*
* @see DB_common::DB_common()
*/
function DB_ldap()
{
$this->DB_common();
$this->phptype = 'ldap';
$this->dbsyntax = 'ldap';
$this->features = array(
'prepare' => false,
'pconnect' => false,
'transactions' => false,
'limit' => false
);
$this->errorcode_map = array(
0x10 => DB_ERROR_NOSUCHFIELD, // LDAP_NO_SUCH_ATTRIBUTE
0x11 => DB_ERROR_INVALID, // LDAP_UNDEFINED_TYPE
0x12 => DB_ERROR_INVALID, // LDAP_INAPPROPRIATE_MATCHING
0x13 => DB_ERROR_INVALID, // LDAP_CONSTRAINT_VIOLATION
0x14 => DB_ERROR_ALREADY_EXISTS, // LDAP_TYPE_OR_VALUE_EXISTS
0x15 => DB_ERROR_INVALID, // LDAP_INVALID_SYNTAX
0x20 => DB_ERROR_NOT_FOUND, // LDAP_NO_SUCH_OBJECT
0x21 => DB_ERROR_NOT_FOUND, // LDAP_ALIAS_PROBLEM
0x22 => DB_ERROR_INVALID, // LDAP_INVALID_DN_SYNTAX
0x23 => DB_ERROR_INVALID, // LDAP_IS_LEAF
0x24 => DB_ERROR_INVALID, // LDAP_ALIAS_DEREF_PROBLEM
0x30 => DB_ERROR_ACCESS_VIOLATION, // LDAP_INAPPROPRIATE_AUTH
0x31 => DB_ERROR_ACCESS_VIOLATION, // LDAP_INVALID_CREDENTIALS
0x32 => DB_ERROR_ACCESS_VIOLATION, // LDAP_INSUFFICIENT_ACCESS
0x40 => DB_ERROR_MISMATCH, // LDAP_NAMING_VIOLATION
0x41 => DB_ERROR_MISMATCH, // LDAP_OBJECT_CLASS_VIOLATION
0x44 => DB_ERROR_ALREADY_EXISTS, // LDAP_ALREADY_EXISTS
0x51 => DB_ERROR_CONNECT_FAILED, // LDAP_SERVER_DOWN
0x57 => DB_ERROR_SYNTAX // LDAP_FILTER_ERROR
);
}
 
/**
* Connect and bind to LDAP server with either anonymous or authenticated bind depending on dsn info
*
* @param array $dsninfo dsn info as passed by DB::connect()
* @param boolean $persistent kept for interface compatibility
* @return DB_OK if successfully connected. A DB error code is returned on failure.
*/
function connect($dsninfo, $persistent = false)
{
if (!PEAR::loadExtension('ldap'))
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
 
$this->dsn = $dsninfo;
$user = $dsninfo['username'];
$pw = $dsninfo['password'];
$host = $dsninfo['hostspec'];
$port = $dsninfo['port'];
$this->base = $dsninfo['database'];
$this->d_base = $this->base;
 
if (empty($host)) {
return $this->raiseError("no host specified $host");
} // else ...
 
if (isset($port)) {
$conn = ldap_connect($host, $port);
} else {
$conn = ldap_connect($host);
}
if (!$conn) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED);
}
if ($user && $pw) {
$bind = @ldap_bind($conn, $user, $pw);
} else {
$bind = @ldap_bind($conn);
}
if (!$bind) {
return $this->raiseError(DB_ERROR_BIND_FAILED);
}
$this->connection = $conn;
return DB_OK;
}
 
/**
* Unbinds from LDAP server
*
* @return int ldap_unbind() return value
*/
function disconnect()
{
$ret = @ldap_unbind($this->connection);
$this->connection = null;
return $ret;
}
 
 
/**
* Performs a request against the LDAP server
*
* The type of request (and the corresponding PHP ldap function called)
* depend on two additional parameters, added in respect to the
* DB_common interface.
*
* @param string $filter text of the request to send to the LDAP server
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return result from ldap function or DB Error object if no result
*/
function simpleQuery($filter, $action = null, $params = null)
{
if ($action === null) {
$action = (!empty($this->q_action) ? $this->q_action : $this->action);
}
if ($params === null) {
$params = (count($this->q_params) > 0 ? $this->q_params : array());
}
if (!$this->isManip($action)) {
$base = $this->q_base ? $this->q_base : $this->base;
$attributes = array();
$attrsonly = 0;
$sizelimit = 0;
$timelimit = 0;
$deref = LDAP_DEREF_NEVER;
$sorting = '';
$sorting_method = '';
reset($params);
while (list($k, $v) = each($params)) {
if (isset(${$k})) ${$k} = $v;
}
$this->sorting = $sorting;
$this->sorting_method = $sorting_method;
$this->attributes = $attributes;
# double escape char for filter: '(o=Przedsi\C4\99biorstwo)' => '(o=Przedsi\\C4\\99biorstwo)'
$filter = str_replace('\\', '\\\\', $filter);
$this->last_query = $filter;
if ($action == 'search')
$result = @ldap_search($this->connection, $base, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref);
else if ($action == 'list')
$result = @ldap_list($this->connection, $base, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref);
else if ($action == 'read')
$result = @ldap_read($this->connection, $base, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref);
else
return $this->ldapRaiseError(DB_ERROR_UNKNOWN_LDAP_ACTION);
if (!$result) {
return $this->ldapRaiseError();
}
} else {
# If first argument is an array, it contains the entry with DN.
if (is_array($filter)) {
$entry = $filter;
$filter = $entry["dn"];
} else {
$entry = array();
}
unset($entry["dn"]);
$attribute = '';
$value = '';
$newrdn = '';
$newparent = '';
$deleteoldrdn = false;
reset($params);
while (list($k, $v) = each($params)) {
if (isset(${$k})) ${$k} = $v;
}
$this->last_query = $filter;
if ($action == 'add')
$result = @ldap_add($this->connection, $filter, $entry);
else if ($action == 'compare')
$result = @ldap_add($this->connection, $filter, $attribute, $value);
else if ($action == 'delete')
$result = @ldap_delete($this->connection, $filter);
else if ($action == 'modify')
$result = @ldap_modify($this->connection, $filter, $entry);
else if ($action == 'mod_add')
$result = @ldap_mod_add($this->connection, $filter, $entry);
else if ($action == 'mod_del')
$result = @ldap_mod_del($this->connection, $filter, $entry);
else if ($action == 'mod_replace')
$result = @ldap_mod_replace($this->connection, $filter, $entry);
else if ($action == 'rename')
$result = @ldap_rename($this->connection, $filter, $newrdn, $newparent, $deleteoldrdn);
else
return $this->ldapRaiseError(DB_ERROR_UNKNOWN_LDAP_ACTION);
if (!$result) {
return $this->ldapRaiseError();
}
}
$this->freeQuery();
return $result;
}
 
/**
* Executes a query performing variables substitution in the query text
*
* @param string $stmt text of the request to send to the LDAP server
* @param array $data query variables values to substitute
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return LDAP_result object or DB Error object if no result
* @see DB_common::executeEmulateQuery $this->simpleQuery()
*/
function execute($stmt, $data = false, $action = null, $params = array())
{
$this->q_params = $params;
$realquery = $this->executeEmulateQuery($stmt, $data);
if (DB::isError($realquery)) {
return $realquery;
}
$result = $this->simpleQuery($realquery);
if (DB::isError($result) || $result === DB_OK) {
return $result;
} else {
return new LDAP_result($this, $result);
}
}
 
/**
* Executes multiple queries performing variables substitution for each query
*
* @param string $stmt text of the request to send to the LDAP server
* @param array $data query variables values to substitute
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return LDAP_result object or DB Error object if no result
* @see DB_common::executeMultiple
*/
function executeMultiple($stmt, &$data, $action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::executeMultiple($stmt, $data));
}
 
/**
* Executes a query substituting variables if any are present
*
* @param string $query text of the request to send to the LDAP server
* @param array $data query variables values to substitute
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return LDAP_result object or DB Error object if no result
* @see DB_common::prepare() $this->execute()$this->simpleQuery()
*/
function &query($query, $data = array(), $action = null, $params = array()) {
// $this->q_action = $action ? $action : $this->action;
// $this->q_params = $params;
if (sizeof($data) > 0) {
$sth = $this->prepare($query);
if (DB::isError($sth)) {
return $sth;
}
return $this->execute($sth, $data);
} else {
$result = $this->simpleQuery($query);
if (DB::isError($result) || $result === DB_OK) {
return $result;
} else {
return new LDAP_result($this, $result);
}
}
}
 
/**
* Modifies a query to return only a set of rows, stores $from and $count for LDAP_result
*
* @param string $query text of the request to send to the LDAP server
* @param int $from record position from which to start returning data
* @param int $count number of records to return
* @return modified query text (no modifications are made, see above)
*/
function modifyLimitQuery($query, $from, $count)
{
$this->limit_from = $from;
$this->limit_count = $count;
return $query;
}
 
/**
* Executes a query returning only a specified number of rows
*
* This method only saves the $from and $count parameters for LDAP_result
* where the actual records processing takes place
*
* @param string $query text of the request to send to the LDAP server
* @param int $from record position from which to start returning data
* @param int $count number of records to return
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return LDAP_result object or DB Error object if no result
*/
function limitQuery($query, $from, $count, $action = null, $params = array())
{
$query = $this->modifyLimitQuery($query, $from, $count);
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return $this->query($query, $action, $params);
}
 
/**
* Fetch the first column of the first row of data returned from
* a query. Takes care of doing the query and freeing the results
* when finished.
*
* @param $query the SQL query
* @param $data if supplied, prepare/execute will be used
* with this array as execute parameters
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return array
* @see DB_common::getOne()
* @access public
*/
function &getOne($query, $data = array(), $action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::getOne($query, $data));
}
 
/**
* Fetch the first row of data returned from a query. Takes care
* of doing the query and freeing the results when finished.
*
* @param $query the SQL query
* @param $fetchmode the fetch mode to use
* @param $data array if supplied, prepare/execute will be used
* with this array as execute parameters
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @access public
* @return array the first row of results as an array indexed from
* 0, or a DB error code.
* @see DB_common::getRow()
* @access public
*/
function &getRow($query,
$data = null,
$fetchmode = DB_FETCHMODE_DEFAULT,
$action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::getRow($query, $data, $fetchmode));
}
 
/**
* Fetch the first column of data returned from a query. Takes care
* of doing the query and freeing the results when finished.
*
* @param $query the SQL query
* @param $col which column to return (integer [column number,
* starting at 0] or string [column name])
* @param $data array if supplied, prepare/execute will be used
* with this array as execute parameters
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @access public
* @return array an indexed array with the data from the first
* row at index 0, or a DB error code.
* @see DB_common::getCol()
* @access public
*/
function &getCol($query, $col = 0, $data = array(), $action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::getCol($query, $col, $data));
}
 
/**
* Calls DB_common::getAssoc()
*
* @param $query the SQL query
* @param $force_array (optional) used only when the query returns
* exactly two columns. If true, the values of the returned array
* will be one-element arrays instead of scalars.
* starting at 0] or string [column name])
* @param array $data if supplied, prepare/execute will be used
* with this array as execute parameters
* @param $fetchmode the fetch mode to use
* @param boolean $group see DB_Common::getAssoc()
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @access public
* @return array an indexed array with the data from the first
* row at index 0, or a DB error code.
* @see DB_common::getAssoc()
* @access public
*/
function &getAssoc($query, $force_array = false, $data = array(),
$fetchmode = DB_FETCHMODE_ORDERED, $group = false,
$action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::getAssoc($query, $force_array, $data, $fetchmode, $group));
}
 
/**
* Fetch all the rows returned from a query.
*
* @param $query the SQL query
* @param array $data if supplied, prepare/execute will be used
* with this array as execute parameters
* @param $fetchmode the fetch mode to use
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @access public
* @return array an nested array, or a DB error
* @see DB_common::getAll()
*/
function &getAll($query,
$data = null,
$fetchmode = DB_FETCHMODE_DEFAULT,
$action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::getAll($query, $data, $fetchmode));
}
 
function numRows($result)
{
return $result->numRows();
}
 
function getTables()
{
return $this->ldapRaiseError(DB_ERROR_NOT_CAPABLE);
}
 
function getListOf($type)
{
return $this->ldapRaiseError(DB_ERROR_NOT_CAPABLE);
}
 
function isManip($action)
{
return(in_array($action, $this->manip));
}
 
function freeResult()
{
return true;
}
 
function freeQuery($query = '')
{
$this->q_action = '';
$this->q_base = '';
$this->q_params = array();
$this->attributes = null;
$this->sorting = '';
return true;
}
 
// Deprecated, will be removed in future releases.
function base($base = null)
{
$this->q_base = ($base !== null) ? $base : null;
return true;
}
 
function ldapSetBase($base = null)
{
$this->base = ($base !== null) ? $base : $this->d_base;
$this->q_base = '';
return true;
}
 
function ldapSetAction($action = 'search')
{
if ($action != 'search' && $action != 'list' && $action != 'read') {
return $this->ldapRaiseError(DB_ERROR_UNKNOWN_LDAP_ACTION);
}
$this->action = $action;
$this->q_action = '';
return true;
}
 
/**
* Get the next value in a sequence.
*
* LDAP provides transactions for only one entry and we need to
* prevent race condition. If unique value before and after modify
* aren't equal then wait and try again.
*
* The name of sequence is LDAP DN of entry.
*
* @access public
* @param string $seq_name the DN of the sequence
* @param bool $ondemand whether to create the sequence on demand
* @return a sequence integer, or a DB error
*/
function nextId($seq_name, $ondemand = true)
{
$repeat = 0;
do {
// Get the sequence entry
$this->base($seq_name);
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$data = $this->getRow("objectClass=*");
$this->popErrorHandling();
 
if (DB::isError($data)) {
// DB_ldap doesn't use DB_ERROR_NOT_FOUND
if ($ondemand && $repeat == 0
&& $data->getCode() == DB_ERROR) {
// Try to create sequence and repeat
$repeat = 1;
$data = $this->createSequence($seq_name);
if (DB::isError($data)) {
return $this->ldapRaiseError($data);
}
} else {
// Other error
return $this->ldapRaiseError($data);
}
} else {
// Increment sequence value
$data["cn"]++;
// Unique identificator of transaction
$seq_unique = mt_rand();
$data["uid"] = $seq_unique;
// Modify the LDAP entry
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$data = $this->simpleQuery($data, 'modify');
$this->popErrorHandling();
if (DB::isError($data)) {
return $this->ldapRaiseError($data);
}
// Get the entry and check if it contains our unique value
$this->base($seq_name);
$data = $this->getRow("objectClass=*");
if (DB::isError($data)) {
return $this->ldapRaiseError($data);
}
if ($data["uid"] != $seq_unique) {
// It is not our entry. Wait a little time and repeat
sleep(1);
$repeat = 1;
} else {
$repeat = 0;
}
}
} while ($repeat);
 
if (DB::isError($data)) {
return $data;
}
return $data["cn"];
}
 
/**
* Create the sequence
*
* The sequence entry is based on core schema with extensibleObject,
* so it should work with any LDAP server which doesn't check schema
* or supports extensibleObject object class.
*
* Sequence name have to be DN started with "sn=$seq_id,", i.e.:
*
* $seq_name = "sn=uidNumber,ou=sequences,dc=php,dc=net";
*
* dn: $seq_name
* objectClass: top
* objectClass: extensibleObject
* sn: $seq_id
* cn: $seq_value
* uid: $seq_uniq
*
* @param string $seq_name the DN of the sequence
* @return mixed DB_OK on success or DB error on error
* @access public
*/
function createSequence($seq_name)
{
// Extract $seq_id from DN
ereg("^([^,]*),", $seq_name, $regs);
$seq_id = $regs[1];
 
// Create the sequence entry
$data = array(
dn => $seq_name,
objectclass => array("top", "extensibleObject"),
sn => $seq_id,
cn => 0,
uid => 0
);
 
// Add the LDAP entry
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$data = $this->simpleQuery($data, 'add');
$this->popErrorHandling();
return $data;
}
 
/**
* Drop a sequence
*
* @param string $seq_name the DN of the sequence
* @return mixed DB_OK on success or DB error on error
* @access public
*/
function dropSequence($seq_name)
{
// Delete the sequence entry
$data = array(
dn => $seq_name,
);
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$data = $this->simpleQuery($data, 'delete');
$this->popErrorHandling();
return $data;
}
 
// {{{ ldapRaiseError()
 
function ldapRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode(ldap_errno($this->connection));
}
if ($this->q_action !== null) {
return $this->raiseError($errno, null, null,
sprintf('%s base="%s" filter="%s"',
$this->q_action, $this->q_base, $this->last_query
),
$errno == DB_ERROR_UNKNOWN_LDAP_ACTION ? null : @ldap_error($this->connection));
} else {
return $this->raiseError($errno, null, null, "???",
@ldap_error($this->connection));
}
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
?>
/tags/v1.0-Homere/bibliotheque/pear/Auth.php
New file
0,0 → 1,869
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Martin Jansen <mj@php.net> |
// +----------------------------------------------------------------------+
//
// $Id: Auth.php,v 1.67 2003/10/20 06:36:34 yavo Exp $
//
 
require_once 'PEAR.php';
 
define('AUTH_IDLED', -1);
define('AUTH_EXPIRED', -2);
define('AUTH_WRONG_LOGIN', -3);
 
/**
* PEAR::Auth
*
* The PEAR::Auth class provides methods for creating an
* authentication system using PHP.
*
* @author Martin Jansen <mj@php.net>
* @package Auth
* @version $Revision: 1.67 $
*/
class Auth {
 
/**
* Auth lifetime in seconds
*
* If this variable is set to 0, auth never expires
*
* @var integer
* @see setExpire(), checkAuth()
*/
var $expire = 0;
 
/**
* Has the auth session expired?
*
* @var bool
* @see checkAuth(), drawLogin()
*/
var $expired = false;
 
/**
* Maximum time of idleness in seconds
*
* The difference to $expire is, that the idletime gets
* refreshed each time, checkAuth() is called. If this
* variable is set to 0, idle time is never checked.
*
* @var integer
* @see setIdle(), checkAuth()
*/
var $idle = 0;
 
/**
* Is the maximum idletime over?
*
* @var boolean
* @see checkAuth(), drawLogin();
*/
var $idled = false;
 
/**
* Storage object
*
* @var object
* @see Auth(), validateLogin()
*/
var $storage = '';
 
/**
* Function defined by the user, that creates the login screen
*
* @var string
*/
var $loginFunction = '';
 
/**
* Should the login form be displayed?
*
* @var bool
* @see setShowlogin()
*/
var $showLogin = true;
 
/**
* Current authentication status
*
* @var string
*/
var $status = '';
 
/**
* Username
*
* @var string
*/
var $username = '';
 
/**
* Password
*
* @var string
*/
var $password = '';
 
/**
* Login callback function name
*
* @var string
* @see setLoginCallback()
*/
var $loginCallback = '';
 
/**
* Failed Login callback function name
*
* @var string
* @see setLoginFailedCallback()
*/
var $loginFailedCallback = '';
 
/**
* Logout callback function name
*
* @var string
* @see setLogoutCallback()
*/
var $logoutCallback = '';
 
/**
* Auth session-array name
*
* @var string
*/
var $_sessionName = '_authsession';
/**
* Package Version
*
* @var string
*/
var $version = "1.2.3";
 
// {{{ Constructor
 
/**
* Constructor
*
* Set up the storage driver.
*
* @param string Type of the storage driver
* @param mixed Additional options for the storage driver
* (example: if you are using DB as the storage
* driver, you have to pass the dsn string here)
*
* @param string Name of the function that creates the login form
* @param boolean Should the login form be displayed if neccessary?
* @return void
*/
function Auth($storageDriver, $options = '', $loginFunction = '', $showLogin = true)
{
if (!empty($options['sessionName'])) {
$this->_sessionName = $options['sessionName'];
unset($options['sessionName']);
}
 
if ($loginFunction != '' && is_callable($loginFunction)) {
$this->loginFunction = $loginFunction;
}
 
if (is_bool($showLogin)) {
$this->showLogin = $showLogin;
}
 
if (is_object($storageDriver)) {
$this->storage =& $storageDriver;
} else {
$this->storage = $this->_factory($storageDriver, $options);
}
// Pass a reference to auth to the container, ugly but works
// this is used by the DB container to use method setAuthData not staticaly.
$this->storage->_auth_obj =& $this;
}
 
// }}}
// {{{ _factory()
 
/**
* Return a storage driver based on $driver and $options
*
* @access private
* @static
* @param string $driver Type of storage class to return
* @param string $options Optional parameters for the storage class
* @return object Object Storage object
*/
function _factory($driver, $options = '')
{
$storage_path = 'Auth/Container/' . $driver . '.php';
$storage_class = 'Auth_Container_' . $driver;
 
require_once $storage_path;
 
return new $storage_class($options);
}
 
// }}}
// {{{ assignData()
 
/**
* Assign data from login form to internal values
*
* This function takes the values for username and password
* from $HTTP_POST_VARS and assigns them to internal variables.
* If you wish to use another source apart from $HTTP_POST_VARS,
* you have to derive this function.
*
* @access private
* @global $HTTP_POST_VARS
* @see Auth
* @return void
*/
function assignData()
{
$post = &$this->_importGlobalVariable('post');
 
if (isset($post['username']) && $post['username'] != '') {
$this->username = (get_magic_quotes_gpc() == 1 ? stripslashes($post['username']) : $post['username']);
}
 
if (isset($post['password']) && $post['password'] != '') {
$this->password = (get_magic_quotes_gpc() == 1 ? stripslashes($post['password']) : $post['password'] );
}
 
}
 
// }}}
// {{{ start()
 
/**
* Start new auth session
*
* @access public
* @return void
*/
function start()
{
$this->assignData();
 
@session_start();
 
if (!$this->checkAuth()) {
$this->login();
}
}
 
// }}}
// {{{ login()
 
/**
* Login function
*
* @access private
* @return void
*/
function login()
{
$login_ok = false;
 
/**
* When the user has already entered a username,
* we have to validate it.
*/
if (!empty($this->username)) {
if (true === $this->storage->fetchData($this->username, $this->password)) {
$login_ok = true;
} else {
if (is_callable($this->loginFailedCallback)) {
call_user_func($this->loginFailedCallback,$this->username, $this);
}
}
}
 
if (!empty($this->username) && $login_ok) {
$this->setAuth($this->username);
if (is_callable($this->loginCallback)) {
call_user_func($this->loginCallback,$this->username, $this);
}
}
 
/**
* If the login failed or the user entered no username,
* output the login screen again.
*/
if (!empty($this->username) && !$login_ok) {
$this->status = AUTH_WRONG_LOGIN;
}
 
if ((empty($this->username) || !$login_ok) && $this->showLogin) {
$this->drawLogin($this->storage->activeUser);
return;
}
}
 
// }}}
// {{{ setExpire()
 
/**
* Set the maximum expire time
*
* @access public
* @param integer time in seconds
* @param bool add time to current expire time or not
* @return void
*/
function setExpire($time, $add = false)
{
if ($add) {
$this->expire += $time;
} else {
$this->expire = $time;
}
}
 
// }}}
// {{{ setIdle()
 
/**
* Set the maximum idle time
*
* @access public
* @param integer time in seconds
* @param bool add time to current maximum idle time or not
* @return void
*/
function setIdle($time, $add = false)
{
if ($add) {
$this->idle += $time;
} else {
$this->idle = $time;
}
}
 
// }}}
// {{{ setSessionname()
 
/**
* Set name of the session to a customized value.
*
* If you are using multiple instances of PEAR::Auth
* on the same domain, you can change the name of
* session per application via this function.
*
* @access public
* @param string New name for the session
* @return void
*/
function setSessionname($name = 'PHPSESSID')
{
@session_name($name);
}
 
// }}}
// {{{ setShowLogin()
 
/**
* Should the login form be displayed if neccessary?
*
* @access public
* @param bool show login form or not
* @return void
*/
function setShowLogin($showLogin = true)
{
$this->showLogin = $showLogin;
}
 
/**
* Register a callback function to be called on user login.
* The function will receive two parameters, the username and a reference to the auth object.
*
* @access public
* @param string callback function name
* @return void
* @see setLogoutCallback()
*/
function setLoginCallback($loginCallback)
{
$this->loginCallback = $loginCallback;
}
 
/**
* Register a callback function to be called on failed user login.
* The function will receive a single parameter, the username and a reference to the auth object.
*
* @access public
* @param string callback function name
* @return void
*/
function setFailedLoginCallback($loginFailedCallback)
{
$this->loginFailedCallback = $loginFailedCallback;
}
 
/**
* Register a callback function to be called on user logout.
* The function will receive three parameters, the username and a reference to the auth object.
*
* @access public
* @param string callback function name
* @return void
* @see setLoginCallback()
*/
function setLogoutCallback($logoutCallback)
{
$this->logoutCallback = $logoutCallback;
}
 
// }}}
// {{{ setAuthData()
 
/**
* Register additional information that is to be stored
* in the session.
*
* @access public
* @param string Name of the data field
* @param mixed Value of the data field
* @param boolean Should existing data be overwritten? (default
* is true)
* @return void
*/
function setAuthData($name, $value, $overwrite = true)
{
$session = &Auth::_importGlobalVariable('session');
 
if (!empty($session[$this->_sessionName]['data'][$name]) && $overwrite == false) {
return;
}
$session[$this->_sessionName]['data'][$name] = $value;
}
 
// }}}
// {{{ getAuthData()
 
/**
* Get additional information that is stored in the session.
*
* If no value for the first parameter is passed, the method will
* return all data that is currently stored.
*
* @access public
* @param string Name of the data field
* @return mixed Value of the data field.
*/
function getAuthData($name = null)
{
$session = &Auth::_importGlobalVariable('session');
if(!isset($session[$this->_sessionName]['data'])){
return(null);
}
 
if (is_null($name)) {
if(isset($session[$this->_sessionName]['data'])) {
return $session[$this->_sessionName]['data'];
} else {
return null;
}
}
if (isset($session[$this->_sessionName]['data'][$name])) {
return $session[$this->_sessionName]['data'][$name];
} else {
return null;
}
}
 
// }}}
// {{{ setAuth()
 
/**
* Register variable in a session telling that the user
* has logged in successfully
*
* @access public
* @param string Username
* @return void
*/
function setAuth($username)
{
$session = &Auth::_importGlobalVariable('session');
 
if (!isset($session[$this->_sessionName]) && !isset($_SESSION)) {
session_register($this->_sessionName);
}
 
if (!isset($session[$this->_sessionName]) || !is_array($session[$this->_sessionName])) {
$session[$this->_sessionName] = array();
}
 
if(!isset($session[$this->_sessionName]['data'])){
$session[$this->_sessionName]['data'] = array();
}
$session[$this->_sessionName]['registered'] = true;
$session[$this->_sessionName]['username'] = $username;
$session[$this->_sessionName]['timestamp'] = time();
$session[$this->_sessionName]['idle'] = time();
}
 
// }}}
// {{{ checkAuth()
 
/**
* Checks if there is a session with valid auth information.
*
* @access private
* @return boolean Whether or not the user is authenticated.
*/
function checkAuth()
{
$session = &$this->_importGlobalVariable('session');
 
if (isset($session[$this->_sessionName])) {
// Check if authentication session is expired
if ($this->expire > 0 &&
isset($session[$this->_sessionName]['timestamp']) &&
($session[$this->_sessionName]['timestamp'] + $this->expire) < time()) {
 
$this->logout();
$this->expired = true;
$this->status = AUTH_EXPIRED;
 
return false;
}
 
// Check if maximum idle time is reached
if ($this->idle > 0 &&
isset($session[$this->_sessionName]['idle']) &&
($session[$this->_sessionName]['idle'] + $this->idle) < time()) {
 
$this->logout();
$this->idled = true;
$this->status = AUTH_IDLED;
 
return false;
}
 
if (isset($session[$this->_sessionName]['registered']) &&
isset($session[$this->_sessionName]['username']) &&
$session[$this->_sessionName]['registered'] == true &&
$session[$this->_sessionName]['username'] != '') {
 
Auth::updateIdle();
 
return true;
}
}
 
return false;
}
 
// }}}
// {{{ getAuth()
 
/**
* Has the user been authenticated?
*
* @access public
* @return bool True if the user is logged in, otherwise false.
*/
function getAuth()
{
$session = &$this->_importGlobalVariable('session');
 
if (!empty($session) &&
(isset($session[$this->_sessionName]['registered']) &&
$session[$this->_sessionName]['registered'] === true))
{
return true;
} else {
return false;
}
}
 
// }}}
// {{{ drawLogin()
 
/**
* Draw the login form
*
* Normally you will not use this output in your application,
* because you can pass a different function name to the
* constructor. For more information on this, please
* consult the documentation.
*
* @access private
* @param string Username if already entered
* @return void
*/
function drawLogin($username = '')
{
if (is_callable($this->loginFunction)) {
call_user_func($this->loginFunction, $username, $this->status, $this);
} else {
$server = &$this->_importGlobalVariable('server');
 
echo '<center>'."\n";
 
if (!empty($this->status) && $this->status == AUTH_EXPIRED) {
echo '<i>Your session expired. Please login again!</i>'."\n";
} else if (!empty($this->status) && $this->status == AUTH_IDLED) {
echo '<i>You have been idle for too long. Please login again!</i>'."\n";
} else if (!empty ($this->status) && $this->status == AUTH_WRONG_LOGIN) {
echo '<i>Wrong login data!</i>'."\n";
}
 
PEAR::raiseError('You are using the built-in login screen of PEAR::Auth.<br />See the <a href="http://pear.php.net/manual/">manual</a> for details on how to create your own login function.', null);
 
echo '<form method="post" action="' . $server['PHP_SELF'] . '">'."\n";
echo '<table border="0" cellpadding="2" cellspacing="0" summary="login form">'."\n";
echo '<tr>'."\n";
echo ' <td colspan="2" bgcolor="#eeeeee"><b>Login:</b></td>'."\n";
echo '</tr>'."\n";
echo '<tr>'."\n";
echo ' <td>Username:</td>'."\n";
echo ' <td><input type="text" name="username" value="' . $username . '" /></td>'."\n";
echo '</tr>'."\n";
echo '<tr>'."\n";
echo ' <td>Password:</td>'."\n";
echo ' <td><input type="password" name="password" /></td>'."\n";
echo '</tr>'."\n";
echo '<tr>'."\n";
echo ' <td colspan="2" bgcolor="#eeeeee"><input type="submit" /></td>'."\n";
echo '</tr>'."\n";
echo '</table>'."\n";
echo '</form>'."\n";
echo '</center>'."\n\n";
}
}
 
// }}}
// {{{ logout()
 
/**
* Logout function
*
* This function clears any auth tokens in the currently
* active session and executes the logout callback function,
* if any
*
* @access public
* @return void
*/
function logout()
{
$session = &$this->_importGlobalVariable('session');
 
if (is_callable($this->logoutCallback)) {
call_user_func($this->logoutCallback, $session[$this->_sessionName]['username'], $this);
}
 
$this->username = '';
$this->password = '';
 
$session[$this->_sessionName] = array();
if (isset($_SESSION)) {
unset($session[$this->_sessionName]);
} else {
session_unregister($this->_sessionName);
}
}
 
// }}}
// {{{ updateIdle()
 
/**
* Update the idletime
*
* @access private
* @return void
*/
function updateIdle()
{
$session = &$this->_importGlobalVariable('session');
$session[$this->_sessionName]['idle'] = time();
}
 
// }}}
// {{{ getUsername()
 
/**
* Get the username
*
* @access public
* @return string
*/
function getUsername()
{
$session = &$this->_importGlobalVariable('session');
if (!isset($session[$this->_sessionName]['username'])) {
return '';
}
return $session[$this->_sessionName]['username'];
}
 
// }}}
// {{{ getStatus()
 
/**
* Get the current status
*
* @access public
* @return string
*/
function getStatus()
{
return $this->status;
}
 
// }}}
// {{{ sessionValidThru()
 
/**
* Returns the time up to the session is valid
*
* @access public
* @return integer
*/
function sessionValidThru()
{
$session = &$this->_importGlobalVariable('session');
if (!isset($session[$this->_sessionName]['idle'])) {
return 0;
}
return ($session[$this->_sessionName]['idle'] + $this->idle);
}
 
// }}}
// {{{ listUsers()
 
/**
* List all users that are currently available in the storage
* container
*
* @access public
* @return array
*/
function listUsers()
{
return $this->storage->listUsers();
}
 
// }}}
// {{{ addUser()
 
/**
* Add user to the storage container
*
* @access public
* @param string Username
* @param string Password
* @param mixed Additional parameters
* @return mixed True on success, PEAR error object on error
* and AUTH_METHOD_NOT_SUPPORTED otherwise.
*/
function addUser($username, $password, $additional = '')
{
return $this->storage->addUser($username, $password, $additional);
}
 
// }}}
// {{{ removeUser()
 
/**
* Remove user from the storage container
*
* @access public
* @param string Username
* @return mixed True on success, PEAR error object on error
* and AUTH_METHOD_NOT_SUPPORTED otherwise.
*/
function removeUser($username)
{
return $this->storage->removeUser($username);
}
 
// }}}
// {{{ _importGlobalVariable()
 
/**
* Import variables from special namespaces.
*
* @access private
* @param string Type of variable (server, session, post)
* @return array
*/
function &_importGlobalVariable($variable)
{
$var = null;
 
switch (strtolower($variable)) {
 
case 'server' :
if (isset($_SERVER)) {
$var = &$_SERVER;
} else {
$var = &$GLOBALS['HTTP_SERVER_VARS'];
}
break;
 
case 'session' :
if (isset($_SESSION)) {
$var = &$_SESSION;
} else {
$var = &$GLOBALS['HTTP_SESSION_VARS'];
}
break;
 
case 'post' :
if (isset($_POST)) {
$var = &$_POST;
} else {
$var = &$GLOBALS['HTTP_POST_VARS'];
}
break;
 
case 'cookie' :
if (isset($_COOKIE)) {
$var = &$_COOKIE;
} else {
$var = &$GLOBALS['HTTP_COOKIE_VARS'];
}
break;
 
case 'get' :
if (isset($_GET)) {
$var = &$_GET;
} else {
$var = &$GLOBALS['HTTP_GET_VARS'];
}
break;
 
default:
break;
 
}
 
return $var;
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Config.php
New file
0,0 → 1,2108
<?php
/**
* PEAR_Config, customized configuration handling for the PEAR Installer
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Config.php,v 1.137 2006/11/19 21:33:00 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* Required for error handling
*/
require_once 'PEAR.php';
require_once 'PEAR/Registry.php';
require_once 'PEAR/Installer/Role.php';
require_once 'System.php';
require_once 'PEAR/Remote.php';
 
/**
* Last created PEAR_Config instance.
* @var object
*/
$GLOBALS['_PEAR_Config_instance'] = null;
if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) {
$PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear';
} else {
$PEAR_INSTALL_DIR = PEAR_INSTALL_DIR;
}
 
// Below we define constants with default values for all configuration
// parameters except username/password. All of them can have their
// defaults set through environment variables. The reason we use the
// PHP_ prefix is for some security, PHP protects environment
// variables starting with PHP_*.
 
// default channel and preferred mirror is based on whether we are invoked through
// the "pear" or the "pecl" command
 
if (!defined('PEAR_RUNTYPE') || PEAR_RUNTYPE == 'pear') {
define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net');
} else {
define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net');
}
 
if (getenv('PHP_PEAR_SYSCONF_DIR')) {
define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR'));
} elseif (getenv('SystemRoot')) {
define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot'));
} else {
define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR);
}
 
// Default for master_server
if (getenv('PHP_PEAR_MASTER_SERVER')) {
define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER'));
} else {
define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net');
}
 
// Default for http_proxy
if (getenv('PHP_PEAR_HTTP_PROXY')) {
define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY'));
} elseif (getenv('http_proxy')) {
define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy'));
} else {
define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', '');
}
 
// Default for php_dir
if (getenv('PHP_PEAR_INSTALL_DIR')) {
define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR'));
} else {
if (file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) {
define('PEAR_CONFIG_DEFAULT_PHP_DIR',
$PEAR_INSTALL_DIR);
} else {
define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
}
}
 
// Default for ext_dir
if (getenv('PHP_PEAR_EXTENSION_DIR')) {
define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR'));
} else {
if (ini_get('extension_dir')) {
define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir'));
} elseif (defined('PEAR_EXTENSION_DIR') &&
file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) {
define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR);
} elseif (defined('PHP_EXTENSION_DIR')) {
define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR);
} else {
define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.');
}
}
 
// Default for doc_dir
if (getenv('PHP_PEAR_DOC_DIR')) {
define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_DOC_DIR',
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs');
}
 
// Default for bin_dir
if (getenv('PHP_PEAR_BIN_DIR')) {
define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR);
}
 
// Default for data_dir
if (getenv('PHP_PEAR_DATA_DIR')) {
define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_DATA_DIR',
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data');
}
 
// Default for test_dir
if (getenv('PHP_PEAR_TEST_DIR')) {
define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_TEST_DIR',
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests');
}
 
// Default for temp_dir
if (getenv('PHP_PEAR_TEMP_DIR')) {
define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_TEMP_DIR',
System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
DIRECTORY_SEPARATOR . 'temp');
}
 
// Default for cache_dir
if (getenv('PHP_PEAR_CACHE_DIR')) {
define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_CACHE_DIR',
System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
DIRECTORY_SEPARATOR . 'cache');
}
 
// Default for download_dir
if (getenv('PHP_PEAR_DOWNLOAD_DIR')) {
define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR',
System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
DIRECTORY_SEPARATOR . 'download');
}
 
// Default for php_bin
if (getenv('PHP_PEAR_PHP_BIN')) {
define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN'));
} else {
define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR.
DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : ''));
}
 
// Default for verbose
if (getenv('PHP_PEAR_VERBOSE')) {
define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE'));
} else {
define('PEAR_CONFIG_DEFAULT_VERBOSE', 1);
}
 
// Default for preferred_state
if (getenv('PHP_PEAR_PREFERRED_STATE')) {
define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE'));
} else {
define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable');
}
 
// Default for umask
if (getenv('PHP_PEAR_UMASK')) {
define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK'));
} else {
define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask()));
}
 
// Default for cache_ttl
if (getenv('PHP_PEAR_CACHE_TTL')) {
define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL'));
} else {
define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600);
}
 
// Default for sig_type
if (getenv('PHP_PEAR_SIG_TYPE')) {
define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE'));
} else {
define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg');
}
 
// Default for sig_bin
if (getenv('PHP_PEAR_SIG_BIN')) {
define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN'));
} else {
define('PEAR_CONFIG_DEFAULT_SIG_BIN',
System::which(
'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg'));
}
 
// Default for sig_keydir
if (getenv('PHP_PEAR_SIG_KEYDIR')) {
define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR'));
} else {
define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR',
PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys');
}
 
/**
* This is a class for storing configuration data, keeping track of
* which are system-defined, user-defined or defaulted.
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Config extends PEAR
{
// {{{ properties
 
/**
* Array of config files used.
*
* @var array layer => config file
*/
var $files = array(
'system' => '',
'user' => '',
);
 
var $layers = array();
/**
* Configuration data, two-dimensional array where the first
* dimension is the config layer ('user', 'system' and 'default'),
* and the second dimension is keyname => value.
*
* The order in the first dimension is important! Earlier
* layers will shadow later ones when a config value is
* requested (if a 'user' value exists, it will be returned first,
* then 'system' and finally 'default').
*
* @var array layer => array(keyname => value, ...)
*/
var $configuration = array(
'user' => array(),
'system' => array(),
'default' => array(),
);
/**
* Configuration values that can be set for a channel
*
* All other configuration values can only have a global value
* @var array
* @access private
*/
var $_channelConfigInfo = array(
'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir',
'test_dir', 'php_bin', 'username', 'password', 'verbose',
'preferred_state', 'umask', 'preferred_mirror',
);
 
/**
* Channels that can be accessed
* @see setChannels()
* @var array
* @access private
*/
var $_channels = array('pear.php.net', 'pecl.php.net', '__uri');
 
/**
* This variable is used to control the directory values returned
* @see setInstallRoot();
* @var string|false
* @access private
*/
var $_installRoot = false;
 
/**
* If requested, this will always refer to the registry
* contained in php_dir
* @var PEAR_Registry
*/
var $_registry = array();
 
/**
* @var array
* @access private
*/
var $_regInitialized = array();
 
/**
* @var bool
* @access private
*/
var $_noRegistry = false;
 
/**
* amount of errors found while parsing config
* @var integer
* @access private
*/
var $_errorsFound = 0;
var $_lastError = null;
 
/**
* Information about the configuration data. Stores the type,
* default value and a documentation string for each configuration
* value.
*
* @var array layer => array(infotype => value, ...)
*/
var $configuration_info = array(
// Channels/Internet Access
'default_channel' => array(
'type' => 'string',
'default' => PEAR_CONFIG_DEFAULT_CHANNEL,
'doc' => 'the default channel to use for all non explicit commands',
'prompt' => 'Default Channel',
'group' => 'Internet Access',
),
'preferred_mirror' => array(
'type' => 'string',
'default' => PEAR_CONFIG_DEFAULT_CHANNEL,
'doc' => 'the default server or mirror to use for channel actions',
'prompt' => 'Default Channel Mirror',
'group' => 'Internet Access',
),
'remote_config' => array(
'type' => 'password',
'default' => '',
'doc' => 'ftp url of remote configuration file to use for synchronized install',
'prompt' => 'Remote Configuration File',
'group' => 'Internet Access',
),
'auto_discover' => array(
'type' => 'integer',
'default' => 0,
'doc' => 'whether to automatically discover new channels',
'prompt' => 'Auto-discover new Channels',
'group' => 'Internet Access',
),
// Internet Access
'master_server' => array(
'type' => 'string',
'default' => 'pear.php.net',
'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]',
'prompt' => 'PEAR server [DEPRECATED]',
'group' => 'Internet Access',
),
'http_proxy' => array(
'type' => 'string',
'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY,
'doc' => 'HTTP proxy (host:port) to use when downloading packages',
'prompt' => 'HTTP Proxy Server Address',
'group' => 'Internet Access',
),
// File Locations
'php_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_PHP_DIR,
'doc' => 'directory where .php files are installed',
'prompt' => 'PEAR directory',
'group' => 'File Locations',
),
'ext_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_EXT_DIR,
'doc' => 'directory where loadable extensions are installed',
'prompt' => 'PHP extension directory',
'group' => 'File Locations',
),
'doc_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_DOC_DIR,
'doc' => 'directory where documentation is installed',
'prompt' => 'PEAR documentation directory',
'group' => 'File Locations',
),
'bin_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_BIN_DIR,
'doc' => 'directory where executables are installed',
'prompt' => 'PEAR executables directory',
'group' => 'File Locations',
),
'data_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_DATA_DIR,
'doc' => 'directory where data files are installed',
'prompt' => 'PEAR data directory',
'group' => 'File Locations (Advanced)',
),
'test_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_TEST_DIR,
'doc' => 'directory where regression tests are installed',
'prompt' => 'PEAR test directory',
'group' => 'File Locations (Advanced)',
),
'cache_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR,
'doc' => 'directory which is used for XMLRPC cache',
'prompt' => 'PEAR Installer cache directory',
'group' => 'File Locations (Advanced)',
),
'temp_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR,
'doc' => 'directory which is used for all temp files',
'prompt' => 'PEAR Installer temp directory',
'group' => 'File Locations (Advanced)',
),
'download_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR,
'doc' => 'directory which is used for all downloaded files',
'prompt' => 'PEAR Installer download directory',
'group' => 'File Locations (Advanced)',
),
'php_bin' => array(
'type' => 'file',
'default' => PEAR_CONFIG_DEFAULT_PHP_BIN,
'doc' => 'PHP CLI/CGI binary for executing scripts',
'prompt' => 'PHP CLI/CGI binary',
'group' => 'File Locations (Advanced)',
),
'php_ini' => array(
'type' => 'file',
'default' => '',
'doc' => 'location of php.ini in which to enable PECL extensions on install',
'prompt' => 'php.ini location',
'group' => 'File Locations (Advanced)',
),
// Maintainers
'username' => array(
'type' => 'string',
'default' => '',
'doc' => '(maintainers) your PEAR account name',
'prompt' => 'PEAR username (for maintainers)',
'group' => 'Maintainers',
),
'password' => array(
'type' => 'password',
'default' => '',
'doc' => '(maintainers) your PEAR account password',
'prompt' => 'PEAR password (for maintainers)',
'group' => 'Maintainers',
),
// Advanced
'verbose' => array(
'type' => 'integer',
'default' => PEAR_CONFIG_DEFAULT_VERBOSE,
'doc' => 'verbosity level
0: really quiet
1: somewhat quiet
2: verbose
3: debug',
'prompt' => 'Debug Log Level',
'group' => 'Advanced',
),
'preferred_state' => array(
'type' => 'set',
'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE,
'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified',
'valid_set' => array(
'stable', 'beta', 'alpha', 'devel', 'snapshot'),
'prompt' => 'Preferred Package State',
'group' => 'Advanced',
),
'umask' => array(
'type' => 'mask',
'default' => PEAR_CONFIG_DEFAULT_UMASK,
'doc' => 'umask used when creating files (Unix-like systems only)',
'prompt' => 'Unix file mask',
'group' => 'Advanced',
),
'cache_ttl' => array(
'type' => 'integer',
'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL,
'doc' => 'amount of secs where the local cache is used and not updated',
'prompt' => 'Cache TimeToLive',
'group' => 'Advanced',
),
'sig_type' => array(
'type' => 'set',
'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE,
'doc' => 'which package signature mechanism to use',
'valid_set' => array('gpg'),
'prompt' => 'Package Signature Type',
'group' => 'Maintainers',
),
'sig_bin' => array(
'type' => 'string',
'default' => PEAR_CONFIG_DEFAULT_SIG_BIN,
'doc' => 'which package signature mechanism to use',
'prompt' => 'Signature Handling Program',
'group' => 'Maintainers',
),
'sig_keyid' => array(
'type' => 'string',
'default' => '',
'doc' => 'which key to use for signing with',
'prompt' => 'Signature Key Id',
'group' => 'Maintainers',
),
'sig_keydir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR,
'doc' => 'directory where signature keys are located',
'prompt' => 'Signature Key Directory',
'group' => 'Maintainers',
),
// __channels is reserved - used for channel-specific configuration
);
 
// }}}
 
// {{{ PEAR_Config([file], [defaults_file])
 
/**
* Constructor.
*
* @param string file to read user-defined options from
* @param string file to read system-wide defaults from
* @param bool determines whether a registry object "follows"
* the value of php_dir (is automatically created
* and moved when php_dir is changed)
* @param bool if true, fails if configuration files cannot be loaded
*
* @access public
*
* @see PEAR_Config::singleton
*/
function PEAR_Config($user_file = '', $system_file = '', $ftp_file = false,
$strict = true)
{
$this->PEAR();
PEAR_Installer_Role::initializeConfig($this);
$sl = DIRECTORY_SEPARATOR;
if (empty($user_file)) {
if (OS_WINDOWS) {
$user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini';
} else {
$user_file = getenv('HOME') . $sl . '.pearrc';
}
}
if (empty($system_file)) {
if (OS_WINDOWS) {
$system_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini';
} else {
$system_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf';
}
}
 
$this->layers = array_keys($this->configuration);
$this->files['user'] = $user_file;
$this->files['system'] = $system_file;
if ($user_file && file_exists($user_file)) {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$this->readConfigFile($user_file, 'user', $strict);
$this->popErrorHandling();
if ($this->_errorsFound > 0) {
return;
}
}
 
if ($system_file && file_exists($system_file)) {
$this->mergeConfigFile($system_file, false, 'system', $strict);
if ($this->_errorsFound > 0) {
return;
}
 
}
 
if (!$ftp_file) {
$ftp_file = $this->get('remote_config');
}
 
if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) {
$this->readFTPConfigFile($ftp_file);
}
 
foreach ($this->configuration_info as $key => $info) {
$this->configuration['default'][$key] = $info['default'];
}
 
$this->_registry['default'] = &new PEAR_Registry($this->configuration['default']['php_dir']);
$this->_registry['default']->setConfig($this);
$this->_regInitialized['default'] = false;
//$GLOBALS['_PEAR_Config_instance'] = &$this;
}
 
// }}}
// {{{ singleton([file], [defaults_file])
 
/**
* Static singleton method. If you want to keep only one instance
* of this class in use, this method will give you a reference to
* the last created PEAR_Config object if one exists, or create a
* new object.
*
* @param string (optional) file to read user-defined options from
* @param string (optional) file to read system-wide defaults from
*
* @return object an existing or new PEAR_Config instance
*
* @access public
*
* @see PEAR_Config::PEAR_Config
*/
function &singleton($user_file = '', $system_file = '', $strict = true)
{
if (is_object($GLOBALS['_PEAR_Config_instance'])) {
return $GLOBALS['_PEAR_Config_instance'];
}
 
$t_conf = &new PEAR_Config($user_file, $system_file, false, $strict);
if ($t_conf->_errorsFound > 0) {
return $t_conf->lastError;
}
 
$GLOBALS['_PEAR_Config_instance'] = &$t_conf;
return $GLOBALS['_PEAR_Config_instance'];
}
 
// }}}
// {{{ validConfiguration()
 
/**
* Determine whether any configuration files have been detected, and whether a
* registry object can be retrieved from this configuration.
* @return bool
* @since PEAR 1.4.0a1
*/
function validConfiguration()
{
if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) {
return true;
}
return false;
}
 
// }}}
// {{{ readConfigFile([file], [layer])
 
/**
* Reads configuration data from a file. All existing values in
* the config layer are discarded and replaced with data from the
* file.
* @param string file to read from, if NULL or not specified, the
* last-used file for the same layer (second param) is used
* @param string config layer to insert data into ('user' or 'system')
* @return bool TRUE on success or a PEAR error on failure
*/
function readConfigFile($file = null, $layer = 'user', $strict = true)
{
if (empty($this->files[$layer])) {
return $this->raiseError("unknown config layer `$layer'");
}
 
if ($file === null) {
$file = $this->files[$layer];
}
 
$data = $this->_readConfigDataFrom($file);
 
if (PEAR::isError($data)) {
if ($strict) {
$this->_errorsFound++;
$this->lastError = $data;
 
return $data;
} else {
return true;
}
} else {
$this->files[$layer] = $file;
}
 
$this->_decodeInput($data);
$this->configuration[$layer] = $data;
$this->_setupChannels();
if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) {
$this->_registry[$layer] = &new PEAR_Registry($phpdir);
$this->_registry[$layer]->setConfig($this);
$this->_regInitialized[$layer] = false;
} else {
unset($this->_registry[$layer]);
}
return true;
}
 
// }}}
 
/**
* @param string url to the remote config file, like ftp://www.example.com/pear/config.ini
* @return true|PEAR_Error
*/
function readFTPConfigFile($path)
{
do { // poor man's try
if (!class_exists('PEAR_FTP')) {
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
if (PEAR_Common::isIncludeable('PEAR/FTP.php')) {
require_once 'PEAR/FTP.php';
}
}
if (class_exists('PEAR_FTP')) {
$this->_ftp = &new PEAR_FTP;
$this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN);
$e = $this->_ftp->init($path);
if (PEAR::isError($e)) {
$this->_ftp->popErrorHandling();
return $e;
}
$tmp = System::mktemp('-d');
PEAR_Common::addTempFile($tmp);
$e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR .
'pear.ini', false, FTP_BINARY);
if (PEAR::isError($e)) {
$this->_ftp->popErrorHandling();
return $e;
}
PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini');
$this->_ftp->disconnect();
$this->_ftp->popErrorHandling();
$this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini';
$e = $this->readConfigFile(null, 'ftp');
if (PEAR::isError($e)) {
return $e;
}
$fail = array();
foreach ($this->configuration_info as $key => $val) {
if (in_array($this->getGroup($key),
array('File Locations', 'File Locations (Advanced)')) &&
$this->getType($key) == 'directory') {
// any directory configs must be set for this to work
if (!isset($this->configuration['ftp'][$key])) {
$fail[] = $key;
}
}
}
if (count($fail)) {
$fail = '"' . implode('", "', $fail) . '"';
unset($this->files['ftp']);
unset($this->configuration['ftp']);
return PEAR::raiseError('ERROR: Ftp configuration file must set all ' .
'directory configuration variables. These variables were not set: ' .
$fail);
} else {
return true;
}
} else {
return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config');
}
} while (false); // poor man's catch
unset($this->files['ftp']);
return PEAR::raiseError('no remote host specified');
}
 
// {{{ _setupChannels()
/**
* Reads the existing configurations and creates the _channels array from it
*/
function _setupChannels()
{
$set = array_flip(array_values($this->_channels));
foreach ($this->configuration as $layer => $data) {
$i = 1000;
if (isset($data['__channels']) && is_array($data['__channels'])) {
foreach ($data['__channels'] as $channel => $info) {
$set[$channel] = $i++;
}
}
}
$this->_channels = array_values(array_flip($set));
$this->setChannels($this->_channels);
}
 
// }}}
// {{{ deleteChannel(channel)
 
function deleteChannel($channel)
{
foreach ($this->configuration as $layer => $data) {
if (isset($data['__channels'])) {
if (isset($data['__channels'][strtolower($channel)])) {
unset($this->configuration[$layer]['__channels'][strtolower($channel)]);
}
}
}
$this->_channels = array_flip($this->_channels);
unset($this->_channels[strtolower($channel)]);
$this->_channels = array_flip($this->_channels);
}
 
// }}}
// {{{ mergeConfigFile(file, [override], [layer])
 
/**
* Merges data into a config layer from a file. Does the same
* thing as readConfigFile, except it does not replace all
* existing values in the config layer.
* @param string file to read from
* @param bool whether to overwrite existing data (default TRUE)
* @param string config layer to insert data into ('user' or 'system')
* @param string if true, errors are returned if file opening fails
* @return bool TRUE on success or a PEAR error on failure
*/
function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true)
{
if (empty($this->files[$layer])) {
return $this->raiseError("unknown config layer `$layer'");
}
if ($file === null) {
$file = $this->files[$layer];
}
$data = $this->_readConfigDataFrom($file);
if (PEAR::isError($data)) {
if ($strict) {
$this->_errorsFound++;
$this->lastError = $data;
 
return $data;
} else {
return true;
}
}
$this->_decodeInput($data);
if ($override) {
$this->configuration[$layer] =
PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data);
} else {
$this->configuration[$layer] =
PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]);
}
$this->_setupChannels();
if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) {
$this->_registry[$layer] = &new PEAR_Registry($phpdir);
$this->_registry[$layer]->setConfig($this);
$this->_regInitialized[$layer] = false;
} else {
unset($this->_registry[$layer]);
}
return true;
}
 
// }}}
// {{{ arrayMergeRecursive($arr2, $arr1)
/**
* @param array
* @param array
* @return array
* @static
*/
function arrayMergeRecursive($arr2, $arr1)
{
$ret = array();
foreach ($arr2 as $key => $data) {
if (!isset($arr1[$key])) {
$ret[$key] = $data;
unset($arr1[$key]);
continue;
}
if (is_array($data)) {
if (!is_array($arr1[$key])) {
$ret[$key] = $arr1[$key];
unset($arr1[$key]);
continue;
}
$ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]);
unset($arr1[$key]);
}
}
return array_merge($ret, $arr1);
}
 
// }}}
// {{{ writeConfigFile([file], [layer])
 
/**
* Writes data into a config layer from a file.
*
* @param string|null file to read from, or null for default
* @param string config layer to insert data into ('user' or
* 'system')
* @param string|null data to write to config file or null for internal data [DEPRECATED]
* @return bool TRUE on success or a PEAR error on failure
*/
function writeConfigFile($file = null, $layer = 'user', $data = null)
{
$this->_lazyChannelSetup($layer);
if ($layer == 'both' || $layer == 'all') {
foreach ($this->files as $type => $file) {
$err = $this->writeConfigFile($file, $type, $data);
if (PEAR::isError($err)) {
return $err;
}
}
return true;
}
if (empty($this->files[$layer])) {
return $this->raiseError("unknown config file type `$layer'");
}
if ($file === null) {
$file = $this->files[$layer];
}
$data = ($data === null) ? $this->configuration[$layer] : $data;
$this->_encodeOutput($data);
$opt = array('-p', dirname($file));
if (!@System::mkDir($opt)) {
return $this->raiseError("could not create directory: " . dirname($file));
}
if (file_exists($file) && is_file($file) && !is_writeable($file)) {
return $this->raiseError("no write access to $file!");
}
$fp = @fopen($file, "w");
if (!$fp) {
return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)");
}
$contents = "#PEAR_Config 0.9\n" . serialize($data);
if (!@fwrite($fp, $contents)) {
return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)");
}
return true;
}
 
// }}}
// {{{ _readConfigDataFrom(file)
 
/**
* Reads configuration data from a file and returns the parsed data
* in an array.
*
* @param string file to read from
*
* @return array configuration data or a PEAR error on failure
*
* @access private
*/
function _readConfigDataFrom($file)
{
$fp = false;
if (file_exists($file)) {
$fp = @fopen($file, "r");
}
if (!$fp) {
return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed");
}
$size = filesize($file);
$rt = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
fclose($fp);
$contents = file_get_contents($file);
if (empty($contents)) {
return $this->raiseError('Configuration file "' . $file . '" is empty');
}
set_magic_quotes_runtime($rt);
 
$version = false;
if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) {
$version = $matches[1];
$contents = substr($contents, strlen($matches[0]));
} else {
// Museum config file
if (substr($contents,0,2) == 'a:') {
$version = '0.1';
}
}
if ($version && version_compare("$version", '1', '<')) {
 
// no '@', it is possible that unserialize
// raises a notice but it seems to block IO to
// STDOUT if a '@' is used and a notice is raise
$data = unserialize($contents);
 
if (!is_array($data) && !$data) {
if ($contents == serialize(false)) {
$data = array();
} else {
$err = $this->raiseError("PEAR_Config: bad data in $file");
return $err;
}
}
if (!is_array($data)) {
if (strlen(trim($contents)) > 0) {
$error = "PEAR_Config: bad data in $file";
$err = $this->raiseError($error);
return $err;
} else {
$data = array();
}
}
// add parsing of newer formats here...
} else {
$err = $this->raiseError("$file: unknown version `$version'");
return $err;
}
return $data;
}
 
// }}}
// {{{ getConfFile(layer)
/**
* Gets the file used for storing the config for a layer
*
* @param string $layer 'user' or 'system'
*/
 
function getConfFile($layer)
{
return $this->files[$layer];
}
 
// }}}
 
/**
* @param array information on a role as parsed from its xml file
* @return true|PEAR_Error
* @access private
*/
function _addConfigVars($vars)
{
if (count($vars) > 3) {
return $this->raiseError('Roles can only define 3 new config variables or less');
}
foreach ($vars as $name => $var) {
if (!is_array($var)) {
return $this->raiseError('Configuration information must be an array');
}
if (!isset($var['type'])) {
return $this->raiseError('Configuration information must contain a type');
} else {
if (!in_array($var['type'],
array('string', 'mask', 'password', 'directory', 'file', 'set'))) {
return $this->raiseError(
'Configuration type must be one of directory, file, string, ' .
'mask, set, or password');
}
}
if (!isset($var['default'])) {
return $this->raiseError(
'Configuration information must contain a default value ("default" index)');
} else {
if (is_array($var['default'])) {
$real_default = '';
foreach ($var['default'] as $config_var => $val) {
if (strpos($config_var, 'text') === 0) {
$real_default .= $val;
} elseif (strpos($config_var, 'constant') === 0) {
if (defined($val)) {
$real_default .= constant($val);
} else {
return $this->raiseError(
'Unknown constant "' . $val . '" requested in ' .
'default value for configuration variable "' .
$name . '"');
}
} elseif (isset($this->configuration_info[$config_var])) {
$real_default .=
$this->configuration_info[$config_var]['default'];
} else {
return $this->raiseError(
'Unknown request for "' . $config_var . '" value in ' .
'default value for configuration variable "' .
$name . '"');
}
}
$var['default'] = $real_default;
}
if ($var['type'] == 'integer') {
$var['default'] = (integer) $var['default'];
}
}
if (!isset($var['doc'])) {
return $this->raiseError(
'Configuration information must contain a summary ("doc" index)');
}
if (!isset($var['prompt'])) {
return $this->raiseError(
'Configuration information must contain a simple prompt ("prompt" index)');
}
if (!isset($var['group'])) {
return $this->raiseError(
'Configuration information must contain a simple group ("group" index)');
}
if (isset($this->configuration_info[$name])) {
return $this->raiseError('Configuration variable "' . $name .
'" already exists');
}
$this->configuration_info[$name] = $var;
// fix bug #7351: setting custom config variable in a channel fails
$this->_channelConfigInfo[] = $name;
}
return true;
}
 
// {{{ _encodeOutput(&data)
 
/**
* Encodes/scrambles configuration data before writing to files.
* Currently, 'password' values will be base64-encoded as to avoid
* that people spot cleartext passwords by accident.
*
* @param array (reference) array to encode values in
*
* @return bool TRUE on success
*
* @access private
*/
function _encodeOutput(&$data)
{
foreach ($data as $key => $value) {
if ($key == '__channels') {
foreach ($data['__channels'] as $channel => $blah) {
$this->_encodeOutput($data['__channels'][$channel]);
}
}
if (!isset($this->configuration_info[$key])) {
continue;
}
$type = $this->configuration_info[$key]['type'];
switch ($type) {
// we base64-encode passwords so they are at least
// not shown in plain by accident
case 'password': {
$data[$key] = base64_encode($data[$key]);
break;
}
case 'mask': {
$data[$key] = octdec($data[$key]);
break;
}
}
}
return true;
}
 
// }}}
// {{{ _decodeInput(&data)
 
/**
* Decodes/unscrambles configuration data after reading from files.
*
* @param array (reference) array to encode values in
*
* @return bool TRUE on success
*
* @access private
*
* @see PEAR_Config::_encodeOutput
*/
function _decodeInput(&$data)
{
if (!is_array($data)) {
return true;
}
foreach ($data as $key => $value) {
if ($key == '__channels') {
foreach ($data['__channels'] as $channel => $blah) {
$this->_decodeInput($data['__channels'][$channel]);
}
}
if (!isset($this->configuration_info[$key])) {
continue;
}
$type = $this->configuration_info[$key]['type'];
switch ($type) {
case 'password': {
$data[$key] = base64_decode($data[$key]);
break;
}
case 'mask': {
$data[$key] = decoct($data[$key]);
break;
}
}
}
return true;
}
 
// }}}
// {{{ getDefaultChannel([layer])
/**
* Retrieve the default channel.
*
* On startup, channels are not initialized, so if the default channel is not
* pear.php.net, then initialize the config.
* @param string registry layer
* @return string|false
*/
function getDefaultChannel($layer = null)
{
$ret = false;
if ($layer === null) {
foreach ($this->layers as $layer) {
if (isset($this->configuration[$layer]['default_channel'])) {
$ret = $this->configuration[$layer]['default_channel'];
break;
}
}
} elseif (isset($this->configuration[$layer]['default_channel'])) {
$ret = $this->configuration[$layer]['default_channel'];
}
if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') {
$ret = 'pecl.php.net';
}
if ($ret) {
if ($ret != 'pear.php.net') {
$this->_lazyChannelSetup();
}
return $ret;
}
return PEAR_CONFIG_DEFAULT_CHANNEL;
}
 
// {{{ get(key, [layer])
/**
* Returns a configuration value, prioritizing layers as per the
* layers property.
*
* @param string config key
*
* @return mixed the config value, or NULL if not found
*
* @access public
*/
function get($key, $layer = null, $channel = false)
{
if (!isset($this->configuration_info[$key])) {
return null;
}
if ($key == '__channels') {
return null;
}
if ($key == 'default_channel') {
return $this->getDefaultChannel($layer);
}
if (!$channel) {
$channel = $this->getDefaultChannel();
} elseif ($channel != 'pear.php.net') {
$this->_lazyChannelSetup();
}
$channel = strtolower($channel);
$test = (in_array($key, $this->_channelConfigInfo)) ?
$this->_getChannelValue($key, $layer, $channel) :
null;
if ($test !== null) {
if ($this->_installRoot) {
if (in_array($this->getGroup($key),
array('File Locations', 'File Locations (Advanced)')) &&
$this->getType($key) == 'directory') {
return $this->_prependPath($test, $this->_installRoot);
}
}
return $test;
}
if ($layer === null) {
foreach ($this->layers as $layer) {
if (isset($this->configuration[$layer][$key])) {
$test = $this->configuration[$layer][$key];
if ($this->_installRoot) {
if (in_array($this->getGroup($key),
array('File Locations', 'File Locations (Advanced)')) &&
$this->getType($key) == 'directory') {
return $this->_prependPath($test, $this->_installRoot);
}
}
if ($key == 'preferred_mirror') {
$reg = &$this->getRegistry();
if (is_object($reg)) {
$chan = &$reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $channel;
}
if (!$chan->getMirror($test) && $chan->getName() != $test) {
return $channel; // mirror does not exist
}
}
}
return $test;
}
}
} elseif (isset($this->configuration[$layer][$key])) {
$test = $this->configuration[$layer][$key];
if ($this->_installRoot) {
if (in_array($this->getGroup($key),
array('File Locations', 'File Locations (Advanced)')) &&
$this->getType($key) == 'directory') {
return $this->_prependPath($test, $this->_installRoot);
}
}
if ($key == 'preferred_mirror') {
$reg = &$this->getRegistry();
if (is_object($reg)) {
$chan = &$reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $channel;
}
if (!$chan->getMirror($test) && $chan->getName() != $test) {
return $channel; // mirror does not exist
}
}
}
return $test;
}
return null;
}
 
// }}}
// {{{ _getChannelValue(key, value, [layer])
/**
* Returns a channel-specific configuration value, prioritizing layers as per the
* layers property.
*
* @param string config key
*
* @return mixed the config value, or NULL if not found
*
* @access private
*/
function _getChannelValue($key, $layer, $channel)
{
if ($key == '__channels' || $channel == 'pear.php.net') {
return null;
}
$ret = null;
if ($layer === null) {
foreach ($this->layers as $ilayer) {
if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) {
$ret = $this->configuration[$ilayer]['__channels'][$channel][$key];
break;
}
}
} elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
$ret = $this->configuration[$layer]['__channels'][$channel][$key];
}
if ($key == 'preferred_mirror') {
if ($ret !== null) {
$reg = &$this->getRegistry($layer);
if (is_object($reg)) {
$chan = &$reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $channel;
}
if (!$chan->getMirror($ret) && $chan->getName() != $ret) {
return $channel; // mirror does not exist
}
}
return $ret;
}
if ($channel != $this->getDefaultChannel($layer)) {
return $channel; // we must use the channel name as the preferred mirror
// if the user has not chosen an alternate
} else {
return $this->getDefaultChannel($layer);
}
}
return $ret;
}
 
 
// }}}
// {{{ set(key, value, [layer])
 
/**
* Set a config value in a specific layer (defaults to 'user').
* Enforces the types defined in the configuration_info array. An
* integer config variable will be cast to int, and a set config
* variable will be validated against its legal values.
*
* @param string config key
* @param string config value
* @param string (optional) config layer
* @param string channel to set this value for, or null for global value
* @return bool TRUE on success, FALSE on failure
*/
function set($key, $value, $layer = 'user', $channel = false)
{
if ($key == '__channels') {
return false;
}
if (!isset($this->configuration[$layer])) {
return false;
}
if ($key == 'default_channel') {
// can only set this value globally
$channel = 'pear.php.net';
if ($value != 'pear.php.net') {
$this->_lazyChannelSetup($layer);
}
}
if ($key == 'preferred_mirror') {
if ($channel == '__uri') {
return false; // can't set the __uri pseudo-channel's mirror
}
$reg = &$this->getRegistry($layer);
if (is_object($reg)) {
$chan = &$reg->getChannel($channel ? $channel : 'pear.php.net');
if (PEAR::isError($chan)) {
return false;
}
if (!$chan->getMirror($value) && $chan->getName() != $value) {
return false; // mirror does not exist
}
}
}
if (empty($this->configuration_info[$key])) {
return false;
}
extract($this->configuration_info[$key]);
switch ($type) {
case 'integer':
$value = (int)$value;
break;
case 'set': {
// If a valid_set is specified, require the value to
// be in the set. If there is no valid_set, accept
// any value.
if ($valid_set) {
reset($valid_set);
if ((key($valid_set) === 0 && !in_array($value, $valid_set)) ||
(key($valid_set) !== 0 && empty($valid_set[$value])))
{
return false;
}
}
break;
}
}
if (!$channel) {
$channel = $this->get('default_channel', null, 'pear.php.net');
}
if (!in_array($channel, $this->_channels)) {
$this->_lazyChannelSetup($layer);
$reg = &$this->getRegistry($layer);
if ($reg) {
$channel = $reg->channelName($channel);
}
if (!in_array($channel, $this->_channels)) {
return false;
}
}
if ($channel != 'pear.php.net') {
if (in_array($key, $this->_channelConfigInfo)) {
$this->configuration[$layer]['__channels'][$channel][$key] = $value;
return true;
} else {
return false;
}
} else {
if ($key == 'default_channel') {
if (!isset($reg)) {
$reg = &$this->getRegistry($layer);
if (!$reg) {
$reg = &$this->getRegistry();
}
}
if ($reg) {
$value = $reg->channelName($value);
}
if (!$value) {
return false;
}
}
}
$this->configuration[$layer][$key] = $value;
if ($key == 'php_dir' && !$this->_noRegistry) {
if (!isset($this->_registry[$layer]) ||
$value != $this->_registry[$layer]->install_dir) {
$this->_registry[$layer] = &new PEAR_Registry($value);
$this->_regInitialized[$layer] = false;
$this->_registry[$layer]->setConfig($this);
}
}
return true;
}
 
// }}}
function _lazyChannelSetup($uselayer = false)
{
if ($this->_noRegistry) {
return;
}
$merge = false;
foreach ($this->_registry as $layer => $p) {
if ($uselayer && $uselayer != $layer) {
continue;
}
if (!$this->_regInitialized[$layer]) {
if ($layer == 'default' && isset($this->_registry['user']) ||
isset($this->_registry['system'])) {
// only use the default registry if there are no alternatives
continue;
}
if (!is_object($this->_registry[$layer])) {
if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) {
$this->_registry[$layer] = &new PEAR_Registry($phpdir);
$this->_registry[$layer]->setConfig($this);
$this->_regInitialized[$layer] = false;
} else {
unset($this->_registry[$layer]);
return;
}
}
$this->setChannels($this->_registry[$layer]->listChannels(), $merge);
$this->_regInitialized[$layer] = true;
$merge = true;
}
}
}
// {{{ setChannels()
/**
* Set the list of channels.
*
* This should be set via a call to {@link PEAR_Registry::listChannels()}
* @param array
* @param bool
* @return bool success of operation
*/
function setChannels($channels, $merge = false)
{
if (!is_array($channels)) {
return false;
}
if ($merge) {
$this->_channels = array_merge($this->_channels, $channels);
} else {
$this->_channels = $channels;
}
foreach ($channels as $channel) {
$channel = strtolower($channel);
if ($channel == 'pear.php.net') {
continue;
}
foreach ($this->layers as $layer) {
if (!isset($this->configuration[$layer]['__channels'])) {
$this->configuration[$layer]['__channels'] = array();
}
if (!isset($this->configuration[$layer]['__channels'][$channel])
|| !is_array($this->configuration[$layer]['__channels'][$channel])) {
$this->configuration[$layer]['__channels'][$channel] = array();
}
}
}
return true;
}
 
// }}}
// {{{ getType(key)
 
/**
* Get the type of a config value.
*
* @param string config key
*
* @return string type, one of "string", "integer", "file",
* "directory", "set" or "password".
*
* @access public
*
*/
function getType($key)
{
if (isset($this->configuration_info[$key])) {
return $this->configuration_info[$key]['type'];
}
return false;
}
 
// }}}
// {{{ getDocs(key)
 
/**
* Get the documentation for a config value.
*
* @param string config key
*
* @return string documentation string
*
* @access public
*
*/
function getDocs($key)
{
if (isset($this->configuration_info[$key])) {
return $this->configuration_info[$key]['doc'];
}
return false;
}
// }}}
// {{{ getPrompt(key)
 
/**
* Get the short documentation for a config value.
*
* @param string config key
*
* @return string short documentation string
*
* @access public
*
*/
function getPrompt($key)
{
if (isset($this->configuration_info[$key])) {
return $this->configuration_info[$key]['prompt'];
}
return false;
}
// }}}
// {{{ getGroup(key)
 
/**
* Get the parameter group for a config key.
*
* @param string config key
*
* @return string parameter group
*
* @access public
*
*/
function getGroup($key)
{
if (isset($this->configuration_info[$key])) {
return $this->configuration_info[$key]['group'];
}
return false;
}
 
// }}}
// {{{ getGroups()
 
/**
* Get the list of parameter groups.
*
* @return array list of parameter groups
*
* @access public
*
*/
function getGroups()
{
$tmp = array();
foreach ($this->configuration_info as $key => $info) {
$tmp[$info['group']] = 1;
}
return array_keys($tmp);
}
 
// }}}
// {{{ getGroupKeys()
 
/**
* Get the list of the parameters in a group.
*
* @param string $group parameter group
*
* @return array list of parameters in $group
*
* @access public
*
*/
function getGroupKeys($group)
{
$keys = array();
foreach ($this->configuration_info as $key => $info) {
if ($info['group'] == $group) {
$keys[] = $key;
}
}
return $keys;
}
 
// }}}
// {{{ getSetValues(key)
 
/**
* Get the list of allowed set values for a config value. Returns
* NULL for config values that are not sets.
*
* @param string config key
*
* @return array enumerated array of set values, or NULL if the
* config key is unknown or not a set
*
* @access public
*
*/
function getSetValues($key)
{
if (isset($this->configuration_info[$key]) &&
isset($this->configuration_info[$key]['type']) &&
$this->configuration_info[$key]['type'] == 'set')
{
$valid_set = $this->configuration_info[$key]['valid_set'];
reset($valid_set);
if (key($valid_set) === 0) {
return $valid_set;
}
return array_keys($valid_set);
}
return null;
}
 
// }}}
// {{{ getKeys()
 
/**
* Get all the current config keys.
*
* @return array simple array of config keys
*
* @access public
*/
function getKeys()
{
$keys = array();
foreach ($this->layers as $layer) {
$test = $this->configuration[$layer];
if (isset($test['__channels'])) {
foreach ($test['__channels'] as $channel => $configs) {
$keys = array_merge($keys, $configs);
}
}
unset($test['__channels']);
$keys = array_merge($keys, $test);
}
return array_keys($keys);
}
 
// }}}
// {{{ remove(key, [layer])
 
/**
* Remove the a config key from a specific config layer.
*
* @param string config key
*
* @param string (optional) config layer
*
* @return bool TRUE on success, FALSE on failure
*
* @access public
*/
function remove($key, $layer = 'user')
{
$channel = $this->getDefaultChannel();
if ($channel !== 'pear.php.net') {
if (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
unset($this->configuration[$layer]['__channels'][$channel][$key]);
return true;
}
}
if (isset($this->configuration[$layer][$key])) {
unset($this->configuration[$layer][$key]);
return true;
}
return false;
}
 
// }}}
// {{{ removeLayer(layer)
 
/**
* Temporarily remove an entire config layer. USE WITH CARE!
*
* @param string config key
*
* @param string (optional) config layer
*
* @return bool TRUE on success, FALSE on failure
*
* @access public
*/
function removeLayer($layer)
{
if (isset($this->configuration[$layer])) {
$this->configuration[$layer] = array();
return true;
}
return false;
}
 
// }}}
// {{{ store([layer])
 
/**
* Stores configuration data in a layer.
*
* @param string config layer to store
*
* @return bool TRUE on success, or PEAR error on failure
*
* @access public
*/
function store($layer = 'user', $data = null)
{
return $this->writeConfigFile(null, $layer, $data);
}
 
// }}}
// {{{ toDefault(key)
 
/**
* Unset the user-defined value of a config key, reverting the
* value to the system-defined one.
*
* @param string config key
*
* @return bool TRUE on success, FALSE on failure
*
* @access public
*/
function toDefault($key)
{
trigger_error("PEAR_Config::toDefault() deprecated, use PEAR_Config::remove() instead", E_USER_NOTICE);
return $this->remove($key, 'user');
}
 
// }}}
// {{{ definedBy(key)
 
/**
* Tells what config layer that gets to define a key.
*
* @param string config key
* @param boolean return the defining channel
*
* @return string|array the config layer, or an empty string if not found.
*
* if $returnchannel, the return is an array array('layer' => layername,
* 'channel' => channelname), or an empty string if not found
*
* @access public
*/
function definedBy($key, $returnchannel = false)
{
foreach ($this->layers as $layer) {
$channel = $this->getDefaultChannel();
if ($channel !== 'pear.php.net') {
if (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
if ($returnchannel) {
return array('layer' => $layer, 'channel' => $channel);
}
return $layer;
}
}
if (isset($this->configuration[$layer][$key])) {
if ($returnchannel) {
return array('layer' => $layer, 'channel' => 'pear.php.net');
}
return $layer;
}
}
return '';
}
 
// }}}
// {{{ isDefaulted(key)
 
/**
* Tells whether a config value has a system-defined value.
*
* @param string config key
*
* @return bool
*
* @access public
*
* @deprecated
*/
function isDefaulted($key)
{
trigger_error("PEAR_Config::isDefaulted() deprecated, use PEAR_Config::definedBy() instead", E_USER_NOTICE);
return $this->definedBy($key) == 'system';
}
 
// }}}
// {{{ isDefined(key)
 
/**
* Tells whether a given key exists as a config value.
*
* @param string config key
*
* @return bool whether <config key> exists in this object
*
* @access public
*/
function isDefined($key)
{
foreach ($this->layers as $layer) {
if (isset($this->configuration[$layer][$key])) {
return true;
}
}
return false;
}
 
// }}}
// {{{ isDefinedLayer(key)
 
/**
* Tells whether a given config layer exists.
*
* @param string config layer
*
* @return bool whether <config layer> exists in this object
*
* @access public
*/
function isDefinedLayer($layer)
{
return isset($this->configuration[$layer]);
}
 
// }}}
// {{{ getLayers()
 
/**
* Returns the layers defined (except the 'default' one)
*
* @return array of the defined layers
*/
function getLayers()
{
$cf = $this->configuration;
unset($cf['default']);
return array_keys($cf);
}
 
// }}}
// {{{ apiVersion()
function apiVersion()
{
return '1.1';
}
// }}}
 
/**
* @return PEAR_Registry
*/
function &getRegistry($use = null)
{
if ($use === null) {
$layer = 'user';
} else {
$layer = $use;
}
if (isset($this->_registry[$layer])) {
return $this->_registry[$layer];
} elseif ($use === null && isset($this->_registry['system'])) {
return $this->_registry['system'];
} elseif ($use === null && isset($this->_registry['default'])) {
return $this->_registry['default'];
} elseif ($use) {
$a = false;
return $a;
} else {
// only go here if null was passed in
echo "CRITICAL ERROR: Registry could not be initialized from any value";
exit(1);
}
}
/**
* This is to allow customization like the use of installroot
* @param PEAR_Registry
* @return bool
*/
function setRegistry(&$reg, $layer = 'user')
{
if ($this->_noRegistry) {
return false;
}
if (!in_array($layer, array('user', 'system'))) {
return false;
}
$this->_registry[$layer] = &$reg;
if (is_object($reg)) {
$this->_registry[$layer]->setConfig($this);
}
return true;
}
 
function noRegistry()
{
$this->_noRegistry = true;
}
 
/**
* @return PEAR_Remote
*/
function &getRemote()
{
$remote = &new PEAR_Remote($this);
return $remote;
}
 
/**
* @return PEAR_REST
*/
function &getREST($version, $options = array())
{
$version = str_replace('.', '', $version);
if (!class_exists($class = 'PEAR_REST_' . $version)) {
require_once 'PEAR/REST/' . $version . '.php';
}
$remote = &new $class($this, $options);
return $remote;
}
 
/**
* The ftp server is set in {@link readFTPConfigFile()}. It exists only if a
* remote configuration file has been specified
* @return PEAR_FTP|false
*/
function &getFTP()
{
if (isset($this->_ftp)) {
return $this->_ftp;
} else {
$a = false;
return $a;
}
}
 
// {{{ _prependPath($path, $prepend)
 
function _prependPath($path, $prepend)
{
if (strlen($prepend) > 0) {
if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) {
if (preg_match('/^[a-z]:/i', $prepend)) {
$prepend = substr($prepend, 2);
} elseif ($prepend{0} != '\\') {
$prepend = "\\$prepend";
}
$path = substr($path, 0, 2) . $prepend . substr($path, 2);
} else {
$path = $prepend . $path;
}
}
return $path;
}
// }}}
 
/**
* @param string|false installation directory to prepend to all _dir variables, or false to
* disable
*/
function setInstallRoot($root)
{
if (substr($root, -1) == DIRECTORY_SEPARATOR) {
$root = substr($root, 0, -1);
}
$old = $this->_installRoot;
$this->_installRoot = $root;
if (($old != $root) && !$this->_noRegistry) {
foreach (array_keys($this->_registry) as $layer) {
if ($layer == 'ftp' || !isset($this->_registry[$layer])) {
continue;
}
$this->_registry[$layer] =
&new PEAR_Registry($this->get('php_dir', $layer, 'pear.php.net'));
$this->_registry[$layer]->setConfig($this);
$this->_regInitialized[$layer] = false;
}
}
}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Registry.php
New file
0,0 → 1,2214
<?php
/**
* PEAR_Registry
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Registry.php,v 1.159 2006/12/20 19:34:03 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* for PEAR_Error
*/
require_once 'PEAR.php';
require_once 'PEAR/DependencyDB.php';
 
define('PEAR_REGISTRY_ERROR_LOCK', -2);
define('PEAR_REGISTRY_ERROR_FORMAT', -3);
define('PEAR_REGISTRY_ERROR_FILE', -4);
define('PEAR_REGISTRY_ERROR_CONFLICT', -5);
define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6);
 
/**
* Administration class used to maintain the installed package database.
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Registry extends PEAR
{
// {{{ properties
 
/**
* File containing all channel information.
* @var string
*/
var $channels = '';
 
/** Directory where registry files are stored.
* @var string
*/
var $statedir = '';
 
/** File where the file map is stored
* @var string
*/
var $filemap = '';
 
/** Directory where registry files for channels are stored.
* @var string
*/
var $channelsdir = '';
 
/** Name of file used for locking the registry
* @var string
*/
var $lockfile = '';
 
/** File descriptor used during locking
* @var resource
*/
var $lock_fp = null;
 
/** Mode used during locking
* @var int
*/
var $lock_mode = 0; // XXX UNUSED
 
/** Cache of package information. Structure:
* array(
* 'package' => array('id' => ... ),
* ... )
* @var array
*/
var $pkginfo_cache = array();
 
/** Cache of file map. Structure:
* array( '/path/to/file' => 'package', ... )
* @var array
*/
var $filemap_cache = array();
 
/**
* @var false|PEAR_ChannelFile
*/
var $_pearChannel;
 
/**
* @var false|PEAR_ChannelFile
*/
var $_peclChannel;
 
/**
* @var PEAR_DependencyDB
*/
var $_dependencyDB;
 
/**
* @var PEAR_Config
*/
var $_config;
// }}}
 
// {{{ constructor
 
/**
* PEAR_Registry constructor.
*
* @param string (optional) PEAR install directory (for .php files)
* @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if
* default values are not desired. Only used the very first time a PEAR
* repository is initialized
* @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if
* default values are not desired. Only used the very first time a PEAR
* repository is initialized
*
* @access public
*/
function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false,
$pecl_channel = false)
{
parent::PEAR();
$ds = DIRECTORY_SEPARATOR;
$this->install_dir = $pear_install_dir;
$this->channelsdir = $pear_install_dir.$ds.'.channels';
$this->statedir = $pear_install_dir.$ds.'.registry';
$this->filemap = $pear_install_dir.$ds.'.filemap';
$this->lockfile = $pear_install_dir.$ds.'.lock';
$this->_pearChannel = $pear_channel;
$this->_peclChannel = $pecl_channel;
$this->_config = false;
}
 
function hasWriteAccess()
{
if (!file_exists($this->install_dir)) {
$dir = $this->install_dir;
while ($dir && $dir != '.') {
$dir = dirname($dir); // cd ..
if ($dir != '.' && file_exists($dir)) {
if (is_writeable($dir)) {
return true;
} else {
return false;
}
}
}
return false;
}
return is_writeable($this->install_dir);
}
 
function setConfig(&$config)
{
$this->_config = &$config;
}
 
function _initializeChannelDirs()
{
static $running = false;
if (!$running) {
$running = true;
$ds = DIRECTORY_SEPARATOR;
if (!is_dir($this->channelsdir) ||
!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') ||
!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') ||
!file_exists($this->channelsdir . $ds . '__uri.reg')) {
if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
$pear_channel = $this->_pearChannel;
if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) {
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$pear_channel = new PEAR_ChannelFile;
$pear_channel->setName('pear.php.net');
$pear_channel->setAlias('pear');
$pear_channel->setServer('pear.php.net');
$pear_channel->setSummary('PHP Extension and Application Repository');
$pear_channel->setDefaultPEARProtocols();
$pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/');
$pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/');
} else {
$pear_channel->setName('pear.php.net');
$pear_channel->setAlias('pear');
}
$pear_channel->validate();
$this->_addChannel($pear_channel);
}
if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) {
$pecl_channel = $this->_peclChannel;
if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) {
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$pecl_channel = new PEAR_ChannelFile;
$pecl_channel->setName('pecl.php.net');
$pecl_channel->setAlias('pecl');
$pecl_channel->setServer('pecl.php.net');
$pecl_channel->setSummary('PHP Extension Community Library');
$pecl_channel->setDefaultPEARProtocols();
$pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/');
$pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/');
$pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0');
} else {
$pecl_channel->setName('pecl.php.net');
$pecl_channel->setAlias('pecl');
}
$pecl_channel->validate();
$this->_addChannel($pecl_channel);
}
if (!file_exists($this->channelsdir . $ds . '__uri.reg')) {
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$private = new PEAR_ChannelFile;
$private->setName('__uri');
$private->addFunction('xmlrpc', '1.0', '****');
$private->setSummary('Pseudo-channel for static packages');
$this->_addChannel($private);
}
$this->_rebuildFileMap();
}
$running = false;
}
}
 
function _initializeDirs()
{
$ds = DIRECTORY_SEPARATOR;
// XXX Compatibility code should be removed in the future
// rename all registry files if any to lowercase
if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) &&
$handle = opendir($this->statedir)) {
$dest = $this->statedir . $ds;
while (false !== ($file = readdir($handle))) {
if (preg_match('/^.*[A-Z].*\.reg$/', $file)) {
rename($dest . $file, $dest . strtolower($file));
}
}
closedir($handle);
}
$this->_initializeChannelDirs();
if (!file_exists($this->filemap)) {
$this->_rebuildFileMap();
}
$this->_initializeDepDB();
}
 
function _initializeDepDB()
{
if (!isset($this->_dependencyDB)) {
static $initializing = false;
if (!$initializing) {
$initializing = true;
if (!$this->_config) { // never used?
if (OS_WINDOWS) {
$file = 'pear.ini';
} else {
$file = '.pearrc';
}
$this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR .
$file);
$this->_config->setRegistry($this);
$this->_config->set('php_dir', $this->install_dir);
}
$this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config);
if (PEAR::isError($this->_dependencyDB)) {
// attempt to recover by removing the dep db
if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') .
DIRECTORY_SEPARATOR . '.depdb')) {
@unlink($this->_config->get('php_dir', null, 'pear.php.net') .
DIRECTORY_SEPARATOR . '.depdb');
}
$this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config);
if (PEAR::isError($this->_dependencyDB)) {
echo $this->_dependencyDB->getMessage();
echo 'Unrecoverable error';
exit(1);
}
}
$initializing = false;
}
}
}
// }}}
// {{{ destructor
 
/**
* PEAR_Registry destructor. Makes sure no locks are forgotten.
*
* @access private
*/
function _PEAR_Registry()
{
parent::_PEAR();
if (is_resource($this->lock_fp)) {
$this->_unlock();
}
}
 
// }}}
 
// {{{ _assertStateDir()
 
/**
* Make sure the directory where we keep registry files exists.
*
* @return bool TRUE if directory exists, FALSE if it could not be
* created
*
* @access private
*/
function _assertStateDir($channel = false)
{
if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
return $this->_assertChannelStateDir($channel);
}
static $init = false;
if (!file_exists($this->statedir)) {
if (!$this->hasWriteAccess()) {
return false;
}
require_once 'System.php';
if (!System::mkdir(array('-p', $this->statedir))) {
return $this->raiseError("could not create directory '{$this->statedir}'");
}
$init = true;
} elseif (!is_dir($this->statedir)) {
return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' .
'it already exists and is not a directory');
}
$ds = DIRECTORY_SEPARATOR;
if (!file_exists($this->channelsdir)) {
if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') ||
!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') ||
!file_exists($this->channelsdir . $ds . '__uri.reg')) {
$init = true;
}
} elseif (!is_dir($this->channelsdir)) {
return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' .
'it already exists and is not a directory');
}
if ($init) {
static $running = false;
if (!$running) {
$running = true;
$this->_initializeDirs();
$running = false;
$init = false;
}
} else {
$this->_initializeDepDB();
}
return true;
}
 
// }}}
// {{{ _assertChannelStateDir()
 
/**
* Make sure the directory where we keep registry files exists for a non-standard channel.
*
* @param string channel name
* @return bool TRUE if directory exists, FALSE if it could not be
* created
*
* @access private
*/
function _assertChannelStateDir($channel)
{
$ds = DIRECTORY_SEPARATOR;
if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
$this->_initializeChannelDirs();
}
return $this->_assertStateDir($channel);
}
$channelDir = $this->_channelDirectoryName($channel);
if (!is_dir($this->channelsdir) ||
!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
$this->_initializeChannelDirs();
}
if (!file_exists($channelDir)) {
if (!$this->hasWriteAccess()) {
return false;
}
require_once 'System.php';
if (!System::mkdir(array('-p', $channelDir))) {
return $this->raiseError("could not create directory '" . $channelDir .
"'");
}
} elseif (!is_dir($channelDir)) {
return $this->raiseError("could not create directory '" . $channelDir .
"', already exists and is not a directory");
}
return true;
}
 
// }}}
// {{{ _assertChannelDir()
 
/**
* Make sure the directory where we keep registry files for channels exists
*
* @return bool TRUE if directory exists, FALSE if it could not be
* created
*
* @access private
*/
function _assertChannelDir()
{
if (!file_exists($this->channelsdir)) {
if (!$this->hasWriteAccess()) {
return false;
}
require_once 'System.php';
if (!System::mkdir(array('-p', $this->channelsdir))) {
return $this->raiseError("could not create directory '{$this->channelsdir}'");
}
} elseif (!is_dir($this->channelsdir)) {
return $this->raiseError("could not create directory '{$this->channelsdir}" .
"', it already exists and is not a directory");
}
if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) {
if (!$this->hasWriteAccess()) {
return false;
}
require_once 'System.php';
if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) {
return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'");
}
} elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) {
return $this->raiseError("could not create directory '{$this->channelsdir}" .
"/.alias', it already exists and is not a directory");
}
return true;
}
 
// }}}
// {{{ _packageFileName()
 
/**
* Get the name of the file where data for a given package is stored.
*
* @param string channel name, or false if this is a PEAR package
* @param string package name
*
* @return string registry file name
*
* @access public
*/
function _packageFileName($package, $channel = false)
{
if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR .
strtolower($package) . '.reg';
}
return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg';
}
 
// }}}
// {{{ _channelFileName()
 
/**
* Get the name of the file where data for a given channel is stored.
* @param string channel name
* @return string registry file name
*/
function _channelFileName($channel, $noaliases = false)
{
if (!$noaliases) {
if (file_exists($this->_getChannelAliasFileName($channel))) {
$channel = implode('', file($this->_getChannelAliasFileName($channel)));
}
}
return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_',
strtolower($channel)) . '.reg';
}
 
// }}}
// {{{ getChannelAliasFileName()
 
/**
* @param string
* @return string
*/
function _getChannelAliasFileName($alias)
{
return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' .
DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt';
}
 
// }}}
// {{{ _getChannelFromAlias()
 
/**
* Get the name of a channel from its alias
*/
function _getChannelFromAlias($channel)
{
if (!$this->_channelExists($channel)) {
if ($channel == 'pear.php.net') {
return 'pear.php.net';
}
if ($channel == 'pecl.php.net') {
return 'pecl.php.net';
}
if ($channel == '__uri') {
return '__uri';
}
return false;
}
$channel = strtolower($channel);
if (file_exists($this->_getChannelAliasFileName($channel))) {
// translate an alias to an actual channel
return implode('', file($this->_getChannelAliasFileName($channel)));
} else {
return $channel;
}
}
// }}}
// {{{ _getChannelFromAlias()
 
/**
* Get the alias of a channel from its alias or its name
*/
function _getAlias($channel)
{
if (!$this->_channelExists($channel)) {
if ($channel == 'pear.php.net') {
return 'pear';
}
if ($channel == 'pecl.php.net') {
return 'pecl';
}
return false;
}
$channel = $this->_getChannel($channel);
if (PEAR::isError($channel)) {
return $channel;
}
return $channel->getAlias();
}
// }}}
// {{{ _channelDirectoryName()
 
/**
* Get the name of the file where data for a given package is stored.
*
* @param string channel name, or false if this is a PEAR package
* @param string package name
*
* @return string registry file name
*
* @access public
*/
function _channelDirectoryName($channel)
{
if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
return $this->statedir;
} else {
$ch = $this->_getChannelFromAlias($channel);
if (!$ch) {
$ch = $channel;
}
return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' .
str_replace('/', '_', $ch));
}
}
 
// }}}
// {{{ _openPackageFile()
 
function _openPackageFile($package, $mode, $channel = false)
{
if (!$this->_assertStateDir($channel)) {
return null;
}
if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) {
return null;
}
$file = $this->_packageFileName($package, $channel);
if (!file_exists($file) && $mode == 'r' || $mode == 'rb') {
return null;
}
$fp = @fopen($file, $mode);
if (!$fp) {
return null;
}
return $fp;
}
 
// }}}
// {{{ _closePackageFile()
 
function _closePackageFile($fp)
{
fclose($fp);
}
 
// }}}
// {{{ _openChannelFile()
 
function _openChannelFile($channel, $mode)
{
if (!$this->_assertChannelDir()) {
return null;
}
if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) {
return null;
}
$file = $this->_channelFileName($channel);
if (!file_exists($file) && $mode == 'r' || $mode == 'rb') {
return null;
}
$fp = @fopen($file, $mode);
if (!$fp) {
return null;
}
return $fp;
}
 
// }}}
// {{{ _closePackageFile()
 
function _closeChannelFile($fp)
{
fclose($fp);
}
 
// }}}
// {{{ _rebuildFileMap()
 
function _rebuildFileMap()
{
if (!class_exists('PEAR_Installer_Role')) {
require_once 'PEAR/Installer/Role.php';
}
$channels = $this->_listAllPackages();
$files = array();
foreach ($channels as $channel => $packages) {
foreach ($packages as $package) {
$version = $this->_packageInfo($package, 'version', $channel);
$filelist = $this->_packageInfo($package, 'filelist', $channel);
if (!is_array($filelist)) {
continue;
}
foreach ($filelist as $name => $attrs) {
if (isset($attrs['attribs'])) {
$attrs = $attrs['attribs'];
}
// it is possible for conflicting packages in different channels to
// conflict with data files/doc files
if ($name == 'dirtree') {
continue;
}
if (isset($attrs['role']) && !in_array($attrs['role'],
PEAR_Installer_Role::getInstallableRoles())) {
// these are not installed
continue;
}
if (isset($attrs['role']) && !in_array($attrs['role'],
PEAR_Installer_Role::getBaseinstallRoles())) {
$attrs['baseinstalldir'] = $package;
}
if (isset($attrs['baseinstalldir'])) {
$file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name;
} else {
$file = $name;
}
$file = preg_replace(',^/+,', '', $file);
if ($channel != 'pear.php.net') {
$files[$attrs['role']][$file] = array(strtolower($channel),
strtolower($package));
} else {
if (!is_array($files)) {
$file = array();
}
if (!isset($files[$attrs['role']])) {
$files[$attrs['role']] = array();
}
$files[$attrs['role']][$file] = strtolower($package);
}
}
}
}
$this->_assertStateDir();
if (!$this->hasWriteAccess()) {
return false;
}
$fp = @fopen($this->filemap, 'wb');
if (!$fp) {
return false;
}
$this->filemap_cache = $files;
fwrite($fp, serialize($files));
fclose($fp);
return true;
}
 
// }}}
// {{{ _readFileMap()
 
function _readFileMap()
{
if (!file_exists($this->filemap)) {
return array();
}
$fp = @fopen($this->filemap, 'r');
if (!$fp) {
return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg);
}
clearstatcache();
$rt = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
$fsize = filesize($this->filemap);
fclose($fp);
$data = file_get_contents($this->filemap);
set_magic_quotes_runtime($rt);
$tmp = unserialize($data);
if (!$tmp && $fsize > 7) {
return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data);
}
$this->filemap_cache = $tmp;
return true;
}
 
// }}}
// {{{ _lock()
 
/**
* Lock the registry.
*
* @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN.
* See flock manual for more information.
*
* @return bool TRUE on success, FALSE if locking failed, or a
* PEAR error if some other error occurs (such as the
* lock file not being writable).
*
* @access private
*/
function _lock($mode = LOCK_EX)
{
if (!eregi('Windows 9', php_uname())) {
if ($mode != LOCK_UN && is_resource($this->lock_fp)) {
// XXX does not check type of lock (LOCK_SH/LOCK_EX)
return true;
}
if (!$this->_assertStateDir()) {
if ($mode == LOCK_EX) {
return $this->raiseError('Registry directory is not writeable by the current user');
} else {
return true;
}
}
$open_mode = 'w';
// XXX People reported problems with LOCK_SH and 'w'
if ($mode === LOCK_SH || $mode === LOCK_UN) {
if (!file_exists($this->lockfile)) {
touch($this->lockfile);
}
$open_mode = 'r';
}
 
if (!is_resource($this->lock_fp)) {
$this->lock_fp = @fopen($this->lockfile, $open_mode);
}
 
if (!is_resource($this->lock_fp)) {
return $this->raiseError("could not create lock file" .
(isset($php_errormsg) ? ": " . $php_errormsg : ""));
}
if (!(int)flock($this->lock_fp, $mode)) {
switch ($mode) {
case LOCK_SH: $str = 'shared'; break;
case LOCK_EX: $str = 'exclusive'; break;
case LOCK_UN: $str = 'unlock'; break;
default: $str = 'unknown'; break;
}
return $this->raiseError("could not acquire $str lock ($this->lockfile)",
PEAR_REGISTRY_ERROR_LOCK);
}
}
return true;
}
 
// }}}
// {{{ _unlock()
 
function _unlock()
{
$ret = $this->_lock(LOCK_UN);
if (is_resource($this->lock_fp)) {
fclose($this->lock_fp);
}
$this->lock_fp = null;
return $ret;
}
 
// }}}
// {{{ _packageExists()
 
function _packageExists($package, $channel = false)
{
return file_exists($this->_packageFileName($package, $channel));
}
 
// }}}
// {{{ _channelExists()
 
/**
* Determine whether a channel exists in the registry
* @param string Channel name
* @param bool if true, then aliases will be ignored
* @return boolean
*/
function _channelExists($channel, $noaliases = false)
{
$a = file_exists($this->_channelFileName($channel, $noaliases));
if (!$a && $channel == 'pear.php.net') {
return true;
}
if (!$a && $channel == 'pecl.php.net') {
return true;
}
return $a;
}
 
// }}}
// {{{ _addChannel()
 
/**
* @param PEAR_ChannelFile Channel object
* @param donotuse
* @param string Last-Modified HTTP tag from remote request
* @return boolean|PEAR_Error True on creation, false if it already exists
*/
function _addChannel($channel, $update = false, $lastmodified = false)
{
if (!is_a($channel, 'PEAR_ChannelFile')) {
return false;
}
if (!$channel->validate()) {
return false;
}
if (file_exists($this->_channelFileName($channel->getName()))) {
if (!$update) {
return false;
}
$checker = $this->_getChannel($channel->getName());
if (PEAR::isError($checker)) {
return $checker;
}
if ($channel->getAlias() != $checker->getAlias()) {
if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) {
@unlink($this->_getChannelAliasFileName($checker->getAlias()));
}
}
} else {
if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net'))) {
return false;
}
}
$ret = $this->_assertChannelDir();
if (PEAR::isError($ret)) {
return $ret;
}
$ret = $this->_assertChannelStateDir($channel->getName());
if (PEAR::isError($ret)) {
return $ret;
}
if ($channel->getAlias() != $channel->getName()) {
if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) &&
$this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) {
$channel->setAlias($channel->getName());
}
if (!$this->hasWriteAccess()) {
return false;
}
$fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w');
if (!$fp) {
return false;
}
fwrite($fp, $channel->getName());
fclose($fp);
}
if (!$this->hasWriteAccess()) {
return false;
}
$fp = @fopen($this->_channelFileName($channel->getName()), 'wb');
if (!$fp) {
return false;
}
$info = $channel->toArray();
if ($lastmodified) {
$info['_lastmodified'] = $lastmodified;
} else {
$info['_lastmodified'] = date('r');
}
fwrite($fp, serialize($info));
fclose($fp);
return true;
}
 
// }}}
// {{{ _deleteChannel()
 
/**
* Deletion fails if there are any packages installed from the channel
* @param string|PEAR_ChannelFile channel name
* @return boolean|PEAR_Error True on deletion, false if it doesn't exist
*/
function _deleteChannel($channel)
{
if (!is_string($channel)) {
if (is_a($channel, 'PEAR_ChannelFile')) {
if (!$channel->validate()) {
return false;
}
$channel = $channel->getName();
} else {
return false;
}
}
if ($this->_getChannelFromAlias($channel) == '__uri') {
return false;
}
if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
return false;
}
if (!$this->_channelExists($channel)) {
return false;
}
if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
return false;
}
$channel = $this->_getChannelFromAlias($channel);
if ($channel == 'pear.php.net') {
return false;
}
$test = $this->_listChannelPackages($channel);
if (count($test)) {
return false;
}
$test = @rmdir($this->_channelDirectoryName($channel));
if (!$test) {
return false;
}
$file = $this->_getChannelAliasFileName($this->_getAlias($channel));
if (file_exists($file)) {
$test = @unlink($file);
if (!$test) {
return false;
}
}
$file = $this->_channelFileName($channel);
$ret = true;
if (file_exists($file)) {
$ret = @unlink($file);
}
return $ret;
}
 
// }}}
// {{{ _isChannelAlias()
 
/**
* Determine whether a channel exists in the registry
* @param string Channel Alias
* @return boolean
*/
function _isChannelAlias($alias)
{
return file_exists($this->_getChannelAliasFileName($alias));
}
 
// }}}
// {{{ _packageInfo()
 
/**
* @param string|null
* @param string|null
* @param string|null
* @return array|null
* @access private
*/
function _packageInfo($package = null, $key = null, $channel = 'pear.php.net')
{
if ($package === null) {
if ($channel === null) {
$channels = $this->_listChannels();
$ret = array();
foreach ($channels as $channel) {
$channel = strtolower($channel);
$ret[$channel] = array();
$packages = $this->_listPackages($channel);
foreach ($packages as $package) {
$ret[$channel][] = $this->_packageInfo($package, null, $channel);
}
}
return $ret;
}
$ps = $this->_listPackages($channel);
if (!count($ps)) {
return array();
}
return array_map(array(&$this, '_packageInfo'),
$ps, array_fill(0, count($ps), null),
array_fill(0, count($ps), $channel));
}
$fp = $this->_openPackageFile($package, 'r', $channel);
if ($fp === null) {
return null;
}
$rt = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
clearstatcache();
$this->_closePackageFile($fp);
$data = file_get_contents($this->_packageFileName($package, $channel));
set_magic_quotes_runtime($rt);
$data = unserialize($data);
if ($key === null) {
return $data;
}
// compatibility for package.xml version 2.0
if (isset($data['old'][$key])) {
return $data['old'][$key];
}
if (isset($data[$key])) {
return $data[$key];
}
return null;
}
 
// }}}
// {{{ _channelInfo()
 
/**
* @param string Channel name
* @param bool whether to strictly retrieve info of channels, not just aliases
* @return array|null
*/
function _channelInfo($channel, $noaliases = false)
{
if (!$this->_channelExists($channel, $noaliases)) {
return null;
}
$fp = $this->_openChannelFile($channel, 'r');
if ($fp === null) {
return null;
}
$rt = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
clearstatcache();
$this->_closeChannelFile($fp);
$data = file_get_contents($this->_channelFileName($channel));
set_magic_quotes_runtime($rt);
$data = unserialize($data);
return $data;
}
 
// }}}
// {{{ _listChannels()
 
function _listChannels()
{
$channellist = array();
if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) {
return array('pear.php.net', 'pecl.php.net', '__uri');
}
$dp = opendir($this->channelsdir);
while ($ent = readdir($dp)) {
if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
continue;
}
if ($ent == '__uri.reg') {
$channellist[] = '__uri';
continue;
}
$channellist[] = str_replace('_', '/', substr($ent, 0, -4));
}
closedir($dp);
if (!in_array('pear.php.net', $channellist)) {
$channellist[] = 'pear.php.net';
}
if (!in_array('pecl.php.net', $channellist)) {
$channellist[] = 'pecl.php.net';
}
if (!in_array('__uri', $channellist)) {
$channellist[] = '__uri';
}
return $channellist;
}
 
// }}}
// {{{ _listPackages()
 
function _listPackages($channel = false)
{
if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
return $this->_listChannelPackages($channel);
}
if (!file_exists($this->statedir) || !is_dir($this->statedir)) {
return array();
}
$pkglist = array();
$dp = opendir($this->statedir);
if (!$dp) {
return $pkglist;
}
while ($ent = readdir($dp)) {
if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
continue;
}
$pkglist[] = substr($ent, 0, -4);
}
closedir($dp);
return $pkglist;
}
 
// }}}
// {{{ _listChannelPackages()
 
function _listChannelPackages($channel)
{
$pkglist = array();
if (!file_exists($this->_channelDirectoryName($channel)) ||
!is_dir($this->_channelDirectoryName($channel))) {
return array();
}
$dp = opendir($this->_channelDirectoryName($channel));
if (!$dp) {
return $pkglist;
}
while ($ent = readdir($dp)) {
if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
continue;
}
$pkglist[] = substr($ent, 0, -4);
}
closedir($dp);
return $pkglist;
}
 
// }}}
function _listAllPackages()
{
$ret = array();
foreach ($this->_listChannels() as $channel) {
$ret[$channel] = $this->_listPackages($channel);
}
return $ret;
}
 
/**
* Add an installed package to the registry
* @param string package name
* @param array package info (parsed by PEAR_Common::infoFrom*() methods)
* @return bool success of saving
* @access private
*/
function _addPackage($package, $info)
{
if ($this->_packageExists($package)) {
return false;
}
$fp = $this->_openPackageFile($package, 'wb');
if ($fp === null) {
return false;
}
$info['_lastmodified'] = time();
fwrite($fp, serialize($info));
$this->_closePackageFile($fp);
if (isset($info['filelist'])) {
$this->_rebuildFileMap();
}
return true;
}
 
/**
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @return bool
* @access private
*/
function _addPackage2($info)
{
if (!$info->validate()) {
if (class_exists('PEAR_Common')) {
$ui = PEAR_Frontend::singleton();
if ($ui) {
foreach ($info->getValidationWarnings() as $err) {
$ui->log($err['message'], true);
}
}
}
return false;
}
$channel = $info->getChannel();
$package = $info->getPackage();
$save = $info;
if ($this->_packageExists($package, $channel)) {
return false;
}
if (!$this->_channelExists($channel, true)) {
return false;
}
$info = $info->toArray(true);
if (!$info) {
return false;
}
$fp = $this->_openPackageFile($package, 'wb', $channel);
if ($fp === null) {
return false;
}
$info['_lastmodified'] = time();
fwrite($fp, serialize($info));
$this->_closePackageFile($fp);
$this->_rebuildFileMap();
return true;
}
 
/**
* @param string Package name
* @param array parsed package.xml 1.0
* @param bool this parameter is only here for BC. Don't use it.
* @access private
*/
function _updatePackage($package, $info, $merge = true)
{
$oldinfo = $this->_packageInfo($package);
if (empty($oldinfo)) {
return false;
}
$fp = $this->_openPackageFile($package, 'w');
if ($fp === null) {
return false;
}
if (is_object($info)) {
$info = $info->toArray();
}
$info['_lastmodified'] = time();
$newinfo = $info;
if ($merge) {
$info = array_merge($oldinfo, $info);
} else {
$diff = $info;
}
fwrite($fp, serialize($info));
$this->_closePackageFile($fp);
if (isset($newinfo['filelist'])) {
$this->_rebuildFileMap();
}
return true;
}
 
/**
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @return bool
* @access private
*/
function _updatePackage2($info)
{
if (!$this->_packageExists($info->getPackage(), $info->getChannel())) {
return false;
}
$fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel());
if ($fp === null) {
return false;
}
$save = $info;
$info = $save->getArray(true);
$info['_lastmodified'] = time();
fwrite($fp, serialize($info));
$this->_closePackageFile($fp);
$this->_rebuildFileMap();
return true;
}
 
/**
* @param string Package name
* @param string Channel name
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null
* @access private
*/
function &_getPackage($package, $channel = 'pear.php.net')
{
$info = $this->_packageInfo($package, null, $channel);
if ($info === null) {
return $info;
}
$a = $this->_config;
if (!$a) {
$this->_config = &new PEAR_Config;
$this->_config->set('php_dir', $this->statedir);
}
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
$pkg = &new PEAR_PackageFile($this->_config);
$pf = &$pkg->fromArray($info);
return $pf;
}
 
/**
* @param string channel name
* @param bool whether to strictly retrieve channel names
* @return PEAR_ChannelFile|PEAR_Error
* @access private
*/
function &_getChannel($channel, $noaliases = false)
{
$ch = false;
if ($this->_channelExists($channel, $noaliases)) {
$chinfo = $this->_channelInfo($channel, $noaliases);
if ($chinfo) {
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo);
}
}
if ($ch) {
if ($ch->validate()) {
return $ch;
}
foreach ($ch->getErrors(true) as $err) {
$message = $err['message'] . "\n";
}
$ch = PEAR::raiseError($message);
return $ch;
}
if ($this->_getChannelFromAlias($channel) == 'pear.php.net') {
// the registry is not properly set up, so use defaults
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$pear_channel = new PEAR_ChannelFile;
$pear_channel->setName('pear.php.net');
$pear_channel->setAlias('pear');
$pear_channel->setSummary('PHP Extension and Application Repository');
$pear_channel->setDefaultPEARProtocols();
$pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/');
$pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/');
return $pear_channel;
}
if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
// the registry is not properly set up, so use defaults
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$pear_channel = new PEAR_ChannelFile;
$pear_channel->setName('pecl.php.net');
$pear_channel->setAlias('pecl');
$pear_channel->setSummary('PHP Extension Community Library');
$pear_channel->setDefaultPEARProtocols();
$pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/');
$pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/');
$pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0');
return $pear_channel;
}
if ($this->_getChannelFromAlias($channel) == '__uri') {
// the registry is not properly set up, so use defaults
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$private = new PEAR_ChannelFile;
$private->setName('__uri');
$private->addFunction('xmlrpc', '1.0', '****');
$private->setSummary('Pseudo-channel for static packages');
return $private;
}
return $ch;
}
 
// {{{ packageExists()
 
/**
* @param string Package name
* @param string Channel name
* @return bool
*/
function packageExists($package, $channel = 'pear.php.net')
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_packageExists($package, $channel);
$this->_unlock();
return $ret;
}
 
// }}}
 
// {{{ channelExists()
 
/**
* @param string channel name
* @param bool if true, then aliases will be ignored
* @return bool
*/
function channelExists($channel, $noaliases = false)
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_channelExists($channel, $noaliases);
$this->_unlock();
return $ret;
}
 
// }}}
 
// {{{ isAlias()
 
/**
* Determines whether the parameter is an alias of a channel
* @param string
* @return bool
*/
function isAlias($alias)
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_isChannelAlias($alias);
$this->_unlock();
return $ret;
}
 
// }}}
// {{{ packageInfo()
 
/**
* @param string|null
* @param string|null
* @param string
* @return array|null
*/
function packageInfo($package = null, $key = null, $channel = 'pear.php.net')
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_packageInfo($package, $key, $channel);
$this->_unlock();
return $ret;
}
 
// }}}
// {{{ channelInfo()
 
/**
* Retrieve a raw array of channel data.
*
* Do not use this, instead use {@link getChannel()} for normal
* operations. Array structure is undefined in this method
* @param string channel name
* @param bool whether to strictly retrieve information only on non-aliases
* @return array|null|PEAR_Error
*/
function channelInfo($channel = null, $noaliases = false)
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_channelInfo($channel, $noaliases);
$this->_unlock();
return $ret;
}
 
// }}}
 
/**
* @param string
*/
function channelName($channel)
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_getChannelFromAlias($channel);
$this->_unlock();
return $ret;
}
 
/**
* @param string
*/
function channelAlias($channel)
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_getAlias($channel);
$this->_unlock();
return $ret;
}
// {{{ listPackages()
 
function listPackages($channel = false)
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_listPackages($channel);
$this->_unlock();
return $ret;
}
 
// }}}
// {{{ listAllPackages()
 
function listAllPackages()
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_listAllPackages();
$this->_unlock();
return $ret;
}
 
// }}}
// {{{ listChannel()
 
function listChannels()
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_listChannels();
$this->_unlock();
return $ret;
}
 
// }}}
// {{{ addPackage()
 
/**
* Add an installed package to the registry
* @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object
* that will be passed to {@link addPackage2()}
* @param array package info (parsed by PEAR_Common::infoFrom*() methods)
* @return bool success of saving
*/
function addPackage($package, $info)
{
if (is_object($info)) {
return $this->addPackage2($info);
}
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
$ret = $this->_addPackage($package, $info);
$this->_unlock();
if ($ret) {
if (!class_exists('PEAR_PackageFile_v1')) {
require_once 'PEAR/PackageFile/v1.php';
}
$pf = new PEAR_PackageFile_v1;
$pf->setConfig($this->_config);
$pf->fromArray($info);
$this->_dependencyDB->uninstallPackage($pf);
$this->_dependencyDB->installPackage($pf);
}
return $ret;
}
 
// }}}
// {{{ addPackage2()
 
function addPackage2($info)
{
if (!is_object($info)) {
return $this->addPackage($info['package'], $info);
}
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
$ret = $this->_addPackage2($info);
$this->_unlock();
if ($ret) {
$this->_dependencyDB->uninstallPackage($info);
$this->_dependencyDB->installPackage($info);
}
return $ret;
}
 
// }}}
// {{{ updateChannel()
 
/**
* For future expandibility purposes, separate this
* @param PEAR_ChannelFile
*/
function updateChannel($channel, $lastmodified = null)
{
if ($channel->getName() == '__uri') {
return false;
}
return $this->addChannel($channel, $lastmodified, true);
}
 
// }}}
// {{{ deleteChannel()
 
/**
* Deletion fails if there are any packages installed from the channel
* @param string|PEAR_ChannelFile channel name
* @return boolean|PEAR_Error True on deletion, false if it doesn't exist
*/
function deleteChannel($channel)
{
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
$ret = $this->_deleteChannel($channel);
$this->_unlock();
if ($ret && is_a($this->_config, 'PEAR_Config')) {
$this->_config->setChannels($this->listChannels());
}
return $ret;
}
 
// }}}
// {{{ addChannel()
 
/**
* @param PEAR_ChannelFile Channel object
* @param string Last-Modified header from HTTP for caching
* @return boolean|PEAR_Error True on creation, false if it already exists
*/
function addChannel($channel, $lastmodified = false, $update = false)
{
if (!is_a($channel, 'PEAR_ChannelFile')) {
return false;
}
if (!$channel->validate()) {
return false;
}
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
$ret = $this->_addChannel($channel, $update, $lastmodified);
$this->_unlock();
if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) {
$this->_config->setChannels($this->listChannels());
}
return $ret;
}
 
// }}}
// {{{ deletePackage()
 
function deletePackage($package, $channel = 'pear.php.net')
{
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
$file = $this->_packageFileName($package, $channel);
if (file_exists($file)) {
$ret = @unlink($file);
} else {
$ret = false;
}
$this->_rebuildFileMap();
$this->_unlock();
$p = array('channel' => $channel, 'package' => $package);
$this->_dependencyDB->uninstallPackage($p);
return $ret;
}
 
// }}}
// {{{ updatePackage()
 
function updatePackage($package, $info, $merge = true)
{
if (is_object($info)) {
return $this->updatePackage2($info, $merge);
}
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
$ret = $this->_updatePackage($package, $info, $merge);
$this->_unlock();
if ($ret) {
if (!class_exists('PEAR_PackageFile_v1')) {
require_once 'PEAR/PackageFile/v1.php';
}
$pf = new PEAR_PackageFile_v1;
$pf->setConfig($this->_config);
$pf->fromArray($this->packageInfo($package));
$this->_dependencyDB->uninstallPackage($pf);
$this->_dependencyDB->installPackage($pf);
}
return $ret;
}
 
// }}}
// {{{ updatePackage2()
 
function updatePackage2($info)
{
if (!is_object($info)) {
return $this->updatePackage($info['package'], $info, $merge);
}
if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) {
return false;
}
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
$ret = $this->_updatePackage2($info);
$this->_unlock();
if ($ret) {
$this->_dependencyDB->uninstallPackage($info);
$this->_dependencyDB->installPackage($info);
}
return $ret;
}
 
// }}}
// {{{ getChannel()
/**
* @param string channel name
* @param bool whether to strictly return raw channels (no aliases)
* @return PEAR_ChannelFile|PEAR_Error
*/
function &getChannel($channel, $noaliases = false)
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = &$this->_getChannel($channel, $noaliases);
if (!$ret) {
return PEAR::raiseError('Unknown channel: ' . $channel);
}
$this->_unlock();
return $ret;
}
 
// }}}
// {{{ getPackage()
/**
* @param string package name
* @param string channel name
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null
*/
function &getPackage($package, $channel = 'pear.php.net')
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$pf = &$this->_getPackage($package, $channel);
$this->_unlock();
return $pf;
}
 
// }}}
 
/**
* Get PEAR_PackageFile_v[1/2] objects representing the contents of
* a dependency group that are installed.
*
* This is used at uninstall-time
* @param array
* @return array|false
*/
function getInstalledGroup($group)
{
$ret = array();
if (isset($group['package'])) {
if (!isset($group['package'][0])) {
$group['package'] = array($group['package']);
}
foreach ($group['package'] as $package) {
$depchannel = isset($package['channel']) ? $package['channel'] : '__uri';
$p = &$this->getPackage($package['name'], $depchannel);
if ($p) {
$save = &$p;
$ret[] = &$save;
}
}
}
if (isset($group['subpackage'])) {
if (!isset($group['subpackage'][0])) {
$group['subpackage'] = array($group['subpackage']);
}
foreach ($group['subpackage'] as $package) {
$depchannel = isset($package['channel']) ? $package['channel'] : '__uri';
$p = &$this->getPackage($package['name'], $depchannel);
if ($p) {
$save = &$p;
$ret[] = &$save;
}
}
}
if (!count($ret)) {
return false;
}
return $ret;
}
 
// {{{ getChannelValidator()
/**
* @param string channel name
* @return PEAR_Validate|false
*/
function &getChannelValidator($channel)
{
$chan = $this->getChannel($channel);
if (PEAR::isError($chan)) {
return $chan;
}
$val = $chan->getValidationObject();
return $val;
}
// }}}
// {{{ getChannels()
/**
* @param string channel name
* @return array an array of PEAR_ChannelFile objects representing every installed channel
*/
function &getChannels()
{
$ret = array();
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
foreach ($this->_listChannels() as $channel) {
$e = &$this->_getChannel($channel);
if (!$e || PEAR::isError($e)) {
continue;
}
$ret[] = $e;
}
$this->_unlock();
return $ret;
}
 
// }}}
// {{{ checkFileMap()
 
/**
* Test whether a file or set of files belongs to a package.
*
* If an array is passed in
* @param string|array file path, absolute or relative to the pear
* install dir
* @param string|array name of PEAR package or array('package' => name, 'channel' =>
* channel) of a package that will be ignored
* @param string API version - 1.1 will exclude any files belonging to a package
* @param array private recursion variable
* @return array|false which package and channel the file belongs to, or an empty
* string if the file does not belong to an installed package,
* or belongs to the second parameter's package
*/
function checkFileMap($path, $package = false, $api = '1.0', $attrs = false)
{
if (is_array($path)) {
static $notempty;
if (empty($notempty)) {
if (!class_exists('PEAR_Installer_Role')) {
require_once 'PEAR/Installer/Role.php';
}
$notempty = create_function('$a','return !empty($a);');
}
$package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1]))
: strtolower($package);
$pkgs = array();
foreach ($path as $name => $attrs) {
if (is_array($attrs)) {
if (isset($attrs['install-as'])) {
$name = $attrs['install-as'];
}
if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) {
// these are not installed
continue;
}
if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) {
$attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package;
}
if (isset($attrs['baseinstalldir'])) {
$name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name;
}
}
$pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs);
if (PEAR::isError($pkgs[$name])) {
return $pkgs[$name];
}
}
return array_filter($pkgs, $notempty);
}
if (empty($this->filemap_cache)) {
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$err = $this->_readFileMap();
$this->_unlock();
if (PEAR::isError($err)) {
return $err;
}
}
if (!$attrs) {
$attrs = array('role' => 'php'); // any old call would be for PHP role only
}
if (isset($this->filemap_cache[$attrs['role']][$path])) {
if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) {
return false;
}
return $this->filemap_cache[$attrs['role']][$path];
}
$l = strlen($this->install_dir);
if (substr($path, 0, $l) == $this->install_dir) {
$path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l));
}
if (isset($this->filemap_cache[$attrs['role']][$path])) {
if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) {
return false;
}
return $this->filemap_cache[$attrs['role']][$path];
}
return false;
}
 
// }}}
// {{{ flush()
/**
* Force a reload of the filemap
* @since 1.5.0RC3
*/
function flushFileMap()
{
$this->filemap_cache = null;
clearstatcache(); // ensure that the next read gets the full, current filemap
}
 
// }}}
// {{{ apiVersion()
/**
* Get the expected API version. Channels API is version 1.1, as it is backwards
* compatible with 1.0
* @return string
*/
function apiVersion()
{
return '1.1';
}
// }}}
 
 
/**
* Parse a package name, or validate a parsed package name array
* @param string|array pass in an array of format
* array(
* 'package' => 'pname',
* ['channel' => 'channame',]
* ['version' => 'version',]
* ['state' => 'state',]
* ['group' => 'groupname'])
* or a string of format
* [channel://][channame/]pname[-version|-state][/group=groupname]
* @return array|PEAR_Error
*/
function parsePackageName($param, $defaultchannel = 'pear.php.net')
{
$saveparam = $param;
if (is_array($param)) {
// convert to string for error messages
$saveparam = $this->parsedPackageNameToString($param);
// process the array
if (!isset($param['package'])) {
return PEAR::raiseError('parsePackageName(): array $param ' .
'must contain a valid package name in index "param"',
'package', null, null, $param);
}
if (!isset($param['uri'])) {
if (!isset($param['channel'])) {
$param['channel'] = $defaultchannel;
}
} else {
$param['channel'] = '__uri';
}
} else {
$components = @parse_url((string) $param);
if (isset($components['scheme'])) {
if ($components['scheme'] == 'http') {
// uri package
$param = array('uri' => $param, 'channel' => '__uri');
} elseif($components['scheme'] != 'channel') {
return PEAR::raiseError('parsePackageName(): only channel:// uris may ' .
'be downloaded, not "' . $param . '"', 'invalid', null, null, $param);
}
}
if (!isset($components['path'])) {
return PEAR::raiseError('parsePackageName(): array $param ' .
'must contain a valid package name in "' . $param . '"',
'package', null, null, $param);
}
if (isset($components['host'])) {
// remove the leading "/"
$components['path'] = substr($components['path'], 1);
}
if (!isset($components['scheme'])) {
if (strpos($components['path'], '/') !== false) {
if ($components['path']{0} == '/') {
return PEAR::raiseError('parsePackageName(): this is not ' .
'a package name, it begins with "/" in "' . $param . '"',
'invalid', null, null, $param);
}
$parts = explode('/', $components['path']);
$components['host'] = array_shift($parts);
if (count($parts) > 1) {
$components['path'] = array_pop($parts);
$components['host'] .= '/' . implode('/', $parts);
} else {
$components['path'] = implode('/', $parts);
}
} else {
$components['host'] = $defaultchannel;
}
} else {
if (strpos($components['path'], '/')) {
$parts = explode('/', $components['path']);
$components['path'] = array_pop($parts);
$components['host'] .= '/' . implode('/', $parts);
}
}
 
if (is_array($param)) {
$param['package'] = $components['path'];
} else {
$param = array(
'package' => $components['path']
);
if (isset($components['host'])) {
$param['channel'] = $components['host'];
}
}
if (isset($components['fragment'])) {
$param['group'] = $components['fragment'];
}
if (isset($components['user'])) {
$param['user'] = $components['user'];
}
if (isset($components['pass'])) {
$param['pass'] = $components['pass'];
}
if (isset($components['query'])) {
parse_str($components['query'], $param['opts']);
}
// check for extension
$pathinfo = pathinfo($param['package']);
if (isset($pathinfo['extension']) &&
in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) {
$param['extension'] = $pathinfo['extension'];
$param['package'] = substr($pathinfo['basename'], 0,
strlen($pathinfo['basename']) - 4);
}
// check for version
if (strpos($param['package'], '-')) {
$test = explode('-', $param['package']);
if (count($test) != 2) {
return PEAR::raiseError('parsePackageName(): only one version/state ' .
'delimiter "-" is allowed in "' . $saveparam . '"',
'version', null, null, $param);
}
list($param['package'], $param['version']) = $test;
}
}
// validation
$info = $this->channelExists($param['channel']);
if (PEAR::isError($info)) {
return $info;
}
if (!$info) {
return PEAR::raiseError('unknown channel "' . $param['channel'] .
'" in "' . $saveparam . '"', 'channel', null, null, $param);
}
$chan = $this->getChannel($param['channel']);
if (PEAR::isError($chan)) {
return $chan;
}
if (!$chan) {
return PEAR::raiseError("Exception: corrupt registry, could not " .
"retrieve channel " . $param['channel'] . " information",
'registry', null, null, $param);
}
$param['channel'] = $chan->getName();
$validate = $chan->getValidationObject();
$vpackage = $chan->getValidationPackage();
// validate package name
if (!$validate->validPackageName($param['package'], $vpackage['_content'])) {
return PEAR::raiseError('parsePackageName(): invalid package name "' .
$param['package'] . '" in "' . $saveparam . '"',
'package', null, null, $param);
}
if (isset($param['group'])) {
if (!PEAR_Validate::validGroupName($param['group'])) {
return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] .
'" is not a valid group name in "' . $saveparam . '"', 'group', null, null,
$param);
}
}
if (isset($param['state'])) {
if (!in_array(strtolower($param['state']), $validate->getValidStates())) {
return PEAR::raiseError('parsePackageName(): state "' . $param['state']
. '" is not a valid state in "' . $saveparam . '"',
'state', null, null, $param);
}
}
if (isset($param['version'])) {
if (isset($param['state'])) {
return PEAR::raiseError('parsePackageName(): cannot contain both ' .
'a version and a stability (state) in "' . $saveparam . '"',
'version/state', null, null, $param);
}
// check whether version is actually a state
if (in_array(strtolower($param['version']), $validate->getValidStates())) {
$param['state'] = strtolower($param['version']);
unset($param['version']);
} else {
if (!$validate->validVersion($param['version'])) {
return PEAR::raiseError('parsePackageName(): "' . $param['version'] .
'" is neither a valid version nor a valid state in "' .
$saveparam . '"', 'version/state', null, null, $param);
}
}
}
return $param;
}
 
/**
* @param array
* @return string
*/
function parsedPackageNameToString($parsed, $brief = false)
{
if (is_string($parsed)) {
return $parsed;
}
if (is_object($parsed)) {
$p = $parsed;
$parsed = array(
'package' => $p->getPackage(),
'channel' => $p->getChannel(),
'version' => $p->getVersion(),
);
}
if (isset($parsed['uri'])) {
return $parsed['uri'];
}
if ($brief) {
if ($channel = $this->channelAlias($parsed['channel'])) {
return $channel . '/' . $parsed['package'];
}
}
$upass = '';
if (isset($parsed['user'])) {
$upass = $parsed['user'];
if (isset($parsed['pass'])) {
$upass .= ':' . $parsed['pass'];
}
$upass = "$upass@";
}
$ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package'];
if (isset($parsed['version']) || isset($parsed['state'])) {
$ver = isset($parsed['version']) ? $parsed['version'] : '';
$ver .= isset($parsed['state']) ? $parsed['state'] : '';
$ret .= '-' . $ver;
}
if (isset($parsed['extension'])) {
$ret .= '.' . $parsed['extension'];
}
if (isset($parsed['opts'])) {
$ret .= '?';
foreach ($parsed['opts'] as $name => $value) {
$parsed['opts'][$name] = "$name=$value";
}
$ret .= implode('&', $parsed['opts']);
}
if (isset($parsed['group'])) {
$ret .= '#' . $parsed['group'];
}
return $ret;
}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/REST.php
New file
0,0 → 1,395
<?php
/**
* PEAR_REST
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: REST.php,v 1.21 2006/03/27 04:33:11 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* For downloading xml files
*/
require_once 'PEAR.php';
require_once 'PEAR/XMLParser.php';
 
/**
* Intelligently retrieve data, following hyperlinks if necessary, and re-directing
* as well
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_REST
{
var $config;
var $_options;
function PEAR_REST(&$config, $options = array())
{
$this->config = &$config;
$this->_options = $options;
}
 
/**
* Retrieve REST data, but always retrieve the local cache if it is available.
*
* This is useful for elements that should never change, such as information on a particular
* release
* @param string full URL to this resource
* @param array|false contents of the accept-encoding header
* @param boolean if true, xml will be returned as a string, otherwise, xml will be
* parsed using PEAR_XMLParser
* @return string|array
*/
function retrieveCacheFirst($url, $accept = false, $forcestring = false)
{
$cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cachefile';
if (file_exists($cachefile)) {
return unserialize(implode('', file($cachefile)));
}
return $this->retrieveData($url, $accept, $forcestring);
}
 
/**
* Retrieve a remote REST resource
* @param string full URL to this resource
* @param array|false contents of the accept-encoding header
* @param boolean if true, xml will be returned as a string, otherwise, xml will be
* parsed using PEAR_XMLParser
* @return string|array
*/
function retrieveData($url, $accept = false, $forcestring = false)
{
$cacheId = $this->getCacheId($url);
if ($ret = $this->useLocalCache($url, $cacheId)) {
return $ret;
}
if (!isset($this->_options['offline'])) {
$trieddownload = true;
$file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept);
} else {
$trieddownload = false;
$file = false;
}
if (PEAR::isError($file)) {
if ($file->getCode() == -9276) {
$trieddownload = false;
$file = false; // use local copy if available on socket connect error
} else {
return $file;
}
}
if (!$file) {
$ret = $this->getCache($url);
if (!PEAR::isError($ret) && $trieddownload) {
// reset the age of the cache if the server says it was unmodified
$this->saveCache($url, $ret, null, true, $cacheId);
}
return $ret;
}
if (is_array($file)) {
$headers = $file[2];
$lastmodified = $file[1];
$content = $file[0];
} else {
$content = $file;
$lastmodified = false;
$headers = array();
}
if ($forcestring) {
$this->saveCache($url, $content, $lastmodified, false, $cacheId);
return $content;
}
if (isset($headers['content-type'])) {
switch ($headers['content-type']) {
case 'text/xml' :
case 'application/xml' :
$parser = new PEAR_XMLParser;
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $parser->parse($content);
PEAR::popErrorHandling();
if (PEAR::isError($err)) {
return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' .
$err->getMessage());
}
$content = $parser->getData();
case 'text/html' :
default :
// use it as a string
}
} else {
// assume XML
$parser = new PEAR_XMLParser;
$parser->parse($content);
$content = $parser->getData();
}
$this->saveCache($url, $content, $lastmodified, false, $cacheId);
return $content;
}
 
function useLocalCache($url, $cacheid = null)
{
if ($cacheid === null) {
$cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cacheid';
if (file_exists($cacheidfile)) {
$cacheid = unserialize(implode('', file($cacheidfile)));
} else {
return false;
}
}
$cachettl = $this->config->get('cache_ttl');
// If cache is newer than $cachettl seconds, we use the cache!
if (time() - $cacheid['age'] < $cachettl) {
return $this->getCache($url);
}
return false;
}
 
function getCacheId($url)
{
$cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cacheid';
if (file_exists($cacheidfile)) {
$ret = unserialize(implode('', file($cacheidfile)));
return $ret;
} else {
return false;
}
}
 
function getCache($url)
{
$cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cachefile';
if (file_exists($cachefile)) {
return unserialize(implode('', file($cachefile)));
} else {
return PEAR::raiseError('No cached content available for "' . $url . '"');
}
}
 
/**
* @param string full URL to REST resource
* @param string original contents of the REST resource
* @param array HTTP Last-Modified and ETag headers
* @param bool if true, then the cache id file should be regenerated to
* trigger a new time-to-live value
*/
function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null)
{
$cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cacheid';
$cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cachefile';
if ($cacheid === null && $nochange) {
$cacheid = unserialize(implode('', file($cacheidfile)));
}
 
$fp = @fopen($cacheidfile, 'wb');
if (!$fp) {
$cache_dir = $this->config->get('cache_dir');
if (!is_dir($cache_dir)) {
System::mkdir(array('-p', $cache_dir));
$fp = @fopen($cacheidfile, 'wb');
if (!$fp) {
return false;
}
} else {
return false;
}
}
 
if ($nochange) {
fwrite($fp, serialize(array(
'age' => time(),
'lastChange' => $cacheid['lastChange'],
)));
fclose($fp);
return true;
} else {
fwrite($fp, serialize(array(
'age' => time(),
'lastChange' => $lastmodified,
)));
}
fclose($fp);
$fp = @fopen($cachefile, 'wb');
if (!$fp) {
if (file_exists($cacheidfile)) {
@unlink($cacheidfile);
}
return false;
}
fwrite($fp, serialize($contents));
fclose($fp);
return true;
}
 
/**
* Efficiently Download a file through HTTP. Returns downloaded file as a string in-memory
* This is best used for small files
*
* If an HTTP proxy has been configured (http_proxy PEAR_Config
* setting), the proxy will be used.
*
* @param string $url the URL to download
* @param string $save_dir directory to save file in
* @param false|string|array $lastmodified header values to check against for caching
* use false to return the header values from this download
* @param false|array $accept Accept headers to send
* @return string|array Returns the contents of the downloaded file or a PEAR
* error on failure. If the error is caused by
* socket-related errors, the error object will
* have the fsockopen error code available through
* getCode(). If caching is requested, then return the header
* values.
*
* @access public
*/
function downloadHttp($url, $lastmodified = null, $accept = false)
{
$info = parse_url($url);
if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) {
return PEAR::raiseError('Cannot download non-http URL "' . $url . '"');
}
if (!isset($info['host'])) {
return PEAR::raiseError('Cannot download from non-URL "' . $url . '"');
} else {
$host = $info['host'];
if (!array_key_exists('port', $info)) {
$info['port'] = null;
}
if (!array_key_exists('path', $info)) {
$info['path'] = null;
}
$port = $info['port'];
$path = $info['path'];
}
$proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
if ($this->config->get('http_proxy')&&
$proxy = parse_url($this->config->get('http_proxy'))) {
$proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') {
$proxy_host = 'ssl://' . $proxy_host;
}
$proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080;
$proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
$proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
}
if (empty($port)) {
if (isset($info['scheme']) && $info['scheme'] == 'https') {
$port = 443;
} else {
$port = 80;
}
}
If (isset($proxy['host'])) {
$request = "GET $url HTTP/1.1\r\n";
} else {
$request = "GET $path HTTP/1.1\r\n";
}
 
$ifmodifiedsince = '';
if (is_array($lastmodified)) {
if (isset($lastmodified['Last-Modified'])) {
$ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n";
}
if (isset($lastmodified['ETag'])) {
$ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n";
}
} else {
$ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : '');
}
$request .= "Host: $host:$port\r\n" . $ifmodifiedsince .
"User-Agent: PEAR/1.5.1/PHP/" . PHP_VERSION . "\r\n";
$username = $this->config->get('username');
$password = $this->config->get('password');
if ($username && $password) {
$tmp = base64_encode("$username:$password");
$request .= "Authorization: Basic $tmp\r\n";
}
if ($proxy_host != '' && $proxy_user != '') {
$request .= 'Proxy-Authorization: Basic ' .
base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n";
}
if ($accept) {
$request .= 'Accept: ' . implode(', ', $accept) . "\r\n";
}
$request .= "Connection: close\r\n";
$request .= "\r\n";
if ($proxy_host != '') {
$fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 15);
if (!$fp) {
return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr",
-9276);
}
} else {
if (isset($info['scheme']) && $info['scheme'] == 'https') {
$host = 'ssl://' . $host;
}
$fp = @fsockopen($host, $port, $errno, $errstr);
if (!$fp) {
return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
}
}
fwrite($fp, $request);
$headers = array();
while (trim($line = fgets($fp, 1024))) {
if (preg_match('/^([^:]+):\s+(.*)\s*$/', $line, $matches)) {
$headers[strtolower($matches[1])] = trim($matches[2]);
} elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
if ($matches[1] == 304 && ($lastmodified || ($lastmodified === false))) {
return false;
}
if ($matches[1] != 200) {
return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)", (int) $matches[1]);
}
}
}
if (isset($headers['content-length'])) {
$length = $headers['content-length'];
} else {
$length = -1;
}
$data = '';
while ($chunk = @fread($fp, 8192)) {
$data .= $chunk;
}
fclose($fp);
if ($lastmodified === false || $lastmodified) {
if (isset($headers['etag'])) {
$lastmodified = array('ETag' => $headers['etag']);
}
if (isset($headers['last-modified'])) {
if (is_array($lastmodified)) {
$lastmodified['Last-Modified'] = $headers['last-modified'];
} else {
$lastmodified = $headers['last-modified'];
}
}
return array($data, $lastmodified, $headers);
}
return $data;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command.php
New file
0,0 → 1,416
<?php
/**
* PEAR_Command, command pattern class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Command.php,v 1.38 2006/10/31 02:54:40 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* Needed for error handling
*/
require_once 'PEAR.php';
require_once 'PEAR/Frontend.php';
require_once 'PEAR/XMLParser.php';
 
/**
* List of commands and what classes they are implemented in.
* @var array command => implementing class
*/
$GLOBALS['_PEAR_Command_commandlist'] = array();
 
/**
* List of commands and their descriptions
* @var array command => description
*/
$GLOBALS['_PEAR_Command_commanddesc'] = array();
 
/**
* List of shortcuts to common commands.
* @var array shortcut => command
*/
$GLOBALS['_PEAR_Command_shortcuts'] = array();
 
/**
* Array of command objects
* @var array class => object
*/
$GLOBALS['_PEAR_Command_objects'] = array();
 
/**
* PEAR command class, a simple factory class for administrative
* commands.
*
* How to implement command classes:
*
* - The class must be called PEAR_Command_Nnn, installed in the
* "PEAR/Common" subdir, with a method called getCommands() that
* returns an array of the commands implemented by the class (see
* PEAR/Command/Install.php for an example).
*
* - The class must implement a run() function that is called with three
* params:
*
* (string) command name
* (array) assoc array with options, freely defined by each
* command, for example:
* array('force' => true)
* (array) list of the other parameters
*
* The run() function returns a PEAR_CommandResponse object. Use
* these methods to get information:
*
* int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL)
* *_PARTIAL means that you need to issue at least
* one more command to complete the operation
* (used for example for validation steps).
*
* string getMessage() Returns a message for the user. Remember,
* no HTML or other interface-specific markup.
*
* If something unexpected happens, run() returns a PEAR error.
*
* - DON'T OUTPUT ANYTHING! Return text for output instead.
*
* - DON'T USE HTML! The text you return will be used from both Gtk,
* web and command-line interfaces, so for now, keep everything to
* plain text.
*
* - DON'T USE EXIT OR DIE! Always use pear errors. From static
* classes do PEAR::raiseError(), from other classes do
* $this->raiseError().
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command
{
// {{{ factory()
 
/**
* Get the right object for executing a command.
*
* @param string $command The name of the command
* @param object $config Instance of PEAR_Config object
*
* @return object the command object or a PEAR error
*
* @access public
* @static
*/
function &factory($command, &$config)
{
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
PEAR_Command::registerCommands();
}
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
}
if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
$a = PEAR::raiseError("unknown command `$command'");
return $a;
}
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
if (!class_exists($class)) {
require_once $GLOBALS['_PEAR_Command_objects'][$class];
}
if (!class_exists($class)) {
$a = PEAR::raiseError("unknown command `$command'");
return $a;
}
$ui =& PEAR_Command::getFrontendObject();
$obj = &new $class($ui, $config);
return $obj;
}
 
// }}}
// {{{ & getObject()
function &getObject($command)
{
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
if (!class_exists($class)) {
require_once $GLOBALS['_PEAR_Command_objects'][$class];
}
if (!class_exists($class)) {
return PEAR::raiseError("unknown command `$command'");
}
$ui =& PEAR_Command::getFrontendObject();
$config = &PEAR_Config::singleton();
$obj = &new $class($ui, $config);
return $obj;
}
 
// }}}
// {{{ & getFrontendObject()
 
/**
* Get instance of frontend object.
*
* @return object|PEAR_Error
* @static
*/
function &getFrontendObject()
{
$a = &PEAR_Frontend::singleton();
return $a;
}
 
// }}}
// {{{ & setFrontendClass()
 
/**
* Load current frontend class.
*
* @param string $uiclass Name of class implementing the frontend
*
* @return object the frontend object, or a PEAR error
* @static
*/
function &setFrontendClass($uiclass)
{
$a = &PEAR_Frontend::setFrontendClass($uiclass);
return $a;
}
 
// }}}
// {{{ setFrontendType()
 
/**
* Set current frontend.
*
* @param string $uitype Name of the frontend type (for example "CLI")
*
* @return object the frontend object, or a PEAR error
* @static
*/
function setFrontendType($uitype)
{
$uiclass = 'PEAR_Frontend_' . $uitype;
return PEAR_Command::setFrontendClass($uiclass);
}
 
// }}}
// {{{ registerCommands()
 
/**
* Scan through the Command directory looking for classes
* and see what commands they implement.
*
* @param bool (optional) if FALSE (default), the new list of
* commands should replace the current one. If TRUE,
* new entries will be merged with old.
*
* @param string (optional) where (what directory) to look for
* classes, defaults to the Command subdirectory of
* the directory from where this file (__FILE__) is
* included.
*
* @return bool TRUE on success, a PEAR error on failure
*
* @access public
* @static
*/
function registerCommands($merge = false, $dir = null)
{
$parser = new PEAR_XMLParser;
if ($dir === null) {
$dir = dirname(__FILE__) . '/Command';
}
if (!is_dir($dir)) {
return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory");
}
$dp = @opendir($dir);
if (empty($dp)) {
return PEAR::raiseError("registerCommands: opendir($dir) failed");
}
if (!$merge) {
$GLOBALS['_PEAR_Command_commandlist'] = array();
}
while ($entry = readdir($dp)) {
if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
continue;
}
$class = "PEAR_Command_".substr($entry, 0, -4);
$file = "$dir/$entry";
$parser->parse(file_get_contents($file));
$implements = $parser->getData();
// List of commands
if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
$GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . substr($entry, 0, -4) .
'.php';
}
foreach ($implements as $command => $desc) {
if ($command == 'attribs') {
continue;
}
if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
return PEAR::raiseError('Command "' . $command . '" already registered in ' .
'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
}
$GLOBALS['_PEAR_Command_commandlist'][$command] = $class;
$GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary'];
if (isset($desc['shortcut'])) {
$shortcut = $desc['shortcut'];
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) {
return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' .
'registered to command "' . $command . '" in class "' .
$GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
}
$GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command;
}
if (isset($desc['options']) && $desc['options']) {
foreach ($desc['options'] as $oname => $option) {
if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) {
return PEAR::raiseError('Option "' . $oname . '" short option "' .
$option['shortopt'] . '" must be ' .
'only 1 character in Command "' . $command . '" in class "' .
$class . '"');
}
}
}
}
}
ksort($GLOBALS['_PEAR_Command_shortcuts']);
ksort($GLOBALS['_PEAR_Command_commandlist']);
@closedir($dp);
return true;
}
 
// }}}
// {{{ getCommands()
 
/**
* Get the list of currently supported commands, and what
* classes implement them.
*
* @return array command => implementing class
*
* @access public
* @static
*/
function getCommands()
{
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
PEAR_Command::registerCommands();
}
return $GLOBALS['_PEAR_Command_commandlist'];
}
 
// }}}
// {{{ getShortcuts()
 
/**
* Get the list of command shortcuts.
*
* @return array shortcut => command
*
* @access public
* @static
*/
function getShortcuts()
{
if (empty($GLOBALS['_PEAR_Command_shortcuts'])) {
PEAR_Command::registerCommands();
}
return $GLOBALS['_PEAR_Command_shortcuts'];
}
 
// }}}
// {{{ getGetoptArgs()
 
/**
* Compiles arguments for getopt.
*
* @param string $command command to get optstring for
* @param string $short_args (reference) short getopt format
* @param array $long_args (reference) long getopt format
*
* @return void
*
* @access public
* @static
*/
function getGetoptArgs($command, &$short_args, &$long_args)
{
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
PEAR_Command::registerCommands();
}
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
}
if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
return null;
}
$obj = &PEAR_Command::getObject($command);
return $obj->getGetoptArgs($command, $short_args, $long_args);
}
 
// }}}
// {{{ getDescription()
 
/**
* Get description for a command.
*
* @param string $command Name of the command
*
* @return string command description
*
* @access public
* @static
*/
function getDescription($command)
{
if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) {
return null;
}
return $GLOBALS['_PEAR_Command_commanddesc'][$command];
}
 
// }}}
// {{{ getHelp()
 
/**
* Get help for command.
*
* @param string $command Name of the command to return help for
*
* @access public
* @static
*/
function getHelp($command)
{
$cmds = PEAR_Command::getCommands();
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
}
if (isset($cmds[$command])) {
$obj = &PEAR_Command::getObject($command);
return $obj->getHelp($command);
}
return false;
}
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Frontend.php
New file
0,0 → 1,186
<?php
/**
* PEAR_Frontend, the singleton-based frontend for user input/output
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Frontend.php,v 1.9 2006/03/03 13:13:07 pajoye Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* Which user interface class is being used.
* @var string class name
*/
$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI';
 
/**
* Instance of $_PEAR_Command_uiclass.
* @var object
*/
$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null;
 
/**
* Singleton-based frontend for PEAR user input/output
*
* Note that frontend classes must implement userConfirm(), and shoul implement
* displayFatalError() and outputData()
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Frontend extends PEAR
{
/**
* Retrieve the frontend object
* @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk
* @static
*/
function &singleton($type = null)
{
if ($type === null) {
if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) {
$a = false;
return $a;
}
return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
} else {
$a = PEAR_Frontend::setFrontendClass($type);
return $a;
}
}
 
/**
* Set the frontend class that will be used by calls to {@link singleton()}
*
* Frontends are expected to conform to the PEAR naming standard of
* _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php)
* @param string $uiclass full class name
* @return PEAR_Frontend
* @static
*/
function &setFrontendClass($uiclass)
{
if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) &&
is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) {
return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
}
if (!class_exists($uiclass)) {
$file = str_replace('_', '/', $uiclass) . '.php';
if (PEAR_Frontend::isIncludeable($file)) {
include_once $file;
}
}
if (class_exists($uiclass)) {
$obj = &new $uiclass;
// quick test to see if this class implements a few of the most
// important frontend methods
if (method_exists($obj, 'userConfirm')) {
$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj;
$GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass;
return $obj;
} else {
$err = PEAR::raiseError("not a frontend class: $uiclass");
return $err;
}
}
$err = PEAR::raiseError("no such class: $uiclass");
return $err;
}
 
/**
* Set the frontend class that will be used by calls to {@link singleton()}
*
* Frontends are expected to be a descendant of PEAR_Frontend
* @param PEAR_Frontend
* @return PEAR_Frontend
* @static
*/
function &setFrontendObject($uiobject)
{
if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) &&
is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) {
return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
}
if (!is_a($uiobject, 'PEAR_Frontend')) {
$err = PEAR::raiseError('not a valid frontend class: (' .
get_class($uiobject) . ')');
return $err;
}
// quick test to see if this class implements a few of the most
// important frontend methods
if (method_exists($uiobject, 'userConfirm')) {
$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject;
$GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject);
return $uiobject;
} else {
$err = PEAR::raiseError("not a value frontend class: (" . get_class($uiobject)
. ')');
return $err;
}
}
 
/**
* @param string $path relative or absolute include path
* @return boolean
* @static
*/
function isIncludeable($path)
{
if (file_exists($path) && is_readable($path)) {
return true;
}
$ipath = explode(PATH_SEPARATOR, ini_get('include_path'));
foreach ($ipath as $include) {
$test = realpath($include . DIRECTORY_SEPARATOR . $path);
if (!$test) { // support wrappers like phar (realpath just don't work with them)
$test = $include . DIRECTORY_SEPARATOR . $path;
}
if (file_exists($test) && is_readable($test)) {
return true;
}
}
return false;
}
 
/**
* @param PEAR_Config
*/
function setConfig(&$config)
{
}
 
/**
* This can be overridden to allow session-based temporary file management
*
* By default, all files are deleted at the end of a session. The web installer
* needs to be able to sustain a list over many sessions in order to support
* user interaction with install scripts
*/
function addTempFile($file)
{
$GLOBALS['_PEAR_Common_tempfiles'][] = $file;
}
 
function log($msg, $append_crlf = true)
{
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFileManager.php
New file
0,0 → 1,1595
<?php
//
// +------------------------------------------------------------------------+
// | PEAR :: Package File Manager |
// +------------------------------------------------------------------------+
// | Copyright (c) 2003-2004 Gregory Beaver |
// | Email cellog@phpdoc.org |
// +------------------------------------------------------------------------+
// | This source file is subject to version 3.00 of the PHP License, |
// | that is available at http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +------------------------------------------------------------------------+
// | Portions of this code based on phpDocumentor |
// | Web http://www.phpdoc.org |
// | Mirror http://phpdocu.sourceforge.net/ |
// +------------------------------------------------------------------------+
// $Id: PackageFileManager.php,v 1.42 2005/04/06 22:21:20 cellog Exp $
//
 
/**
* @package PEAR_PackageFileManager
*/
/**
* PEAR installer
*/
require_once 'PEAR/Common.php';
/**#@+
* Error Codes
*/
define('PEAR_PACKAGEFILEMANAGER_NOSTATE', 1);
define('PEAR_PACKAGEFILEMANAGER_NOVERSION', 2);
define('PEAR_PACKAGEFILEMANAGER_NOPKGDIR', 3);
define('PEAR_PACKAGEFILEMANAGER_NOBASEDIR', 4);
define('PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND', 5);
define('PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE', 6);
define('PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE', 7);
define('PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE', 8);
define('PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE', 9);
define('PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE', 10);
define('PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST', 11);
define('PEAR_PACKAGEFILEMANAGER_NOCVSENTRIES', 12);
define('PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST', 13);
define('PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS', 14);
define('PEAR_PACKAGEFILEMANAGER_NOPACKAGE', 15);
define('PEAR_PACKAGEFILEMANAGER_WRONG_MROLE', 16);
define('PEAR_PACKAGEFILEMANAGER_NOSUMMARY', 17);
define('PEAR_PACKAGEFILEMANAGER_NODESC', 18);
define('PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS', 19);
define('PEAR_PACKAGEFILEMANAGER_NO_FILES', 20);
define('PEAR_PACKAGEFILEMANAGER_IGNORED_EVERYTHING', 21);
define('PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE', 22);
define('PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE', 23);
define('PEAR_PACKAGEFILEMANAGER_INVALID_ROLE', 24);
define('PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE', 25);
define('PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED', 26);
define('PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO', 27);
/**#@-*/
/**
* Error messages
* @global array $GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS']
*/
$GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'] =
array(
'en' =>
array(
PEAR_PACKAGEFILEMANAGER_NOSTATE =>
'Release State (option \'state\') must by specified in PEAR_PackageFileManager setOptions (alpha|beta|stable)',
PEAR_PACKAGEFILEMANAGER_NOVERSION =>
'Release Version (option \'version\') must be specified in PEAR_PackageFileManager setOptions',
PEAR_PACKAGEFILEMANAGER_NOPKGDIR =>
'Package source base directory (option \'packagedirectory\') must be ' .
'specified in PEAR_PackageFileManager setOptions',
PEAR_PACKAGEFILEMANAGER_NOBASEDIR =>
'Package install base directory (option \'baseinstalldir\') must be ' .
'specified in PEAR_PackageFileManager setOptions',
PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND =>
'Base class "%s" can\'t be located',
PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE =>
'Base class "%s" can\'t be located in default or user-specified directories',
PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE =>
'Failed to write package.xml file to destination directory',
PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE =>
'Destination directory "%s" is unwritable',
PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE =>
'Failed to copy package.xml.tmp file to package.xml',
PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE =>
'Failed to open temporary file "%s" for writing',
PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST =>
'package.xml file path "%s" doesn\'t exist or isn\'t a directory',
PEAR_PACKAGEFILEMANAGER_NOCVSENTRIES =>
'Directory "%s" is not a CVS directory (it must have the CVS/Entries file)',
PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST =>
'Package source base directory "%s" doesn\'t exist or isn\'t a directory',
PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS =>
'Run $managerclass->setOptions() before any other methods',
PEAR_PACKAGEFILEMANAGER_NOPACKAGE =>
'Package Name (option \'package\') must by specified in PEAR_PackageFileManager '.
'setOptions to create a new package.xml',
PEAR_PACKAGEFILEMANAGER_NOSUMMARY =>
'Package Summary (option \'summary\') must by specified in PEAR_PackageFileManager' .
' setOptions to create a new package.xml',
PEAR_PACKAGEFILEMANAGER_NODESC =>
'Detailed Package Description (option \'description\') must be' .
' specified in PEAR_PackageFileManager setOptions to create a new package.xml',
PEAR_PACKAGEFILEMANAGER_WRONG_MROLE =>
'Maintainer role must be one of "%s", was "%s"',
PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS =>
'Add maintainers to a package before generating the package.xml',
PEAR_PACKAGEFILEMANAGER_NO_FILES =>
'No files found, check the path "%s"',
PEAR_PACKAGEFILEMANAGER_IGNORED_EVERYTHING =>
'No files left, check the path "%s" and ignore option "%s"',
PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE =>
'Package validation failed:%s%s',
PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE =>
'Replacement Type must be one of "%s", was passed "%s"',
PEAR_PACKAGEFILEMANAGER_INVALID_ROLE =>
'Invalid file role passed to addRole, must be one of "%s", was passed "%s"',
PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE =>
'addDependency had PHP as a package, use type="php"',
PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED =>
'path "%path%" contains CVS directory',
PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO =>
'PHP_Compat is not installed, cannot detect dependencies',
),
// other language translations go here
);
/**
* PEAR :: PackageFileManager updates the <filelist></filelist> section
* of a PEAR package.xml file to reflect the current files in
* preparation for a release.
*
* The PEAR_PackageFileManager class uses a plugin system to generate the
* list of files in a package. This allows both standard recursive
* directory parsing (plugin type file) and more intelligent options
* such as the CVS browser {@link PEAR_PackageFileManager_Cvs}, which
* grabs all files in a local CVS checkout to create the list, ignoring
* any other local files.
*
* Other options include specifying roles for file extensions (all .php
* files are role="php", for example), roles for directories (all directories
* named "tests" are given role="tests" by default), and exceptions.
* Exceptions are specific pathnames with * and ? wildcards that match
* a default role, but should have another. For example, perhaps
* a debug.tpl template would normally be data, but should be included
* in the docs role. Along these lines, to exclude files entirely,
* use the ignore option.
*
* Required options for a release include version, baseinstalldir, state,
* and packagedirectory (the full path to the local location of the
* package to create a package.xml file for)
*
* Example usage:
* <code>
* <?php
* require_once('PEAR/PackageFileManager.php');
* $packagexml = new PEAR_PackageFileManager;
* $e = $packagexml->setOptions(
* array('baseinstalldir' => 'PhpDocumentor',
* 'version' => '1.2.1',
* 'packagedirectory' => 'C:/Web Pages/chiara/phpdoc2/',
* 'state' => 'stable',
* 'filelistgenerator' => 'cvs', // generate from cvs, use file for directory
* 'notes' => 'We\'ve implemented many new and exciting features',
* 'ignore' => array('TODO', 'tests/'), // ignore TODO, all files in tests/
* 'installexceptions' => array('phpdoc' => '/*'), // baseinstalldir ="/" for phpdoc
* 'dir_roles' => array('tutorials' => 'doc'),
* 'exceptions' => array('README' => 'doc', // README would be data, now is doc
* 'PHPLICENSE.txt' => 'doc'))); // same for the license
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* die();
* }
* $e = $test->addPlatformException('pear-phpdoc.bat', 'windows');
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* exit;
* }
* $packagexml->addRole('pkg', 'doc'); // add a new role mapping
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* exit;
* }
* // replace @PHP-BIN@ in this file with the path to php executable! pretty neat
* $e = $test->addReplacement('pear-phpdoc', 'pear-config', '@PHP-BIN@', 'php_bin');
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* exit;
* }
* $e = $test->addReplacement('pear-phpdoc.bat', 'pear-config', '@PHP-BIN@', 'php_bin');
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* exit;
* }
* // note use of {@link debugPackageFile()} - this is VERY important
* if (isset($_GET['make']) || (isset($_SERVER['argv'][2]) &&
* $_SERVER['argv'][2] == 'make')) {
* $e = $packagexml->writePackageFile();
* } else {
* $e = $packagexml->debugPackageFile();
* }
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* die();
* }
* ?>
* </code>
*
* In addition, a package.xml file can now be generated from
* scratch, with the usage of new options package, summary, description, and
* the use of the {@link addMaintainer()} method
* @package PEAR_PackageFileManager
*/
class PEAR_PackageFileManager
{
/**
* Format: array(array(regexp-ready string to search for whole path,
* regexp-ready string to search for basename of ignore strings),...)
* @var false|array
* @access private
*/
var $_ignore = false;
/**
* Contents of the package.xml file
* @var string
* @access private
*/
var $_packageXml = false;
/**
* Contents of the original package.xml file, if any
* @var string
* @access private
*/
var $_oldPackageXml = false;
/**
* @access private
* @var PEAR_Common
*/
var $_pear;
/**
* @access private
* @var array
*/
var $_warningStack = array();
 
/**
* flag used to determine whether to use PHP_CompatInfo to detect deps
* @var boolean
* @access private
*/
var $_detectDependencies = false;
/**
* @access private
* @var string
*/
var $_options = array(
'packagefile' => 'package.xml',
'doctype' => 'http://pear.php.net/dtd/package-1.0',
'filelistgenerator' => 'file',
'license' => 'PHP License',
'changelogoldtonew' => true,
'roles' =>
array(
'php' => 'php',
'html' => 'doc',
'*' => 'data',
),
'dir_roles' =>
array(
'docs' => 'doc',
'examples' => 'doc',
'tests' => 'test',
),
'exceptions' => array(),
'installexceptions' => array(),
'installas' => array(),
'platformexceptions' => array(),
'scriptphaseexceptions' => array(),
'ignore' => array(),
'include' => false,
'deps' => false,
'maintainers' => false,
'notes' => '',
'changelognotes' => false,
'outputdirectory' => false,
'pathtopackagefile' => false,
'lang' => 'en',
'configure_options' => array(),
'replacements' => array(),
'pearcommonclass' => false,
'simpleoutput' => false,
'addhiddenfiles' => false,
'cleardependencies' => false,
);
/**
* Does nothing, use setOptions
*
* The constructor is not used in order to be able to
* return a PEAR_Error from setOptions
* @see setOptions()
*/
function PEAR_PackageFileManager()
{
}
/**
* Set package.xml generation options
*
* The options array is indexed as follows:
* <code>
* $options = array('option_name' => <optionvalue>);
* </code>
*
* The documentation below simplifies this description through
* the use of option_name without quotes
*
* Configuration options:
* - lang: lang controls the language in which error messages are
* displayed. There are currently only English error messages,
* but any contributed will be added over time.<br>
* Possible values: en (default)
* - packagefile: the name of the packagefile, defaults to package.xml
* - pathtopackagefile: the path to an existing package file to read in,
* if different from the packagedirectory
* - packagedirectory: the path to the base directory of the package. For
* package PEAR_PackageFileManager, this path is
* /path/to/pearcvs/pear/PEAR_PackageFileManager where
* /path/to/pearcvs is a local path on your hard drive
* - outputdirectory: the path in which to place the generated package.xml
* by default, this is ignored, and the package.xml is
* created in the packagedirectory
* - filelistgenerator: the <filelist> section plugin which will be used.
* In this release, there are two generator plugins,
* file and cvs. For details, see the docs for these
* plugins
* - usergeneratordir: For advanced users. If you write your own filelist
* generator plugin, use this option to tell
* PEAR_PackageFileManager where to find the file that
* contains it. If the plugin is named foo, the class
* must be named PEAR_PackageFileManager_Foo
* no matter where it is located. By default, the Foo
* plugin is located in PEAR/PackageFileManager/Foo.php.
* If you pass /path/to/foo in this option, setOptions
* will look for PEAR_PackageFileManager_Foo in
* /path/to/foo/Foo.php
* - doctype: Specifies the DTD of the package.xml file. Default is
* http://pear.php.net/dtd/package-1.0
* - pearcommonclass: Specifies the name of the class to instantiate, default
* is PEAR_Common, but users can override this with a custom
* class that implements PEAR_Common's method interface
* - changelogoldtonew: True if the ChangeLog should list from oldest entry to
* newest. Set to false if you would like new entries first
* - simpleoutput: True if the package.xml should not contain md5sum or <provides />
* for readability
* - addhiddenfiles: True if you wish to add hidden files/directories that begin with .
* like .bashrc. This is only used by the File generator. The CVS
* generator will use all files in CVS regardless of format
*
* package.xml simple options:
* - baseinstalldir: The base directory to install this package in. For
* package PEAR_PackageFileManager, this is "PEAR", for
* package PEAR, this is "/"
* - license: The license this release is released under. Default is
* PHP License if left unspecified
* - notes: Release notes, any text describing what makes this release unique
* - changelognotes: notes for the changelog, this should be more detailed than
* the release notes. By default, PEAR_PackageFileManager uses
* the notes option for the changelog as well
* - version: The version number for this release. Remember the convention for
* numbering: initial alpha is between 0 and 1, add b<beta number> for
* beta as in 1.0b1, the integer portion of the version should specify
* backwards compatibility, as in 1.1 is backwards compatible with 1.0,
* but 2.0 is not backwards compatible with 1.10. Also note that 1.10
* is a greater release version than 1.1 (think of it as "one point ten"
* and "one point one"). Bugfix releases should be a third decimal as in
* 1.0.1, 1.0.2
* - package: [optional] Package name. Use this to create a new package.xml, or
* overwrite an existing one from another package used as a template
* - summary: [optional] Summary of package purpose
* - description: [optional] Description of package purpose. Note that the above
* three options are not optional when creating a new package.xml
* from scratch
*
* <b>WARNING</b>: all complex options that require a file path are case-sensitive
*
* package.xml complex options:
* - cleardependencies: since version 1.3.0, this option will erase any existing
* dependencies in the package.xml if set to true
* - ignore: an array of filenames, directory names, or wildcard expressions specifying
* files to exclude entirely from the package.xml. Wildcards are operating system
* wildcards * and ?. file*foo.php will exclude filefoo.php, fileabrfoo.php and
* filewho_is_thisfoo.php. file?foo.php will exclude fileafoo.php and will not
* exclude fileaafoo.php. test/ will exclude all directories and subdirectories of
* ANY directory named test encountered in directory parsing. *test* will exclude
* all files and directories that contain test in their name
* - include: an array of filenames, directory names, or wildcard expressions specifying
* files to include in the listing. All other files will be ignored.
* Wildcards are in the same format as ignore
* - roles: this is an array mapping file extension to install role. This
* specifies default behavior that can be overridden by the exceptions
* option and dir_roles option. use {@link addRole()} to add a new
* role to the pre-existing array
* - dir_roles: this is an array mapping directory name to install role. All
* files in a directory whose name matches the directory will be
* given the install role specified. Single files can be excluded
* from this using the exceptions option. The directory should be
* a relative path from the baseinstalldir, or "/" for the baseinstalldir
* - exceptions: specify file role for specific files. This array maps all files
* matching the exact name of a file to a role as in "file.ext" => "role"
* - deps: dependency array. Pass in an empty array to clear all dependencies, and use
* {@link addDependency()} to add new ones/replace existing ones
* - maintainers: maintainers array. Pass in an empty array to clear all maintainers, and
* use {@link addMaintainer()} to add a new maintainer/replace existing maintainer
* - installexceptions: array mapping of specific filenames to baseinstalldir values. Use
* this to force the installation of a file into another directory,
* such as forcing a script to be in the root scripts directory so that
* it will be in the path. The filename must be a relative path to the
* packagedirectory
* - platformexceptions: array mapping of specific filenames to the platform they should be
* installed on. Use this to specify unix-only files or windows-only
* files. The format of the platform string must be
* OS-version-cpu-extra if any more specific information is needed,
* and the OS must be in lower case as in "windows." The match is
* performed using a regular expression, but uses * and ? wildcards
* instead of .* and .?. Note that hpux/aix/irix/linux are all
* exclusive. To select non-windows, use (*ix|*ux)
* - scriptphaseexceptions: array mapping of scripts to their install phase. This can be
* one of: pre-install, post-install, pre-uninstall, post-uninstall,
* pre-build, post-build, pre-setup, or post-setup
* - installas: array mapping of specific filenames to the filename they should be installed as.
* Use this to specify new filenames for files that should be installed. This will
* often be used in conjunction with platformexceptions if there are two files for
* different OSes that must have the same name when installed.
* - replacements: array mapping of specific filenames to complex text search-and-replace that
* should be performed upon install. The format is:
* <pre>
* filename => array('type' => php-const|pear-config|package-info
* 'from' => text in file
* 'to' => name of variable)
* </pre>
* if type is php-const, then 'to' must be the name of a PHP Constant.
* If type is pear-config, then 'to' must be the name of a PEAR config
* variable accessible through a PEAR_Config class->get() method. If
* type is package-info, then 'to' must be the name of a section from
* the package.xml file used to install this file.
* - globalreplacements: a list of replacements that should be performed on every single file.
* The format is the same as replacements (since 1.4.0)
* - configure_options: array specifies build options for PECL packages (you should probably
* use PECL_Gen instead, but it's here for completeness)
* @see PEAR_PackageFileManager_File
* @see PEAR_PackageFileManager_CVS
* @return void|PEAR_Error
* @throws PEAR_PACKAGEFILEMANAGER_NOSTATE
* @throws PEAR_PACKAGEFILEMANAGER_NOVERSION
* @throws PEAR_PACKAGEFILEMANAGER_NOPKGDIR
* @throws PEAR_PACKAGEFILEMANAGER_NOBASEDIR
* @throws PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE
* @throws PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND
* @param array
*/
function setOptions($options = array(), $internal = false)
{
if (!$internal) {
if (!isset($options['state'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOSTATE);
}
if (!isset($options['version'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOVERSION);
}
}
if (!isset($options['packagedirectory']) && !$internal) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOPKGDIR);
} elseif (isset($options['packagedirectory'])) {
$options['packagedirectory'] = str_replace(DIRECTORY_SEPARATOR,
'/',
realpath($options['packagedirectory']));
if ($options['packagedirectory']{strlen($options['packagedirectory']) - 1} != '/') {
$options['packagedirectory'] .= '/';
}
}
if (isset($options['pathtopackagefile'])) {
$options['pathtopackagefile'] = str_replace(DIRECTORY_SEPARATOR,
'/',
realpath($options['pathtopackagefile']));
if ($options['pathtopackagefile']{strlen($options['pathtopackagefile']) - 1} != '/') {
$options['pathtopackagefile'] .= '/';
}
}
if (!isset($options['baseinstalldir']) && !$internal) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOBASEDIR);
}
$this->_options = array_merge($this->_options, $options);
if (!class_exists($this->_options['pearcommonclass'])) {
if ($this->_options['simpleoutput']) {
if ($this->isIncludeable('PEAR/PackageFile/Generator/v1.php')) {
include_once 'PEAR/PackageFileManager/SimpleGenerator.php';
$this->_options['pearcommonclass'] = 'PEAR_PackageFileManager_SimpleGenerator';
} else {
include_once 'PEAR/PackageFileManager/XMLOutput.php';
$this->_options['pearcommonclass'] = 'PEAR_PackageFileManager_XMLOutput';
}
} else {
$this->_options['pearcommonclass'] = 'PEAR_Common';
}
}
$path = ($this->_options['pathtopackagefile'] ?
$this->_options['pathtopackagefile'] : $this->_options['packagedirectory']);
$this->_options['filelistgenerator'] =
ucfirst(strtolower($this->_options['filelistgenerator']));
if (!$internal) {
if (PEAR::isError($res =
$this->_getExistingPackageXML($path, $this->_options['packagefile']))) {
return $res;
}
}
if (!class_exists('PEAR_PackageFileManager_' . $this->_options['filelistgenerator'])) {
// attempt to load the interface from the standard PEAR location
if ($this->isIncludeable('PEAR/PackageFileManager/' .
$this->_options['filelistgenerator'] . '.php')) {
include_once('PEAR/PackageFileManager/' .
$this->_options['filelistgenerator'] . '.php');
} elseif (isset($this->_options['usergeneratordir'])) {
// attempt to load from a user-specified directory
if (is_dir(realpath($this->_options['usergeneratordir']))) {
$this->_options['usergeneratordir'] =
str_replace(DIRECTORY_SEPARATOR,
'/',
realpath($this->_options['usergeneratordir']));
if ($this->_options['usergeneratordir']{strlen($this->_options['usergeneratordir'])
- 1} != '/') {
$this->_options['usergeneratordir'] .= '/';
}
} else {
$this->_options['usergeneratordir'] = '////';
}
if (file_exists($this->_options['usergeneratordir'] .
$this->_options['filelistgenerator'] . '.php') &&
is_readable($this->_options['usergeneratordir'] .
$this->_options['filelistgenerator'] . '.php')) {
include_once($this->_options['usergeneratordir'] .
$this->_options['filelistgenerator'] . '.php');
}
if (!class_exists('PEAR_PackageFileManager_' . $this->_options['filelistgenerator'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE,
'PEAR_PackageFileManager_' . $this->_options['filelistgenerator']);
}
} else {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND,
'PEAR_PackageFileManager_' . $this->_options['filelistgenerator']);
}
}
}
 
/**
* Import options from an existing package.xml
*
* @return true|PEAR_Error
*/
function importOptions($packagefile, $options = array())
{
$options['cleardependencies'] = $options['deps'] = $options['maintainers'] = false;
$this->setOptions($options, true);
if (PEAR::isError($res = $this->_getExistingPackageXML(dirname($packagefile) .
DIRECTORY_SEPARATOR, basename($packagefile)))) {
return $res;
}
$this->_options['package'] = $this->_oldPackageXml['package'];
$this->_options['summary'] = $this->_oldPackageXml['summary'];
$this->_options['description'] = $this->_oldPackageXml['description'];
$this->_options['date'] = $this->_oldPackageXml['release_date'];
$this->_options['version'] = $this->_oldPackageXml['version'];
$this->_options['license'] = $this->_oldPackageXml['release_license'];
$this->_options['state'] = $this->_oldPackageXml['release_state'];
$this->_options['notes'] = $this->_oldPackageXml['release_notes'];
if (isset($this->_oldPackagexml['release_deps'])) {
$this->_options['deps'] = $this->_oldPackageXml['release_deps'];
}
$this->_options['maintainers'] = $this->_oldPackageXml['maintainers'];
return true;
}
 
/**
* Get the existing options
* @return array
*/
function getOptions()
{
return $this->_options;
}
 
/**
* Add an extension/role mapping to the role mapping option
*
* Roles influence both where a file is installed and how it is installed.
* Files with role="data" are in a completely different directory hierarchy
* from the program files of role="php"
*
* In PEAR 1.3b2, these roles are
* - php (most common)
* - data
* - doc
* - test
* - script (gives the file an executable attribute)
* - src
* @param string file extension
* @param string role
* @throws PEAR_PACKAGEFILEMANAGER_INVALID_ROLE
*/
function addRole($extension, $role)
{
$roles = call_user_func(array($this->_options['pearcommonclass'], 'getfileroles'));
if (!in_array($role, $roles)) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_ROLE, implode($roles, ', '), $role);
}
$this->_options['roles'][$extension] = $role;
}
/**
* Add an install-time platform conditional install for a file
*
* The format of the platform string must be
* OS-version-cpu-extra if any more specific information is needed,
* and the OS must be in lower case as in "windows." The match is
* performed using a regular expression, but uses * and ? wildcards
* instead of .* and .?. Note that hpux/aix/irix/linux are all
* exclusive. To select non-windows, use (*ix|*ux)
*
* This information is based on eyeing the source for OS/Guess.php, so
* if you are unsure of what to do, read that file.
* @param string relative path of file (relative to packagedirectory option)
* @param string platform descriptor string
*/
function addPlatformException($path, $platform)
{
if (!isset($this->_options['platformexceptions'])) {
$this->_options['platformexceptions'] = array();
}
$this->_options['platformexceptions'][$path] = $platform;
}
 
/**
* Add a replacement option for all files
*
* This sets an install-time complex search-and-replace function
* allowing the setting of platform-specific variables in all
* installed files.
*
* if $type is php-const, then $to must be the name of a PHP Constant.
* If $type is pear-config, then $to must be the name of a PEAR config
* variable accessible through a {@link PEAR_Config::get()} method. If
* type is package-info, then $to must be the name of a section from
* the package.xml file used to install this file.
* @param string relative path of file (relative to packagedirectory option)
* @param string variable type, either php-const, pear-config or package-info
* @param string text to replace in the source file
* @param string variable name to use for replacement
* @throws PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE
*/
function addGlobalReplacement($type, $from, $to)
{
if (!isset($this->_options['globalreplacements'])) {
$this->_options['globalreplacements'] = array();
}
$types = call_user_func(array($this->_options['pearcommonclass'], 'getreplacementtypes'));
if (!in_array($type, $types)) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE,
implode($types, ', '), $type);
}
$this->_options['globalreplacements'][] =
array('type' => $type, 'from' => $from, 'to' => $to);
}
 
/**
* Add a replacement option for a file
*
* This sets an install-time complex search-and-replace function
* allowing the setting of platform-specific variables in an
* installed file.
*
* if $type is php-const, then $to must be the name of a PHP Constant.
* If $type is pear-config, then $to must be the name of a PEAR config
* variable accessible through a {@link PEAR_Config::get()} method. If
* type is package-info, then $to must be the name of a section from
* the package.xml file used to install this file.
* @param string relative path of file (relative to packagedirectory option)
* @param string variable type, either php-const, pear-config or package-info
* @param string text to replace in the source file
* @param string variable name to use for replacement
* @throws PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE
*/
function addReplacement($path, $type, $from, $to)
{
if (!isset($this->_options['replacements'])) {
$this->_options['replacements'] = array();
}
$types = call_user_func(array($this->_options['pearcommonclass'], 'getreplacementtypes'));
if (!in_array($type, $types)) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE,
implode($types, ', '), $type);
}
$this->_options['replacements'][$path][] = array('type' => $type, 'from' => $from, 'to' => $to);
}
/**
* Add a maintainer to the list of maintainers.
*
* Every maintainer must have a valid account at pear.php.net. The
* first parameter is the account name (for instance, cellog is the
* handle for Greg Beaver at pear.php.net). Every maintainer has
* one of four possible roles:
* - lead: the primary maintainer
* - developer: an important developer on the project
* - contributor: self-explanatory
* - helper: ditto
*
* Finally, specify the name and email of the maintainer
* @param string username on pear.php.net of maintainer
* @param lead|developer|contributor|helper role of maintainer
* @param string full name of maintainer
* @param string email address of maintainer
*/
function addMaintainer($handle, $role, $name, $email)
{
if (!$this->_packageXml) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
if (!in_array($role, $GLOBALS['_PEAR_Common_maintainer_roles'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_WRONG_MROLE,
implode(', ', call_user_func(array($this->_options['pearcommonclass'],
'getUserRoles'))),
$role);
}
if (!isset($this->_packageXml['maintainers'])) {
$this->_packageXml['maintainers'] = array();
}
$found = false;
foreach($this->_packageXml['maintainers'] as $index => $maintainer) {
if ($maintainer['handle'] == $handle) {
$found = $index;
break;
}
}
$maintainer =
array('handle' => $handle, 'role' => $role, 'name' => $name, 'email' => $email);
if ($found !== false) {
$this->_packageXml['maintainers'][$found] = $maintainer;
} else {
$this->_packageXml['maintainers'][] = $maintainer;
}
}
/**
* Add an install-time configuration option for building of source
*
* This option is only useful to PECL projects that are built upon
* installation
* @param string name of the option
* @param string prompt to display to the user
* @param string default value
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
* @return void|PEAR_Error
*/
function addConfigureOption($name, $prompt, $default = null)
{
if (!$this->_packageXml) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
if (!isset($this->_packageXml['configure_options'])) {
$this->_packageXml['configure_options'] = array();
}
$found = false;
foreach($this->_packageXml['configure_options'] as $index => $option) {
if ($option['name'] == $name) {
$found = $index;
break;
}
}
$option = array('name' => $name, 'prompt' => $prompt);
if (isset($default)) {
$option['default'] = $default;
}
if ($found !== false) {
$this->_packageXml['configure_options'][$found] = $option;
} else {
$this->_packageXml['configure_options'][] = $option;
}
}
 
/**
* @return void|PEAR_Error
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
*/
function detectDependencies()
{
if (!$this->_packageXml) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
if (!$this->isIncludeable('PHP/CompatInfo.php')) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_PHP_COMPAT_NOT_INSTALLED);
} else {
if (include_once('PHP/CompatInfo.php')) {
$this->_detectDependencies = true;
} else {
$this->raiseError(PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO);
}
}
}
 
function isIncludeable($file)
{
if (!defined('PATH_SEPARATOR')) {
define('PATH_SEPARATOR', strtolower(substr(PHP_OS, 0, 3)) == 'win' ? ';' : ':');
}
foreach (explode(PATH_SEPARATOR, ini_get('include_path')) as $path) {
if (file_exists($path . DIRECTORY_SEPARATOR . $file) &&
is_readable($path . DIRECTORY_SEPARATOR . $file)) {
return true;
}
}
return false;
}
 
/**
* Add a dependency on another package, or an extension/php
*
* This will overwrite an existing dependency if it is found. In
* other words, if a dependency on PHP 4.1.0 exists, and
* addDependency('php', '4.3.0', 'ge', 'php') is called, the existing
* dependency on PHP 4.1.0 will be overwritten with the new one on PHP 4.3.0
* @param string Dependency element name
* @param string Dependency version
* @param string A specific operator for the version, this can be one of:
* 'has', 'not', 'lt', 'le', 'eq', 'ne', 'ge', or 'gt'
* @param string Dependency type. This can be one of:
* 'pkg', 'ext', 'php', 'prog', 'os', 'sapi', or 'zend'
* @param boolean true if dependency is optional
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
* @throws PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE
* @return void|PEAR_Error
*/
function addDependency($name, $version = false, $operator = 'ge', $type = 'pkg', $optional = false)
{
if (!$this->_packageXml) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
if ((strtolower($name) == 'php') && (strtolower($type) == 'pkg')) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE);
}
if (!isset($this->_packageXml['release_deps']) || !is_array($this->_packageXml['release_deps'])) {
$this->_packageXml['release_deps'] = array();
}
$found = false;
foreach($this->_packageXml['release_deps'] as $index => $dep) {
if ($type == 'php') {
if ($dep['type'] == 'php') {
$found = $index;
break;
}
} else {
if (isset($dep['name']) && $dep['name'] == $name && $dep['type'] == $type) {
$found = $index;
break;
}
}
}
$dep =
array(
'name' => $name,
'type' => $type);
if ($type == 'php') {
unset($dep['name']);
}
if ($operator) {
$dep['rel'] = $operator;
if ($dep['rel'] != 'has' && $version) {
$dep['version'] = $version;
}
}
if ($optional) {
$dep['optional'] = 'yes';
} else {
$dep['optional'] = 'no';
}
 
if ($found !== false) {
$this->_packageXml['release_deps'][$found] = $dep; // overwrite existing dependency
} else {
$this->_packageXml['release_deps'][] = $dep; // add new dependency
}
}
 
/**
* Writes the package.xml file out with the newly created <release></release> tag
*
* ALWAYS use {@link debugPackageFile} to verify that output is correct before
* overwriting your package.xml
* @param boolean null if no debugging, true if web interface, false if command-line
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
* @throws PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS
* @throws PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE
* @throws PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE
* @throws PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE
* @throws PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE
* @return void|PEAR_Error
*/
function writePackageFile($debuginterface = null)
{
if (!$this->_packageXml) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
if (!isset($this->_packageXml['maintainers']) || empty($this->_packageXml['maintainers'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS);
}
extract($this->_options);
$date = date('Y-m-d');
if (isset($package)) {
$this->_packageXml['package'] = $package;
}
if (isset($summary)) {
$this->_packageXml['summary'] = $summary;
}
if (isset($description)) {
$this->_packageXml['description'] = $description;
}
$this->_packageXml['release_date'] = $date;
$this->_packageXml['version'] = $version;
$this->_packageXml['release_license'] = $license;
$this->_packageXml['release_state'] = $state;
$this->_packageXml['release_notes'] = $notes;
$PEAR_Common = $this->_options['pearcommonclass'];
$this->_pear = new $PEAR_Common;
if (method_exists($this->_pear, 'setPackageFileManager')) {
$this->_pear->setPackageFileManager($this);
}
$this->_packageXml['filelist'] = $this->_getFileList();
$warnings = $this->getWarnings();
if (count($warnings)) {
$nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n");
foreach($warnings as $errmsg) {
echo 'WARNING: ' . $errmsg['message'] . $nl;
}
}
if (PEAR::isError($this->_packageXml['filelist'])) {
return $this->_packageXml['filelist'];
}
if (isset($this->_pear->pkginfo['provides'])) {
$this->_packageXml['provides'] = $this->_pear->pkginfo['provides'];
}
if ($this->_options['simpleoutput']) {
unset($this->_packageXml['provides']);
}
$this->_packageXml['release_deps'] = $this->_getDependencies();
$this->_updateChangeLog();
$common = &$this->_pear;
$warnings = $errors = array();
if (method_exists($common, 'setPackageFileManagerOptions')) {
$common->setPackageFileManagerOptions($this->_options);
}
$packagexml = $common->xmlFromInfo($this->_packageXml);
$common->validatePackageInfo($packagexml, $warnings, $errors,
$this->_options['packagedirectory']);
if (count($errors)) {
$ret = '';
$nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n");
foreach($errors as $errmsg) {
$ret .= $errmsg . $nl;
}
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE, $nl, $ret);
}
if (count($warnings)) {
$nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n");
foreach($warnings as $errmsg) {
echo $errmsg . $nl;
}
}
if (!strpos($packagexml, '<!DOCTYPE')) {
// hack to fix pear
$packagexml = str_replace('<package version="1.0">',
'<!DOCTYPE package SYSTEM "' . $this->_options['doctype'] .
"\">\n<package version=\"1.0\">",
$packagexml);
}
if (isset($debuginterface)) {
if ($debuginterface) {
echo '<pre>' . htmlentities($packagexml) . '</pre>';
} else {
echo $packagexml;
}
return true;
}
$outputdir = ($this->_options['outputdirectory'] ?
$this->_options['outputdirectory'] : $this->_options['packagedirectory']);
if ((file_exists($outputdir . $this->_options['packagefile']) &&
is_writable($outputdir . $this->_options['packagefile']))
||
@touch($outputdir . $this->_options['packagefile'])) {
if ($fp = @fopen($outputdir . $this->_options['packagefile'] . '.tmp', "w")) {
$written = @fwrite($fp, $packagexml);
@fclose($fp);
if ($written === false) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE);
}
if (!@copy($outputdir . $this->_options['packagefile'] . '.tmp',
$outputdir . $this->_options['packagefile'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE);
} else {
@unlink($outputdir . $this->_options['packagefile'] . '.tmp');
return true;
}
} else {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE,
$outputdir . $this->_options['packagefile'] . '.tmp');
}
} else {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE, $outputdir);
}
}
/**
* ALWAYS use this to test output before overwriting your package.xml!!
*
* This method instructs writePackageFile() to simply print the package.xml
* to output, either command-line or web-friendly (this is automatic
* based on the value of php_sapi_name())
* @uses writePackageFile() calls with the debug parameter set based on
* whether it is called from the command-line or web interface
*/
function debugPackageFile()
{
$webinterface = php_sapi_name() != 'cli';
return $this->writePackageFile($webinterface);
}
/**
* Store a warning on the warning stack
*/
function pushWarning($code, $info)
{
$this->_warningStack[] = array('code' => $code,
'message' => $this->_getMessage($code, $info));
}
/**
* Retrieve the list of warnings
* @return array
*/
function getWarnings()
{
$a = $this->_warningStack;
$this->_warningStack = array();
return $a;
}
/**
* Retrieve an error message from a code
* @access private
* @return string Error message
*/
function _getMessage($code, $info)
{
$msg = $GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'][$this->_options['lang']][$code];
foreach ($info as $name => $value) {
$msg = str_replace('%' . $name . '%', $value, $msg);
}
return $msg;
}
/**
* Utility function to shorten error generation code
*
* {@source}
* @return PEAR_Error
* @static
*/
function raiseError($code, $i1 = '', $i2 = '')
{
return PEAR::raiseError('PEAR_PackageFileManager Error: ' .
sprintf($GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'][$this->_options['lang']][$code],
$i1, $i2), $code);
}
/**
* Uses {@link PEAR_Common::analyzeSourceCode()} and {@link PEAR_Common::buildProvidesArray()}
* to create the <provides></provides> section of the package.xml
* @param PEAR_Common
* @param string path to source file
* @access private
*/
function _addProvides(&$pear, $file)
{
if (!($a = $pear->analyzeSourceCode($file))) {
return;
} else {
$pear->buildProvidesArray($a);
}
}
/**
* @uses getDirTag() generate the xml from the array
* @return string
* @access private
*/
function _getFileList()
{
$generatorclass = 'PEAR_PackageFileManager_' . $this->_options['filelistgenerator'];
$generator = new $generatorclass($this, $this->_options);
if ($this->_options['simpleoutput'] && is_a($this->_pear, 'PEAR_Common')) {
return $this->_getSimpleDirTag($this->_struc = $generator->getFileList());
}
return $this->_getDirTag($this->_struc = $generator->getFileList());
}
/**
* Recursively generate the <filelist> section's <dir> and <file> tags, but with
* simple human-readable output
* @param array|PEAR_Error the sorted directory structure, or an error
* from filelist generation
* @param false|string whether the parent directory has a role this should
* inherit
* @param integer indentation level
* @return array|PEAR_Error
* @access private
*/
function _getSimpleDirTag($struc, $role = false, $_curdir = '')
{
if (PEAR::isError($struc)) {
return $struc;
}
extract($this->_options);
$ret = array();
foreach($struc as $dir => $files) {
if (false && $dir === '/') {
// global directory role? overrides all exceptions except file exceptions
if (isset($dir_roles['/'])) {
$role = $dir_roles['/'];
}
return array(
'baseinstalldir' => $this->_options['baseinstalldir'],
'##files' => $this->_getSimpleDirTag($struc[$dir], $role, ''),
'name' => '/');
} else {
if (!isset($files['file'])) {
if (isset($dir_roles[$_curdir . $dir])) {
$myrole = $dir_roles[$_curdir . $dir];
} else {
$myrole = $role;
}
$ret[$dir] = array();
if ($dir == '/') {
$ret[$dir]['baseinstalldir'] = $this->_options['baseinstalldir'];
}
$ret[$dir]['name'] = $dir;
$recurdir = ($_curdir == '') ? $dir . '/' : $_curdir . $dir . '/';
if ($recurdir == '//') {
$recurdir = '';
}
$ret[$dir]['##files'] = $this->_getSimpleDirTag($files, $myrole, $recurdir);
} else {
$myrole = '';
if (!$role)
{
$myrole = false;
if (isset($exceptions[$files['path']])) {
$myrole = $exceptions[$files['path']];
} elseif (isset($roles[$files['ext']])) {
$myrole = $roles[$files['ext']];
} else {
$myrole = $roles['*'];
}
} else {
$myrole = $role;
if (isset($exceptions[$files['path']])) {
$myrole = $exceptions[$files['path']];
}
}
$test = explode('/', $files['path']);
foreach ($test as $subpath) {
if ($subpath == 'CVS') {
$this->pushWarning(PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED,
array('path' => $files['path']));
}
}
$ret[$files['file']] = array('role' => $myrole);
if (isset($installexceptions[$files['path']])) {
$ret[$files['file']]['baseinstalldir'] =
$installexceptions[$files['path']];
}
if (isset($platformexceptions[$files['path']])) {
$ret[$files['file']]['platform'] = $platformexceptions[$files['path']];
}
if (isset($installas[$files['path']])) {
$ret[$files['file']]['install-as'] = $installas[$files['path']];
}
if (isset($replacements[$files['path']])) {
$ret[$files['file']]['replacements'] = $replacements[$files['path']];
}
if (isset($globalreplacements)) {
if (!isset($ret[$files['file']]['replacements'])) {
$ret[$files['file']]['replacements'] = array();
}
$ret[$files['file']]['replacements'] = array_merge(
$ret[$files['file']]['replacements'], $globalreplacements);
}
}
}
}
return $ret;
}
/**
* Recursively generate the <filelist> section's <dir> and <file> tags
* @param array|PEAR_Error the sorted directory structure, or an error
* from filelist generation
* @param false|string whether the parent directory has a role this should
* inherit
* @param integer indentation level
* @return array|PEAR_Error
* @access private
*/
function _getDirTag($struc, $role=false, $_curdir = '')
{
if (PEAR::isError($struc)) {
return $struc;
}
extract($this->_options);
$ret = array();
foreach($struc as $dir => $files) {
if ($dir === '/') {
// global directory role? overrides all exceptions except file exceptions
if (isset($dir_roles['/'])) {
$role = $dir_roles['/'];
}
return $this->_getDirTag($struc[$dir], $role, '');
} else {
if (!isset($files['file'])) {
$myrole = '';
if (isset($dir_roles[$_curdir . $dir])) {
$myrole = $dir_roles[$_curdir . $dir];
} elseif ($role) {
$myrole = $role;
}
$ret = array_merge($ret, $this->_getDirTag($files, $myrole, $_curdir . $dir . '/'));
} else {
$myrole = '';
if (!$role)
{
$myrole = false;
if (isset($exceptions[$files['path']])) {
$myrole = $exceptions[$files['path']];
} elseif (isset($roles[$files['ext']])) {
$myrole = $roles[$files['ext']];
} else {
$myrole = $roles['*'];
}
} else {
$myrole = $role;
if (isset($exceptions[$files['path']])) {
$myrole = $exceptions[$files['path']];
}
}
if (isset($installexceptions[$files['path']])) {
$bi = $installexceptions[$files['path']];
} else {
$bi = $this->_options['baseinstalldir'];
}
$test = explode('/', $files['path']);
foreach ($test as $subpath) {
if ($subpath == 'CVS') {
$this->pushWarning(PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED, array('path' => $files['path']));
}
}
$ret[$files['path']] =
array('role' => $myrole,
'baseinstalldir' => $bi,
);
if (!isset($this->_options['simpleoutput'])) {
$md5sum = @md5_file($this->_options['packagedirectory'] . $files['path']);
if (!empty($md5sum)) {
$ret[$files['path']]['md5sum'] = $md5sum;
}
} elseif (isset($ret[$files['path']]['md5sum'])) {
unset($ret[$files['path']]['md5sum']);
}
if (isset($platformexceptions[$files['path']])) {
$ret[$files['path']]['platform'] = $platformexceptions[$files['path']];
}
if (isset($installas[$files['path']])) {
$ret[$files['path']]['install-as'] = $installas[$files['path']];
}
if (isset($replacements[$files['path']])) {
$ret[$files['path']]['replacements'] = $replacements[$files['path']];
}
if (isset($globalreplacements)) {
if (!isset($ret[$files['path']]['replacements'])) {
$ret[$files['path']]['replacements'] = array();
}
$ret[$files['path']]['replacements'] = array_merge(
$ret[$files['path']]['replacements'], $globalreplacements);
}
if ($myrole == 'php' && !$this->_options['simpleoutput']) {
$this->_addProvides($this->_pear, $files['fullpath']);
}
}
}
}
return $ret;
}
 
/**
* @param array
* @access private
*/
function _traverseFileArray($files, &$ret) {
foreach ($files as $file) {
if (!isset($file['fullpath'])) {
$this->_traverseFileArray($file, $ret);
} else {
$ret[] = $file['fullpath'];
}
}
}
 
/**
* Retrieve the 'deps' option passed to the constructor
* @access private
* @return array
*/
function _getDependencies()
{
if ($this->_detectDependencies) {
$this->_traverseFileArray($this->_struc, $ret);
$compatinfo = new PHP_CompatInfo();
$info = $compatinfo->parseArray($ret);
$ret = $this->addDependency('php',$info['version'],'ge','php',false);
if (is_a($ret, 'PEAR_Error')) {
return $ret;
}
foreach ($info['extensions'] as $ext) {
$this->addDependency($ext, '', 'has', 'ext', false);
}
}
if (isset($this->_packageXml['release_deps']) &&
is_array($this->_packageXml['release_deps'])) {
return $this->_packageXml['release_deps'];
} else {
return array();
}
}
 
/**
* Creates a changelog entry with the current release
* notes and dates, or overwrites a previous creation
* @access private
*/
function _updateChangeLog()
{
$curlog = $oldchangelog = false;
if (!isset($this->_packageXml['changelog'])) {
$changelog = array();
if (isset($this->_oldPackageXml['release_notes'])) {
$changelog['release_notes'] = $this->_oldPackageXml['release_notes'];
}
if (isset($this->_oldPackageXml['version'])) {
$changelog['version'] = $this->_oldPackageXml['version'];
}
if (isset($this->_oldPackageXml['release_date'])) {
$changelog['release_date'] = $this->_oldPackageXml['release_date'];
}
if (isset($this->_oldPackageXml['release_license'])) {
$changelog['release_license'] = $this->_oldPackageXml['release_license'];
}
if (isset($this->_oldPackageXml['release_state'])) {
$changelog['release_state'] = $this->_oldPackageXml['release_state'];
}
if (count($changelog)) {
$this->_packageXml['changelog'] = array($changelog);
} else {
$this->_packageXml['changelog'] = array();
}
} else {
if (isset($this->_oldPackageXml['release_notes'])) {
$oldchangelog['release_notes'] = $this->_oldPackageXml['release_notes'];
}
if (isset($this->_oldPackageXml['version'])) {
$oldchangelog['version'] = $this->_oldPackageXml['version'];
}
if (isset($this->_oldPackageXml['release_date'])) {
$oldchangelog['release_date'] = $this->_oldPackageXml['release_date'];
}
if (isset($this->_oldPackageXml['release_license'])) {
$oldchangelog['release_license'] = $this->_oldPackageXml['release_license'];
}
if (isset($this->_oldPackageXml['release_state'])) {
$oldchangelog['release_state'] = $this->_oldPackageXml['release_state'];
}
}
$hasoldversion = false;
foreach($this->_packageXml['changelog'] as $index => $changelog) {
if ($oldchangelog && isset($oldchangelog['version'])
&& strnatcasecmp($oldchangelog['version'], $changelog['version']) == 0) {
$hasoldversion = true;
}
if (isset($changelog['version']) && strnatcasecmp($changelog['version'], $this->_options['version']) == 0) {
$curlog = $index;
}
if (isset($this->_packageXml['changelog'][$index]['release_notes'])) {
$this->_packageXml['changelog'][$index]['release_notes'] = trim($changelog['release_notes']);
}
// the parsing of the release notes adds a \n for some reason
}
if (!$hasoldversion && $oldchangelog && count($oldchangelog)
&& $oldchangelog['version'] != $this->_options['version']) {
$this->_packageXml['changelog'][] = $oldchangelog;
}
$notes = ($this->_options['changelognotes'] ?
$this->_options['changelognotes'] : $this->_options['notes']);
$changelog = array('version' => $this->_options['version'],
'release_date' => date('Y-m-d'),
'release_license' => $this->_options['license'],
'release_state' => $this->_options['state'],
'release_notes' => $notes,
);
if ($curlog !== false) {
$this->_packageXml['changelog'][$curlog] = $changelog;
} else {
$this->_packageXml['changelog'][] = $changelog;
}
usort($this->_packageXml['changelog'], array($this, '_changelogsort'));
}
/**
* @static
* @access private
*/
function _changelogsort($a, $b)
{
if ($this->_options['changelogoldtonew']) {
$c = strtotime($a['release_date']);
$d = strtotime($b['release_date']);
$v1 = $a['version'];
$v2 = $b['version'];
} else {
$d = strtotime($a['release_date']);
$c = strtotime($b['release_date']);
$v2 = $a['version'];
$v1 = $b['version'];
}
if ($c - $d > 0) {
return 1;
} elseif ($c - $d < 0) {
return -1;
}
return version_compare($v1, $v2);
}
 
/**
* @return true|PEAR_Error
* @uses _generateNewPackageXML() if no package.xml is found, it
* calls this to create a new one
* @param string full path to package file
* @param string name of package file
* @throws PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST
* @access private
*/
function _getExistingPackageXML($path, $packagefile = 'package.xml')
{
if (is_string($path) && is_dir($path)) {
$contents = false;
if (file_exists($path . $packagefile)) {
$contents = file_get_contents($path . $packagefile);
}
if (!$contents) {
return $this->_generateNewPackageXML();
} else {
$PEAR_Common = $this->_options['pearcommonclass'];
if (!class_exists($PEAR_Common)) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
$common = new $PEAR_Common;
if (is_a($common, 'PEAR_Common')) {
$this->_oldPackageXml =
$this->_packageXml = $common->infoFromString($contents);
} else { // new way
require_once 'PEAR/PackageFile.php';
$z = &PEAR_Config::singleton();
$pkg = &new PEAR_PackageFile($z);
$pf = &$pkg->fromXmlString($contents, PEAR_VALIDATE_DOWNLOADING, $path . $packagefile);
if (PEAR::isError($pf)) {
return $pf;
}
if ($pf->getPackagexmlVersion() != '1.0') {
return PEAR::raiseError('PEAR_PackageFileManager can only manage ' .
'package.xml version 1.0, use PEAR_PackageFileManager_v2 for newer' .
' package files');
}
$this->_oldPackageXml =
$this->_packageXml = $pf->toArray();
}
if (PEAR::isError($this->_packageXml)) {
return $this->_packageXml;
}
if ($this->_options['cleardependencies']) {
$this->_packageXml['release_deps'] = $this->_options['deps'];
}
if ($this->_options['deps'] !== false) {
$this->_packageXml['release_deps'] = $this->_options['deps'];
} else {
if (isset($this->_packageXml['release_deps'])) {
$this->_options['deps'] = $this->_packageXml['release_deps'];
}
}
if ($this->_options['maintainers'] !== false) {
$this->_packageXml['maintainers'] = $this->_options['maintainers'];
} else {
$this->_options['maintainers'] = $this->_packageXml['maintainers'];
}
unset($this->_packageXml['filelist']);
unset($this->_packageXml['provides']);
}
return true;
} else {
if (!is_string($path)) {
$path = gettype($path);
}
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST,
$path);
}
}
/**
* Create the structure for a new package.xml
*
* @uses $_packageXml emulates reading in a package.xml
* by using the package, summary and description
* options
* @return true|PEAR_Error
* @access private
*/
function _generateNewPackageXML()
{
$this->_oldPackageXml = false;
if (!isset($this->_options['package'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOPACKAGE);
}
if (!isset($this->_options['summary'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOSUMMARY);
}
if (!isset($this->_options['description'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NODESC);
}
$this->_packageXml = array();
$this->_packageXml['package'] = $this->_options['package'];
$this->_packageXml['summary'] = $this->_options['summary'];
$this->_packageXml['description'] = $this->_options['description'];
$this->_packageXml['changelog'] = array();
if ($this->_options['deps'] !== false) {
$this->_packageXml['release_deps'] = $this->_options['deps'];
} else {
$this->_packageXml['release_deps'] = $this->_options['deps'] = array();
}
if ($this->_options['maintainers'] !== false) {
$this->_packageXml['maintainers'] = $this->_options['maintainers'];
} else {
$this->_packageXml['maintainers'] = $this->_options['maintainers'] = array();
}
return true;
}
}
 
if (!function_exists('file_get_contents')) {
/**
* @ignore
*/
function file_get_contents($path, $use_include_path = null, $context = null)
{
$a = @file($path, $use_include_path, $context);
if (is_array($a)) {
return implode('', $a);
} else {
return false;
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Builder.php
New file
0,0 → 1,479
<?php
/**
* PEAR_Builder for building PHP extensions (PECL packages)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Builder.php,v 1.31 2007/01/10 05:32:51 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*
* TODO: log output parameters in PECL command line
* TODO: msdev path in configuration
*/
 
/**
* Needed for extending PEAR_Builder
*/
require_once 'PEAR/Common.php';
require_once 'PEAR/PackageFile.php';
/**
* Class to handle building (compiling) extensions.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since PHP 4.0.2
* @see http://pear.php.net/manual/en/core.ppm.pear-builder.php
*/
class PEAR_Builder extends PEAR_Common
{
// {{{ properties
 
var $php_api_version = 0;
var $zend_module_api_no = 0;
var $zend_extension_api_no = 0;
 
var $extensions_built = array();
 
/**
* @var string Used for reporting when it is not possible to pass function
* via extra parameter, e.g. log, msdevCallback
*/
var $current_callback = null;
 
// used for msdev builds
var $_lastline = null;
var $_firstline = null;
// }}}
// {{{ constructor
 
/**
* PEAR_Builder constructor.
*
* @param object $ui user interface object (instance of PEAR_Frontend_*)
*
* @access public
*/
function PEAR_Builder(&$ui)
{
parent::PEAR_Common();
$this->setFrontendObject($ui);
}
 
// }}}
 
// {{{ _build_win32()
 
/**
* Build an extension from source on windows.
* requires msdev
*/
function _build_win32($descfile, $callback = null)
{
if (is_object($descfile)) {
$pkg = $descfile;
$descfile = $pkg->getPackageFile();
} else {
$pf = &new PEAR_PackageFile($this->config, $this->debug);
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pkg)) {
return $pkg;
}
}
$dir = dirname($descfile);
$old_cwd = getcwd();
 
if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
return $this->raiseError("could not chdir to $dir");
}
// packages that were in a .tar have the packagefile in this directory
$vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
if (file_exists($dir) && is_dir($vdir)) {
if (chdir($vdir)) {
$dir = getcwd();
} else {
return $this->raiseError("could not chdir to " . realpath($vdir));
}
}
 
$this->log(2, "building in $dir");
 
$dsp = $pkg->getPackage().'.dsp';
if (!file_exists("$dir/$dsp")) {
return $this->raiseError("The DSP $dsp does not exist.");
}
// XXX TODO: make release build type configurable
$command = 'msdev '.$dsp.' /MAKE "'.$pkg->getPackage(). ' - Release"';
 
$err = $this->_runCommand($command, array(&$this, 'msdevCallback'));
if (PEAR::isError($err)) {
return $err;
}
 
// figure out the build platform and type
$platform = 'Win32';
$buildtype = 'Release';
if (preg_match('/.*?'.$pkg->getPackage().'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) {
$platform = $matches[1];
$buildtype = $matches[2];
}
 
if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/',$this->_lastline,$matches)) {
if ($matches[2]) {
// there were errors in the build
return $this->raiseError("There were errors during compilation.");
}
$out = $matches[1];
} else {
return $this->raiseError("Did not understand the completion status returned from msdev.exe.");
}
 
// msdev doesn't tell us the output directory :/
// open the dsp, find /out and use that directory
$dsptext = join(file($dsp),'');
 
// this regex depends on the build platform and type having been
// correctly identified above.
$regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'.
$pkg->getPackage().'\s-\s'.
$platform.'\s'.
$buildtype.'").*?'.
'\/out:"(.*?)"/is';
 
if ($dsptext && preg_match($regex,$dsptext,$matches)) {
// what we get back is a relative path to the output file itself.
$outfile = realpath($matches[2]);
} else {
return $this->raiseError("Could not retrieve output information from $dsp.");
}
// realpath returns false if the file doesn't exist
if ($outfile && copy($outfile, "$dir/$out")) {
$outfile = "$dir/$out";
}
 
$built_files[] = array(
'file' => "$outfile",
'php_api' => $this->php_api_version,
'zend_mod_api' => $this->zend_module_api_no,
'zend_ext_api' => $this->zend_extension_api_no,
);
 
return $built_files;
}
// }}}
 
// {{{ msdevCallback()
function msdevCallback($what, $data)
{
if (!$this->_firstline)
$this->_firstline = $data;
$this->_lastline = $data;
call_user_func($this->current_callback, $what, $data);
}
// }}}
 
// {{{ _harventInstDir
/**
* @param string
* @param string
* @param array
* @access private
*/
function _harvestInstDir($dest_prefix, $dirname, &$built_files)
{
$d = opendir($dirname);
if (!$d)
return false;
 
$ret = true;
while (($ent = readdir($d)) !== false) {
if ($ent{0} == '.')
continue;
 
$full = $dirname . DIRECTORY_SEPARATOR . $ent;
if (is_dir($full)) {
if (!$this->_harvestInstDir(
$dest_prefix . DIRECTORY_SEPARATOR . $ent,
$full, $built_files)) {
$ret = false;
break;
}
} else {
$dest = $dest_prefix . DIRECTORY_SEPARATOR . $ent;
$built_files[] = array(
'file' => $full,
'dest' => $dest,
'php_api' => $this->php_api_version,
'zend_mod_api' => $this->zend_module_api_no,
'zend_ext_api' => $this->zend_extension_api_no,
);
}
}
closedir($d);
return $ret;
}
 
// }}}
 
// {{{ build()
 
/**
* Build an extension from source. Runs "phpize" in the source
* directory, but compiles in a temporary directory
* (/var/tmp/pear-build-USER/PACKAGE-VERSION).
*
* @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or
* a PEAR_PackageFile object
*
* @param mixed $callback callback function used to report output,
* see PEAR_Builder::_runCommand for details
*
* @return array an array of associative arrays with built files,
* format:
* array( array( 'file' => '/path/to/ext.so',
* 'php_api' => YYYYMMDD,
* 'zend_mod_api' => YYYYMMDD,
* 'zend_ext_api' => YYYYMMDD ),
* ... )
*
* @access public
*
* @see PEAR_Builder::_runCommand
*/
function build($descfile, $callback = null)
{
$this->current_callback = $callback;
if (PEAR_OS == "Windows") {
return $this->_build_win32($descfile,$callback);
}
if (PEAR_OS != 'Unix') {
return $this->raiseError("building extensions not supported on this platform");
}
if (is_object($descfile)) {
$pkg = $descfile;
$descfile = $pkg->getPackageFile();
} else {
$pf = &new PEAR_PackageFile($this->config);
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pkg)) {
return $pkg;
}
}
$dir = dirname($descfile);
$old_cwd = getcwd();
if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
return $this->raiseError("could not chdir to $dir");
}
$vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
if (is_dir($vdir)) {
chdir($vdir);
}
$dir = getcwd();
$this->log(2, "building in $dir");
putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH'));
$err = $this->_runCommand("phpize", array(&$this, 'phpizeCallback'));
if (PEAR::isError($err)) {
return $err;
}
if (!$err) {
return $this->raiseError("`phpize' failed");
}
 
// {{{ start of interactive part
$configure_command = "$dir/configure";
$configure_options = $pkg->getConfigureOptions();
if ($configure_options) {
foreach ($configure_options as $o) {
$default = array_key_exists('default', $o) ? $o['default'] : null;
list($r) = $this->ui->userDialog('build',
array($o['prompt']),
array('text'),
array($default));
if (substr($o['name'], 0, 5) == 'with-' &&
($r == 'yes' || $r == 'autodetect')) {
$configure_command .= " --$o[name]";
} else {
$configure_command .= " --$o[name]=".trim($r);
}
}
}
// }}} end of interactive part
 
// FIXME make configurable
if(!$user=getenv('USER')){
$user='defaultuser';
}
$build_basedir = "/var/tmp/pear-build-$user";
$build_dir = "$build_basedir/$vdir";
$inst_dir = "$build_basedir/install-$vdir";
$this->log(1, "building in $build_dir");
if (is_dir($build_dir)) {
System::rm(array('-rf', $build_dir));
}
if (!System::mkDir(array('-p', $build_dir))) {
return $this->raiseError("could not create build dir: $build_dir");
}
$this->addTempFile($build_dir);
if (!System::mkDir(array('-p', $inst_dir))) {
return $this->raiseError("could not create temporary install dir: $inst_dir");
}
$this->addTempFile($inst_dir);
 
if (getenv('MAKE')) {
$make_command = getenv('MAKE');
} else {
$make_command = 'make';
}
$to_run = array(
$configure_command,
$make_command,
"$make_command INSTALL_ROOT=\"$inst_dir\" install",
"find \"$inst_dir\" -ls"
);
if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) {
return $this->raiseError("could not chdir to $build_dir");
}
putenv('PHP_PEAR_VERSION=1.5.1');
foreach ($to_run as $cmd) {
$err = $this->_runCommand($cmd, $callback);
if (PEAR::isError($err)) {
chdir($old_cwd);
return $err;
}
if (!$err) {
chdir($old_cwd);
return $this->raiseError("`$cmd' failed");
}
}
if (!($dp = opendir("modules"))) {
chdir($old_cwd);
return $this->raiseError("no `modules' directory found");
}
$built_files = array();
$prefix = exec("php-config --prefix");
$this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files);
chdir($old_cwd);
return $built_files;
}
 
// }}}
// {{{ phpizeCallback()
 
/**
* Message callback function used when running the "phpize"
* program. Extracts the API numbers used. Ignores other message
* types than "cmdoutput".
*
* @param string $what the type of message
* @param mixed $data the message
*
* @return void
*
* @access public
*/
function phpizeCallback($what, $data)
{
if ($what != 'cmdoutput') {
return;
}
$this->log(1, rtrim($data));
if (preg_match('/You should update your .aclocal.m4/', $data)) {
return;
}
$matches = array();
if (preg_match('/^\s+(\S[^:]+):\s+(\d{8})/', $data, $matches)) {
$member = preg_replace('/[^a-z]/', '_', strtolower($matches[1]));
$apino = (int)$matches[2];
if (isset($this->$member)) {
$this->$member = $apino;
//$msg = sprintf("%-22s : %d", $matches[1], $apino);
//$this->log(1, $msg);
}
}
}
 
// }}}
// {{{ _runCommand()
 
/**
* Run an external command, using a message callback to report
* output. The command will be run through popen and output is
* reported for every line with a "cmdoutput" message with the
* line string, including newlines, as payload.
*
* @param string $command the command to run
*
* @param mixed $callback (optional) function to use as message
* callback
*
* @return bool whether the command was successful (exit code 0
* means success, any other means failure)
*
* @access private
*/
function _runCommand($command, $callback = null)
{
$this->log(1, "running: $command");
$pp = popen("$command 2>&1", "r");
if (!$pp) {
return $this->raiseError("failed to run `$command'");
}
if ($callback && $callback[0]->debug == 1) {
$olddbg = $callback[0]->debug;
$callback[0]->debug = 2;
}
 
while ($line = fgets($pp, 1024)) {
if ($callback) {
call_user_func($callback, 'cmdoutput', $line);
} else {
$this->log(2, rtrim($line));
}
}
if ($callback && isset($olddbg)) {
$callback[0]->debug = $olddbg;
}
if (is_resource($pp)) {
$exitcode = pclose($pp);
} else {
$exitcode = -1;
}
return ($exitcode == 0);
}
 
// }}}
// {{{ log()
 
function log($level, $msg)
{
if ($this->current_callback) {
if ($this->debug >= $level) {
call_user_func($this->current_callback, 'output', $msg);
}
return;
}
return PEAR_Common::log($level, $msg);
}
 
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/REST/10.php
New file
0,0 → 1,684
<?php
/**
* PEAR_REST_10
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: 10.php,v 1.43 2006/11/01 05:09:05 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a12
*/
 
/**
* For downloading REST xml/txt files
*/
require_once 'PEAR/REST.php';
 
/**
* Implement REST 1.0
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a12
*/
class PEAR_REST_10
{
/**
* @var PEAR_REST
*/
var $_rest;
function PEAR_REST_10($config, $options = array())
{
$this->_rest = &new PEAR_REST($config, $options);
}
 
/**
* Retrieve information about a remote package to be downloaded from a REST server
*
* @param string $base The uri to prepend to all REST calls
* @param array $packageinfo an array of format:
* <pre>
* array(
* 'package' => 'packagename',
* 'channel' => 'channelname',
* ['state' => 'alpha' (or valid state),]
* -or-
* ['version' => '1.whatever']
* </pre>
* @param string $prefstate Current preferred_state config variable value
* @param bool $installed the installed version of this package to compare against
* @return array|false|PEAR_Error see {@link _returnDownloadURL()}
*/
function getDownloadURL($base, $packageinfo, $prefstate, $installed)
{
$channel = $packageinfo['channel'];
$package = $packageinfo['package'];
$states = $this->betterStates($prefstate, true);
if (!$states) {
return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
}
$state = $version = null;
if (isset($packageinfo['state'])) {
$state = $packageinfo['state'];
}
if (isset($packageinfo['version'])) {
$version = $packageinfo['version'];
}
$info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml');
if (PEAR::isError($info)) {
return PEAR::raiseError('No releases available for package "' .
$channel . '/' . $package . '"');
}
if (!isset($info['r'])) {
return false;
}
$found = false;
$release = false;
if (!is_array($info['r']) || !isset($info['r'][0])) {
$info['r'] = array($info['r']);
}
foreach ($info['r'] as $release) {
if (!isset($this->_rest->_options['force']) && ($installed &&
version_compare($release['v'], $installed, '<'))) {
continue;
}
if (isset($state)) {
// try our preferred state first
if ($release['s'] == $state) {
$found = true;
break;
}
// see if there is something newer and more stable
// bug #7221
if (in_array($release['s'], $this->betterStates($state), true)) {
$found = true;
break;
}
} elseif (isset($version)) {
if ($release['v'] == $version) {
$found = true;
break;
}
} else {
if (in_array($release['s'], $states)) {
$found = true;
break;
}
}
}
return $this->_returnDownloadURL($base, $package, $release, $info, $found);
}
 
function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage,
$prefstate = 'stable', $installed = false)
{
$channel = $dependency['channel'];
$package = $dependency['name'];
$states = $this->betterStates($prefstate, true);
if (!$states) {
return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
}
$state = $version = null;
if (isset($packageinfo['state'])) {
$state = $packageinfo['state'];
}
if (isset($packageinfo['version'])) {
$version = $packageinfo['version'];
}
$info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml');
if (PEAR::isError($info)) {
return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package']
. '" dependency "' . $channel . '/' . $package . '" has no releases');
}
if (!is_array($info) || !isset($info['r'])) {
return false;
}
$exclude = array();
$min = $max = $recommended = false;
if ($xsdversion == '1.0') {
$pinfo['package'] = $dependency['name'];
$pinfo['channel'] = 'pear.php.net'; // this is always true - don't change this
switch ($dependency['rel']) {
case 'ge' :
$min = $dependency['version'];
break;
case 'gt' :
$min = $dependency['version'];
$exclude = array($dependency['version']);
break;
case 'eq' :
$recommended = $dependency['version'];
break;
case 'lt' :
$max = $dependency['version'];
$exclude = array($dependency['version']);
break;
case 'le' :
$max = $dependency['version'];
break;
case 'ne' :
$exclude = array($dependency['version']);
break;
}
} else {
$pinfo['package'] = $dependency['name'];
$min = isset($dependency['min']) ? $dependency['min'] : false;
$max = isset($dependency['max']) ? $dependency['max'] : false;
$recommended = isset($dependency['recommended']) ?
$dependency['recommended'] : false;
if (isset($dependency['exclude'])) {
if (!isset($dependency['exclude'][0])) {
$exclude = array($dependency['exclude']);
}
}
}
$found = false;
$release = false;
if (!is_array($info['r']) || !isset($info['r'][0])) {
$info['r'] = array($info['r']);
}
foreach ($info['r'] as $release) {
if (!isset($this->_rest->_options['force']) && ($installed &&
version_compare($release['v'], $installed, '<'))) {
continue;
}
if (in_array($release['v'], $exclude)) { // skip excluded versions
continue;
}
// allow newer releases to say "I'm OK with the dependent package"
if ($xsdversion == '2.0' && isset($release['co'])) {
if (!is_array($release['co']) || !isset($release['co'][0])) {
$release['co'] = array($release['co']);
}
foreach ($release['co'] as $entry) {
if (isset($entry['x']) && !is_array($entry['x'])) {
$entry['x'] = array($entry['x']);
} elseif (!isset($entry['x'])) {
$entry['x'] = array();
}
if ($entry['c'] == $deppackage['channel'] &&
strtolower($entry['p']) == strtolower($deppackage['package']) &&
version_compare($deppackage['version'], $entry['min'], '>=') &&
version_compare($deppackage['version'], $entry['max'], '<=') &&
!in_array($release['v'], $entry['x'])) {
$recommended = $release['v'];
break;
}
}
}
if ($recommended) {
if ($release['v'] != $recommended) { // if we want a specific
// version, then skip all others
continue;
} else {
if (!in_array($release['s'], $states)) {
// the stability is too low, but we must return the
// recommended version if possible
return $this->_returnDownloadURL($base, $package, $release, $info, true);
}
}
}
if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions
continue;
}
if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions
continue;
}
if ($installed && version_compare($release['v'], $installed, '<')) {
continue;
}
if (in_array($release['s'], $states)) { // if in the preferred state...
$found = true; // ... then use it
break;
}
}
return $this->_returnDownloadURL($base, $package, $release, $info, $found);
}
 
/**
* Take raw data and return the array needed for processing a download URL
*
* @param string $base REST base uri
* @param string $package Package name
* @param array $release an array of format array('v' => version, 's' => state)
* describing the release to download
* @param array $info list of all releases as defined by allreleases.xml
* @param bool $found determines whether the release was found or this is the next
* best alternative
* @return array|PEAR_Error
* @access private
*/
function _returnDownloadURL($base, $package, $release, $info, $found)
{
if (!$found) {
$release = $info['r'][0];
}
$pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . strtolower($package) . '/' .
'info.xml');
if (PEAR::isError($pinfo)) {
return PEAR::raiseError('Package "' . $package .
'" does not have REST info xml available');
}
$releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
$release['v'] . '.xml');
if (PEAR::isError($releaseinfo)) {
return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] .
'" does not have REST xml available');
}
$packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
'deps.' . $release['v'] . '.txt', false, true);
if (PEAR::isError($packagexml)) {
return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] .
'" does not have REST dependency information available');
}
$packagexml = unserialize($packagexml);
if (!$packagexml) {
$packagexml = array();
}
$allinfo = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/allreleases.xml');
if (!is_array($allinfo['r']) || !isset($allinfo['r'][0])) {
$allinfo['r'] = array($allinfo['r']);
}
$compatible = false;
foreach ($allinfo['r'] as $release) {
if ($release['v'] != $releaseinfo['v']) {
continue;
}
if (!isset($release['co'])) {
break;
}
$compatible = array();
if (!is_array($release['co']) || !isset($release['co'][0])) {
$release['co'] = array($release['co']);
}
foreach ($release['co'] as $entry) {
$comp = array();
$comp['name'] = $entry['p'];
$comp['channel'] = $entry['c'];
$comp['min'] = $entry['min'];
$comp['max'] = $entry['max'];
if (isset($entry['x']) && !is_array($entry['x'])) {
$comp['exclude'] = $entry['x'];
}
$compatible[] = $comp;
}
if (count($compatible) == 1) {
$compatible = $compatible[0];
}
break;
}
if (isset($pinfo['dc']) && isset($pinfo['dp'])) {
$deprecated = array('channel' => (string) $pinfo['dc'],
'package' => trim($pinfo['dp']['_content']));
} else {
$deprecated = false;
}
if ($found) {
return
array('version' => $releaseinfo['v'],
'info' => $packagexml,
'package' => $releaseinfo['p']['_content'],
'stability' => $releaseinfo['st'],
'url' => $releaseinfo['g'],
'compatible' => $compatible,
'deprecated' => $deprecated,
);
} else {
return
array('version' => $releaseinfo['v'],
'package' => $releaseinfo['p']['_content'],
'stability' => $releaseinfo['st'],
'info' => $packagexml,
'compatible' => $compatible,
'deprecated' => $deprecated,
);
}
}
 
function listPackages($base)
{
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml');
if (PEAR::isError($packagelist)) {
return $packagelist;
}
if (!is_array($packagelist) || !isset($packagelist['p'])) {
return array();
}
if (!is_array($packagelist['p'])) {
$packagelist['p'] = array($packagelist['p']);
}
return $packagelist['p'];
}
 
function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false)
{
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml');
if (PEAR::isError($packagelist)) {
return $packagelist;
}
if ($this->_rest->config->get('verbose') > 0) {
$ui = &PEAR_Frontend::singleton();
$ui->log('Retrieving data...0%', false);
}
$ret = array();
if (!is_array($packagelist) || !isset($packagelist['p'])) {
return $ret;
}
if (!is_array($packagelist['p'])) {
$packagelist['p'] = array($packagelist['p']);
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$next = .1;
foreach ($packagelist['p'] as $progress => $package) {
if ($this->_rest->config->get('verbose') > 0) {
if ($progress / count($packagelist['p']) >= $next) {
if ($next == .5) {
$ui->log('50%', false);
} else {
$ui->log('.', false);
}
$next += .1;
}
}
if ($basic) { // remote-list command
if ($dostable) {
$latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/stable.txt');
} else {
$latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/latest.txt');
}
if (PEAR::isError($latest)) {
$latest = false;
}
$info = array('stable' => $latest);
} else { // list-all command
$inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml');
if (PEAR::isError($inf)) {
PEAR::popErrorHandling();
return $inf;
}
if ($searchpackage) {
$found = (!empty($searchpackage) && stristr($package, $searchpackage) !== false);
if (!$found && !(isset($searchsummary) && !empty($searchsummary)
&& (stristr($inf['s'], $searchsummary) !== false
|| stristr($inf['d'], $searchsummary) !== false)))
{
continue;
};
}
$releases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/allreleases.xml');
if (PEAR::isError($releases)) {
continue;
}
if (!isset($releases['r'][0])) {
$releases['r'] = array($releases['r']);
}
unset($latest);
unset($unstable);
unset($stable);
unset($state);
foreach ($releases['r'] as $release) {
if (!isset($latest)) {
if ($dostable && $release['s'] == 'stable') {
$latest = $release['v'];
$state = 'stable';
}
if (!$dostable) {
$latest = $release['v'];
$state = $release['s'];
}
}
if (!isset($stable) && $release['s'] == 'stable') {
$stable = $release['v'];
if (!isset($unstable)) {
$unstable = $stable;
}
}
if (!isset($unstable) && $release['s'] != 'stable') {
$latest = $unstable = $release['v'];
$state = $release['s'];
}
if (isset($latest) && !isset($state)) {
$state = $release['s'];
}
if (isset($latest) && isset($stable) && isset($unstable)) {
break;
}
}
$deps = array();
if (!isset($unstable)) {
$unstable = false;
$state = 'stable';
if (isset($stable)) {
$latest = $unstable = $stable;
}
} else {
$latest = $unstable;
}
if (!isset($latest)) {
$latest = false;
}
if ($latest) {
$d = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' .
$latest . '.txt');
if (!PEAR::isError($d)) {
$d = unserialize($d);
if ($d) {
if (isset($d['required'])) {
if (!class_exists('PEAR_PackageFile_v2')) {
require_once 'PEAR/PackageFile/v2.php';
}
if (!isset($pf)) {
$pf = new PEAR_PackageFile_v2;
}
$pf->setDeps($d);
$tdeps = $pf->getDeps();
} else {
$tdeps = $d;
}
foreach ($tdeps as $dep) {
if ($dep['type'] !== 'pkg') {
continue;
}
$deps[] = $dep;
}
}
}
}
if (!isset($stable)) {
$stable = '-n/a-';
}
if (!$searchpackage) {
$info = array('stable' => $latest, 'summary' => $inf['s'], 'description' =>
$inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'],
'unstable' => $unstable, 'state' => $state);
} else {
$info = array('stable' => $stable, 'summary' => $inf['s'], 'description' =>
$inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'],
'unstable' => $unstable, 'state' => $state);
}
}
$ret[$package] = $info;
}
PEAR::popErrorHandling();
return $ret;
}
 
function listLatestUpgrades($base, $state, $installed, $channel, &$reg)
{
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml');
if (PEAR::isError($packagelist)) {
return $packagelist;
}
$ret = array();
if (!is_array($packagelist) || !isset($packagelist['p'])) {
return $ret;
}
if (!is_array($packagelist['p'])) {
$packagelist['p'] = array($packagelist['p']);
}
if ($state) {
$states = $this->betterStates($state, true);
}
foreach ($packagelist['p'] as $package) {
if (!isset($installed[strtolower($package)])) {
continue;
}
$inst_version = $reg->packageInfo($package, 'version', $channel);
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/allreleases.xml');
PEAR::popErrorHandling();
if (PEAR::isError($info)) {
continue; // no remote releases
}
if (!isset($info['r'])) {
continue;
}
$found = false;
$release = false;
if (!is_array($info['r']) || !isset($info['r'][0])) {
$info['r'] = array($info['r']);
}
foreach ($info['r'] as $release) {
if ($inst_version && version_compare($release['v'], $inst_version, '<=')) {
continue;
}
if ($state) {
if (in_array($release['s'], $states)) {
$found = true;
break;
}
} else {
$found = true;
break;
}
}
if (!$found) {
continue;
}
$relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
$release['v'] . '.xml');
if (PEAR::isError($relinfo)) {
return $relinfo;
}
$ret[$package] = array(
'version' => $release['v'],
'state' => $release['s'],
'filesize' => $relinfo['f'],
);
}
return $ret;
}
 
function packageInfo($base, $package)
{
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pinfo = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml');
if (PEAR::isError($pinfo)) {
PEAR::popErrorHandling();
return PEAR::raiseError('Unknown package: "' . $package . '" (Debug: ' .
$pinfo->getMessage() . ')');
}
$releases = array();
$allreleases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/allreleases.xml');
if (!PEAR::isError($allreleases)) {
if (!class_exists('PEAR_PackageFile_v2')) {
require_once 'PEAR/PackageFile/v2.php';
}
if (!is_array($allreleases['r']) || !isset($allreleases['r'][0])) {
$allreleases['r'] = array($allreleases['r']);
}
$pf = new PEAR_PackageFile_v2;
foreach ($allreleases['r'] as $release) {
$ds = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' .
$release['v'] . '.txt');
if (PEAR::isError($ds)) {
continue;
}
if (!isset($latest)) {
$latest = $release['v'];
}
$pf->setDeps(unserialize($ds));
$ds = $pf->getDeps();
$info = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package)
. '/' . $release['v'] . '.xml');
if (PEAR::isError($info)) {
continue;
}
$releases[$release['v']] = array(
'doneby' => $info['m'],
'license' => $info['l'],
'summary' => $info['s'],
'description' => $info['d'],
'releasedate' => $info['da'],
'releasenotes' => $info['n'],
'state' => $release['s'],
'deps' => $ds ? $ds : array(),
);
}
} else {
$latest = '';
}
PEAR::popErrorHandling();
if (isset($pinfo['dc']) && isset($pinfo['dp'])) {
$deprecated = array('channel' => (string) $pinfo['dc'],
'package' => trim($pinfo['dp']['_content']));
} else {
$deprecated = false;
}
return array(
'name' => $pinfo['n'],
'channel' => $pinfo['c'],
'category' => $pinfo['ca']['_content'],
'stable' => $latest,
'license' => $pinfo['l'],
'summary' => $pinfo['s'],
'description' => $pinfo['d'],
'releases' => $releases,
'deprecated' => $deprecated,
);
}
 
/**
* Return an array containing all of the states that are more stable than
* or equal to the passed in state
*
* @param string Release state
* @param boolean Determines whether to include $state in the list
* @return false|array False if $state is not a valid release state
*/
function betterStates($state, $include = false)
{
static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
$i = array_search($state, $states);
if ($i === false) {
return false;
}
if ($include) {
$i--;
}
return array_slice($states, $i + 1);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/REST/11.php
New file
0,0 → 1,224
<?php
/**
* PEAR_REST_11 - implement faster list-all/remote-list command
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: 11.php,v 1.8 2007/01/27 16:10:23 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.3
*/
 
/**
* For downloading REST xml/txt files
*/
require_once 'PEAR/REST.php';
 
/**
* Implement REST 1.1
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.3
*/
class PEAR_REST_11
{
/**
* @var PEAR_REST
*/
var $_rest;
 
function PEAR_REST_11($config, $options = array())
{
$this->_rest = &new PEAR_REST($config, $options);
}
 
function listAll($base, $dostable, $basic = true)
{
$categorylist = $this->_rest->retrieveData($base . 'c/categories.xml');
if (PEAR::isError($categorylist)) {
return $categorylist;
}
$ret = array();
if (!is_array($categorylist['c']) || !isset($categorylist['c'][0])) {
$categorylist['c'] = array($categorylist['c']);
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
 
foreach ($categorylist['c'] as $progress => $category) {
$category = $category['_content'];
$packagesinfo = $this->_rest->retrieveData($base .
'c/' . urlencode($category) . '/packagesinfo.xml');
 
if (PEAR::isError($packagesinfo)) {
continue;
}
 
if (!is_array($packagesinfo) || !isset($packagesinfo['pi'])) {
continue;
}
 
if (!is_array($packagesinfo['pi']) || !isset($packagesinfo['pi'][0])) {
$packagesinfo['pi'] = array($packagesinfo['pi']);
}
 
foreach ($packagesinfo['pi'] as $packageinfo) {
$info = $packageinfo['p'];
$package = $info['n'];
$releases = isset($packageinfo['a']) ? $packageinfo['a'] : false;
unset($latest);
unset($unstable);
unset($stable);
unset($state);
 
if ($releases) {
if (!isset($releases['r'][0])) {
$releases['r'] = array($releases['r']);
}
foreach ($releases['r'] as $release) {
if (!isset($latest)) {
if ($dostable && $release['s'] == 'stable') {
$latest = $release['v'];
$state = 'stable';
}
if (!$dostable) {
$latest = $release['v'];
$state = $release['s'];
}
}
if (!isset($stable) && $release['s'] == 'stable') {
$stable = $release['v'];
if (!isset($unstable)) {
$unstable = $stable;
}
}
if (!isset($unstable) && $release['s'] != 'stable') {
$latest = $unstable = $release['v'];
$state = $release['s'];
}
if (isset($latest) && !isset($state)) {
$state = $release['s'];
}
if (isset($latest) && isset($stable) && isset($unstable)) {
break;
}
}
}
 
if ($basic) { // remote-list command
if (!isset($latest)) {
$latest = false;
}
if ($dostable) {
// $state is not set if there are no releases
if (isset($state) && $state == 'stable') {
$ret[$package] = array('stable' => $latest);
} else {
$ret[$package] = array('stable' => '-n/a-');
}
} else {
$ret[$package] = array('stable' => $latest);
}
continue;
}
 
// list-all command
$deps = array();
if (!isset($unstable)) {
$unstable = false;
$state = 'stable';
if (isset($stable)) {
$latest = $unstable = $stable;
}
} else {
$latest = $unstable;
}
 
if (!isset($latest)) {
$latest = false;
}
 
if ($latest && $packageinfo['deps'] !== null) {
if (isset($packageinfo['deps'])) {
if (!is_array($packageinfo['deps']) ||
!isset($packageinfo['deps'][0])) {
$packageinfo['deps'] = array($packageinfo['deps']);
}
}
$d = false;
foreach ($packageinfo['deps'] as $dep) {
if ($dep['v'] == $latest) {
$d = unserialize($dep['d']);
}
}
if ($d) {
if (isset($d['required'])) {
if (!class_exists('PEAR_PackageFile_v2')) {
require_once 'PEAR/PackageFile/v2.php';
}
if (!isset($pf)) {
$pf = new PEAR_PackageFile_v2;
}
$pf->setDeps($d);
$tdeps = $pf->getDeps();
} else {
$tdeps = $d;
}
foreach ($tdeps as $dep) {
if ($dep['type'] !== 'pkg') {
continue;
}
$deps[] = $dep;
}
}
}
 
$info = array('stable' => $latest, 'summary' => $info['s'],
'description' =>
$info['d'], 'deps' => $deps, 'category' => $info['ca']['_content'],
'unstable' => $unstable, 'state' => $state);
$ret[$package] = $info;
}
}
PEAR::popErrorHandling();
return $ret;
}
 
/**
* Return an array containing all of the states that are more stable than
* or equal to the passed in state
*
* @param string Release state
* @param boolean Determines whether to include $state in the list
* @return false|array False if $state is not a valid release state
*/
function betterStates($state, $include = false)
{
static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
$i = array_search($state, $states);
if ($i === false) {
return false;
}
if ($include) {
$i--;
}
return array_slice($states, $i + 1);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Mirror.xml
New file
0,0 → 1,18
<commands version="1.0">
<download-all>
<summary>Downloads each available package from the default channel</summary>
<function>doDownloadAll</function>
<shortcut>da</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>
Requests a list of available packages from the default channel ({config default_channel})
and downloads them to current working directory. Note: only
packages within preferred_state ({config preferred_state}) will be downloaded</doc>
</download-all>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Common.php
New file
0,0 → 1,291
<?php
/**
* PEAR_Command_Common base class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Common.php,v 1.35 2006/06/08 22:25:18 pajoye Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR.php';
 
/**
* PEAR commands base class
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Common extends PEAR
{
// {{{ properties
 
/**
* PEAR_Config object used to pass user system and configuration
* on when executing commands
*
* @var PEAR_Config
*/
var $config;
/**
* @var PEAR_Registry
* @access protected
*/
var $_registry;
 
/**
* User Interface object, for all interaction with the user.
* @var object
*/
var $ui;
 
var $_deps_rel_trans = array(
'lt' => '<',
'le' => '<=',
'eq' => '=',
'ne' => '!=',
'gt' => '>',
'ge' => '>=',
'has' => '=='
);
 
var $_deps_type_trans = array(
'pkg' => 'package',
'ext' => 'extension',
'php' => 'PHP',
'prog' => 'external program',
'ldlib' => 'external library for linking',
'rtlib' => 'external runtime library',
'os' => 'operating system',
'websrv' => 'web server',
'sapi' => 'SAPI backend'
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Common constructor.
*
* @access public
*/
function PEAR_Command_Common(&$ui, &$config)
{
parent::PEAR();
$this->config = &$config;
$this->ui = &$ui;
}
 
// }}}
 
// {{{ getCommands()
 
/**
* Return a list of all the commands defined by this class.
* @return array list of commands
* @access public
*/
function getCommands()
{
$ret = array();
foreach (array_keys($this->commands) as $command) {
$ret[$command] = $this->commands[$command]['summary'];
}
return $ret;
}
 
// }}}
// {{{ getShortcuts()
 
/**
* Return a list of all the command shortcuts defined by this class.
* @return array shortcut => command
* @access public
*/
function getShortcuts()
{
$ret = array();
foreach (array_keys($this->commands) as $command) {
if (isset($this->commands[$command]['shortcut'])) {
$ret[$this->commands[$command]['shortcut']] = $command;
}
}
return $ret;
}
 
// }}}
// {{{ getOptions()
 
function getOptions($command)
{
$shortcuts = $this->getShortcuts();
if (isset($shortcuts[$command])) {
$command = $shortcuts[$command];
}
if (isset($this->commands[$command]) &&
isset($this->commands[$command]['options'])) {
return $this->commands[$command]['options'];
} else {
return null;
}
}
 
// }}}
// {{{ getGetoptArgs()
 
function getGetoptArgs($command, &$short_args, &$long_args)
{
$short_args = "";
$long_args = array();
if (empty($this->commands[$command]) || empty($this->commands[$command]['options'])) {
return;
}
reset($this->commands[$command]['options']);
while (list($option, $info) = each($this->commands[$command]['options'])) {
$larg = $sarg = '';
if (isset($info['arg'])) {
if ($info['arg']{0} == '(') {
$larg = '==';
$sarg = '::';
$arg = substr($info['arg'], 1, -1);
} else {
$larg = '=';
$sarg = ':';
$arg = $info['arg'];
}
}
if (isset($info['shortopt'])) {
$short_args .= $info['shortopt'] . $sarg;
}
$long_args[] = $option . $larg;
}
}
 
// }}}
// {{{ getHelp()
/**
* Returns the help message for the given command
*
* @param string $command The command
* @return mixed A fail string if the command does not have help or
* a two elements array containing [0]=>help string,
* [1]=> help string for the accepted cmd args
*/
function getHelp($command)
{
$config = &PEAR_Config::singleton();
if (!isset($this->commands[$command])) {
return "No such command \"$command\"";
}
$help = null;
if (isset($this->commands[$command]['doc'])) {
$help = $this->commands[$command]['doc'];
}
if (empty($help)) {
// XXX (cox) Fallback to summary if there is no doc (show both?)
if (!isset($this->commands[$command]['summary'])) {
return "No help for command \"$command\"";
}
$help = $this->commands[$command]['summary'];
}
if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) {
foreach($matches[0] as $k => $v) {
$help = preg_replace("/$v/", $config->get($matches[1][$k]), $help);
}
}
return array($help, $this->getHelpArgs($command));
}
 
// }}}
// {{{ getHelpArgs()
/**
* Returns the help for the accepted arguments of a command
*
* @param string $command
* @return string The help string
*/
function getHelpArgs($command)
{
if (isset($this->commands[$command]['options']) &&
count($this->commands[$command]['options']))
{
$help = "Options:\n";
foreach ($this->commands[$command]['options'] as $k => $v) {
if (isset($v['arg'])) {
if ($v['arg'][0] == '(') {
$arg = substr($v['arg'], 1, -1);
$sapp = " [$arg]";
$lapp = "[=$arg]";
} else {
$sapp = " $v[arg]";
$lapp = "=$v[arg]";
}
} else {
$sapp = $lapp = "";
}
if (isset($v['shortopt'])) {
$s = $v['shortopt'];
$help .= " -$s$sapp, --$k$lapp\n";
} else {
$help .= " --$k$lapp\n";
}
$p = " ";
$doc = rtrim(str_replace("\n", "\n$p", $v['doc']));
$help .= " $doc\n";
}
return $help;
}
return null;
}
 
// }}}
// {{{ run()
 
function run($command, $options, $params)
{
if (empty($this->commands[$command]['function'])) {
// look for shortcuts
foreach (array_keys($this->commands) as $cmd) {
if (isset($this->commands[$cmd]['shortcut']) && $this->commands[$cmd]['shortcut'] == $command) {
if (empty($this->commands[$cmd]['function'])) {
return $this->raiseError("unknown command `$command'");
} else {
$func = $this->commands[$cmd]['function'];
}
$command = $cmd;
break;
}
}
} else {
$func = $this->commands[$command]['function'];
}
return $this->$func($command, $options, $params);
}
 
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Test.xml
New file
0,0 → 1,49
<commands version="1.0">
<run-tests>
<summary>Run Regression Tests</summary>
<function>doRunTests</function>
<shortcut>rt</shortcut>
<options>
<recur>
<shortopt>r</shortopt>
<doc>Run tests in child directories, recursively. 4 dirs deep maximum</doc>
</recur>
<ini>
<shortopt>i</shortopt>
<doc>actual string of settings to pass to php in format &quot; -d setting=blah&quot;</doc>
<arg>SETTINGS</arg>
</ini>
<realtimelog>
<shortopt>l</shortopt>
<doc>Log test runs/results as they are run</doc>
</realtimelog>
<quiet>
<shortopt>q</shortopt>
<doc>Only display detail for failed tests</doc>
</quiet>
<simple>
<shortopt>s</shortopt>
<doc>Display simple output for all tests</doc>
</simple>
<package>
<shortopt>p</shortopt>
<doc>Treat parameters as installed packages from which to run tests</doc>
</package>
<phpunit>
<shortopt>u</shortopt>
<doc>Search parameters for AllTests.php, and use that to run phpunit-based tests</doc>
</phpunit>
<tapoutput>
<shortopt>t</shortopt>
<doc>Output run-tests.log in TAP-compliant format</doc>
</tapoutput>
<cgi>
<shortopt>c</shortopt>
<doc>CGI php executable (needed for tests with POST/GET section)</doc>
<arg>PHPCGI</arg>
</cgi>
</options>
<doc>[testfile|dir ...]
Run regression tests with PHP&apos;s regression testing script (run-tests.php).</doc>
</run-tests>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Package.php
New file
0,0 → 1,828
<?php
/**
* PEAR_Command_Package (package, package-validate, cvsdiff, cvstag, package-dependencies,
* sign, makerpm, convert commands)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Package.php,v 1.122 2006/06/07 23:38:14 pajoye Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
 
/**
* PEAR commands for login/logout
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
 
class PEAR_Command_Package extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'package' => array(
'summary' => 'Build Package',
'function' => 'doPackage',
'shortcut' => 'p',
'options' => array(
'nocompress' => array(
'shortopt' => 'Z',
'doc' => 'Do not gzip the package file'
),
'showname' => array(
'shortopt' => 'n',
'doc' => 'Print the name of the packaged file.',
),
),
'doc' => '[descfile] [descfile2]
Creates a PEAR package from its description file (usually called
package.xml). If a second packagefile is passed in, then
the packager will check to make sure that one is a package.xml
version 1.0, and the other is a package.xml version 2.0. The
package.xml version 1.0 will be saved as "package.xml" in the archive,
and the other as "package2.xml" in the archive"
'
),
'package-validate' => array(
'summary' => 'Validate Package Consistency',
'function' => 'doPackageValidate',
'shortcut' => 'pv',
'options' => array(),
'doc' => '
',
),
'cvsdiff' => array(
'summary' => 'Run a "cvs diff" for all files in a package',
'function' => 'doCvsDiff',
'shortcut' => 'cd',
'options' => array(
'quiet' => array(
'shortopt' => 'q',
'doc' => 'Be quiet',
),
'reallyquiet' => array(
'shortopt' => 'Q',
'doc' => 'Be really quiet',
),
'date' => array(
'shortopt' => 'D',
'doc' => 'Diff against revision of DATE',
'arg' => 'DATE',
),
'release' => array(
'shortopt' => 'R',
'doc' => 'Diff against tag for package release REL',
'arg' => 'REL',
),
'revision' => array(
'shortopt' => 'r',
'doc' => 'Diff against revision REV',
'arg' => 'REV',
),
'context' => array(
'shortopt' => 'c',
'doc' => 'Generate context diff',
),
'unified' => array(
'shortopt' => 'u',
'doc' => 'Generate unified diff',
),
'ignore-case' => array(
'shortopt' => 'i',
'doc' => 'Ignore case, consider upper- and lower-case letters equivalent',
),
'ignore-whitespace' => array(
'shortopt' => 'b',
'doc' => 'Ignore changes in amount of white space',
),
'ignore-blank-lines' => array(
'shortopt' => 'B',
'doc' => 'Ignore changes that insert or delete blank lines',
),
'brief' => array(
'doc' => 'Report only whether the files differ, no details',
),
'dry-run' => array(
'shortopt' => 'n',
'doc' => 'Don\'t do anything, just pretend',
),
),
'doc' => '<package.xml>
Compares all the files in a package. Without any options, this
command will compare the current code with the last checked-in code.
Using the -r or -R option you may compare the current code with that
of a specific release.
',
),
'cvstag' => array(
'summary' => 'Set CVS Release Tag',
'function' => 'doCvsTag',
'shortcut' => 'ct',
'options' => array(
'quiet' => array(
'shortopt' => 'q',
'doc' => 'Be quiet',
),
'reallyquiet' => array(
'shortopt' => 'Q',
'doc' => 'Be really quiet',
),
'slide' => array(
'shortopt' => 'F',
'doc' => 'Move (slide) tag if it exists',
),
'delete' => array(
'shortopt' => 'd',
'doc' => 'Remove tag',
),
'dry-run' => array(
'shortopt' => 'n',
'doc' => 'Don\'t do anything, just pretend',
),
),
'doc' => '<package.xml> [files...]
Sets a CVS tag on all files in a package. Use this command after you have
packaged a distribution tarball with the "package" command to tag what
revisions of what files were in that release. If need to fix something
after running cvstag once, but before the tarball is released to the public,
use the "slide" option to move the release tag.
 
to include files (such as a second package.xml, or tests not included in the
release), pass them as additional parameters.
',
),
'package-dependencies' => array(
'summary' => 'Show package dependencies',
'function' => 'doPackageDependencies',
'shortcut' => 'pd',
'options' => array(),
'doc' => '
List all dependencies the package has.'
),
'sign' => array(
'summary' => 'Sign a package distribution file',
'function' => 'doSign',
'shortcut' => 'si',
'options' => array(),
'doc' => '<package-file>
Signs a package distribution (.tar or .tgz) file with GnuPG.',
),
'makerpm' => array(
'summary' => 'Builds an RPM spec file from a PEAR package',
'function' => 'doMakeRPM',
'shortcut' => 'rpm',
'options' => array(
'spec-template' => array(
'shortopt' => 't',
'arg' => 'FILE',
'doc' => 'Use FILE as RPM spec file template'
),
'rpm-pkgname' => array(
'shortopt' => 'p',
'arg' => 'FORMAT',
'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced
by the PEAR package name, defaults to "PEAR::%s".',
),
),
'doc' => '<package-file>
 
Creates an RPM .spec file for wrapping a PEAR package inside an RPM
package. Intended to be used from the SPECS directory, with the PEAR
package tarball in the SOURCES directory:
 
$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz
Wrote RPM spec file PEAR::Net_Geo-1.0.spec
$ rpm -bb PEAR::Net_Socket-1.0.spec
...
Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm
',
),
'convert' => array(
'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format',
'function' => 'doConvert',
'shortcut' => 'c2',
'options' => array(
'flat' => array(
'shortopt' => 'f',
'doc' => 'do not beautify the filelist.',
),
),
'doc' => '[descfile] [descfile2]
Converts a package.xml in 1.0 format into a package.xml
in 2.0 format. The new file will be named package2.xml by default,
and package.xml will be used as the old file by default.
This is not the most intelligent conversion, and should only be
used for automated conversion or learning the format.
'
),
);
 
var $output;
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Package constructor.
*
* @access public
*/
function PEAR_Command_Package(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ _displayValidationResults()
 
function _displayValidationResults($err, $warn, $strict = false)
{
foreach ($err as $e) {
$this->output .= "Error: $e\n";
}
foreach ($warn as $w) {
$this->output .= "Warning: $w\n";
}
$this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n",
sizeof($err), sizeof($warn));
if ($strict && sizeof($err) > 0) {
$this->output .= "Fix these errors and try again.";
return false;
}
return true;
}
 
// }}}
function &getPackager()
{
if (!class_exists('PEAR_Packager')) {
require_once 'PEAR/Packager.php';
}
$a = &new PEAR_Packager;
return $a;
}
 
function &getPackageFile($config, $debug = false, $tmpdir = null)
{
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
if (!class_exists('PEAR/PackageFile.php')) {
require_once 'PEAR/PackageFile.php';
}
$a = &new PEAR_PackageFile($config, $debug, $tmpdir);
$common = new PEAR_Common;
$common->ui = $this->ui;
$a->setLogger($common);
return $a;
}
// {{{ doPackage()
 
function doPackage($command, $options, $params)
{
$this->output = '';
$pkginfofile = isset($params[0]) ? $params[0] : 'package.xml';
$pkg2 = isset($params[1]) ? $params[1] : null;
if (!$pkg2 && !isset($params[0])) {
if (file_exists('package2.xml')) {
$pkg2 = 'package2.xml';
}
}
$packager = &$this->getPackager();
$compress = empty($options['nocompress']) ? true : false;
$result = $packager->package($pkginfofile, $compress, $pkg2);
if (PEAR::isError($result)) {
return $this->raiseError($result);
}
// Don't want output, only the package file name just created
if (isset($options['showname'])) {
$this->output = $result;
}
if ($this->output) {
$this->ui->outputData($this->output, $command);
}
return true;
}
 
// }}}
// {{{ doPackageValidate()
 
function doPackageValidate($command, $options, $params)
{
$this->output = '';
if (sizeof($params) < 1) {
$params[0] = "package.xml";
}
$obj = &$this->getPackageFile($this->config, $this->_debug);
$obj->rawReturn();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
if (PEAR::isError($info)) {
$info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL);
} else {
$archive = $info->getArchiveFile();
$tar = &new Archive_Tar($archive);
$tar->extract(dirname($info->getPackageFile()));
$info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR .
$info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR .
basename($info->getPackageFile()));
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
$valid = false;
if ($info->getPackagexmlVersion() == '2.0') {
if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) {
$info->flattenFileList();
$valid = $info->validate(PEAR_VALIDATE_PACKAGING);
}
} else {
$valid = $info->validate(PEAR_VALIDATE_PACKAGING);
}
$err = array();
$warn = array();
if (!$valid) {
foreach ($info->getValidationWarnings() as $error) {
if ($error['level'] == 'warning') {
$warn[] = $error['message'];
} else {
$err[] = $error['message'];
}
}
}
$this->_displayValidationResults($err, $warn);
$this->ui->outputData($this->output, $command);
return true;
}
 
// }}}
// {{{ doCvsTag()
 
function doCvsTag($command, $options, $params)
{
$this->output = '';
$_cmd = $command;
if (sizeof($params) < 1) {
$help = $this->getHelp($command);
return $this->raiseError("$command: missing parameter: $help[0]");
}
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
$err = $warn = array();
if (!$info->validate()) {
foreach ($info->getValidationWarnings() as $error) {
if ($error['level'] == 'warning') {
$warn[] = $error['message'];
} else {
$err[] = $error['message'];
}
}
}
if (!$this->_displayValidationResults($err, $warn, true)) {
$this->ui->outputData($this->output, $command);
return $this->raiseError('CVS tag failed');
}
$version = $info->getVersion();
$cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version);
$cvstag = "RELEASE_$cvsversion";
$files = array_keys($info->getFilelist());
$command = "cvs";
if (isset($options['quiet'])) {
$command .= ' -q';
}
if (isset($options['reallyquiet'])) {
$command .= ' -Q';
}
$command .= ' tag';
if (isset($options['slide'])) {
$command .= ' -F';
}
if (isset($options['delete'])) {
$command .= ' -d';
}
$command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]);
array_shift($params);
if (count($params)) {
// add in additional files to be tagged
$files = array_merge($files, $params);
}
foreach ($files as $file) {
$command .= ' ' . escapeshellarg($file);
}
if ($this->config->get('verbose') > 1) {
$this->output .= "+ $command\n";
}
$this->output .= "+ $command\n";
if (empty($options['dry-run'])) {
$fp = popen($command, "r");
while ($line = fgets($fp, 1024)) {
$this->output .= rtrim($line)."\n";
}
pclose($fp);
}
$this->ui->outputData($this->output, $_cmd);
return true;
}
 
// }}}
// {{{ doCvsDiff()
 
function doCvsDiff($command, $options, $params)
{
$this->output = '';
if (sizeof($params) < 1) {
$help = $this->getHelp($command);
return $this->raiseError("$command: missing parameter: $help[0]");
}
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
$err = $warn = array();
if (!$info->validate()) {
foreach ($info->getValidationWarnings() as $error) {
if ($error['level'] == 'warning') {
$warn[] = $error['message'];
} else {
$err[] = $error['message'];
}
}
}
if (!$this->_displayValidationResults($err, $warn, true)) {
$this->ui->outputData($this->output, $command);
return $this->raiseError('CVS diff failed');
}
$info1 = $info->getFilelist();
$files = $info1;
$cmd = "cvs";
if (isset($options['quiet'])) {
$cmd .= ' -q';
unset($options['quiet']);
}
if (isset($options['reallyquiet'])) {
$cmd .= ' -Q';
unset($options['reallyquiet']);
}
if (isset($options['release'])) {
$cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']);
$cvstag = "RELEASE_$cvsversion";
$options['revision'] = $cvstag;
unset($options['release']);
}
$execute = true;
if (isset($options['dry-run'])) {
$execute = false;
unset($options['dry-run']);
}
$cmd .= ' diff';
// the rest of the options are passed right on to "cvs diff"
foreach ($options as $option => $optarg) {
$arg = $short = false;
if (isset($this->commands[$command]['options'][$option])) {
$arg = $this->commands[$command]['options'][$option]['arg'];
$short = $this->commands[$command]['options'][$option]['shortopt'];
}
$cmd .= $short ? " -$short" : " --$option";
if ($arg && $optarg) {
$cmd .= ($short ? '' : '=') . escapeshellarg($optarg);
}
}
foreach ($files as $file) {
$cmd .= ' ' . escapeshellarg($file['name']);
}
if ($this->config->get('verbose') > 1) {
$this->output .= "+ $cmd\n";
}
if ($execute) {
$fp = popen($cmd, "r");
while ($line = fgets($fp, 1024)) {
$this->output .= rtrim($line)."\n";
}
pclose($fp);
}
$this->ui->outputData($this->output, $command);
return true;
}
 
// }}}
// {{{ doPackageDependencies()
 
function doPackageDependencies($command, $options, $params)
{
// $params[0] -> the PEAR package to list its information
if (sizeof($params) != 1) {
return $this->raiseError("bad parameter(s), try \"help $command\"");
}
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
$deps = $info->getDeps();
if (is_array($deps)) {
if ($info->getPackagexmlVersion() == '1.0') {
$data = array(
'caption' => 'Dependencies for pear/' . $info->getPackage(),
'border' => true,
'headline' => array("Required?", "Type", "Name", "Relation", "Version"),
);
 
foreach ($deps as $d) {
if (isset($d['optional'])) {
if ($d['optional'] == 'yes') {
$req = 'No';
} else {
$req = 'Yes';
}
} else {
$req = 'Yes';
}
if (isset($this->_deps_rel_trans[$d['rel']])) {
$rel = $this->_deps_rel_trans[$d['rel']];
} else {
$rel = $d['rel'];
}
 
if (isset($this->_deps_type_trans[$d['type']])) {
$type = ucfirst($this->_deps_type_trans[$d['type']]);
} else {
$type = $d['type'];
}
 
if (isset($d['name'])) {
$name = $d['name'];
} else {
$name = '';
}
 
if (isset($d['version'])) {
$version = $d['version'];
} else {
$version = '';
}
 
$data['data'][] = array($req, $type, $name, $rel, $version);
}
} else { // package.xml 2.0 dependencies display
require_once 'PEAR/Dependency2.php';
$deps = $info->getDependencies();
$reg = &$this->config->getRegistry();
if (is_array($deps)) {
$d = new PEAR_Dependency2($this->config, array(), '');
$data = array(
'caption' => 'Dependencies for ' . $info->getPackage(),
'border' => true,
'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'),
);
foreach ($deps as $type => $subd) {
$req = ($type == 'required') ? 'Yes' : 'No';
if ($type == 'group') {
$group = $subd['attribs']['name'];
} else {
$group = '';
}
if (!isset($subd[0])) {
$subd = array($subd);
}
foreach ($subd as $groupa) {
foreach ($groupa as $deptype => $depinfo) {
if ($deptype == 'attribs') {
continue;
}
if ($deptype == 'pearinstaller') {
$deptype = 'pear Installer';
}
if (!isset($depinfo[0])) {
$depinfo = array($depinfo);
}
foreach ($depinfo as $inf) {
$name = '';
if (isset($inf['channel'])) {
$alias = $reg->channelAlias($inf['channel']);
if (!$alias) {
$alias = '(channel?) ' .$inf['channel'];
}
$name = $alias . '/';
}
if (isset($inf['name'])) {
$name .= $inf['name'];
} elseif (isset($inf['pattern'])) {
$name .= $inf['pattern'];
} else {
$name .= '';
}
if (isset($inf['uri'])) {
$name .= ' [' . $inf['uri'] . ']';
}
if (isset($inf['conflicts'])) {
$ver = 'conflicts';
} else {
$ver = $d->_getExtraString($inf);
}
$data['data'][] = array($req, ucfirst($deptype), $name,
$ver, $group);
}
}
}
}
}
}
 
$this->ui->outputData($data, $command);
return true;
}
 
// Fallback
$this->ui->outputData("This package does not have any dependencies.", $command);
}
 
// }}}
// {{{ doSign()
 
function doSign($command, $options, $params)
{
require_once 'System.php';
require_once 'Archive/Tar.php';
// should move most of this code into PEAR_Packager
// so it'll be easy to implement "pear package --sign"
if (sizeof($params) != 1) {
return $this->raiseError("bad parameter(s), try \"help $command\"");
}
if (!file_exists($params[0])) {
return $this->raiseError("file does not exist: $params[0]");
}
$obj = $this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
$tar = new Archive_Tar($params[0]);
$tmpdir = System::mktemp('-d pearsign');
if (!$tar->extractList('package2.xml package.sig', $tmpdir)) {
if (!$tar->extractList('package.xml package.sig', $tmpdir)) {
return $this->raiseError("failed to extract tar file");
}
}
if (file_exists("$tmpdir/package.sig")) {
return $this->raiseError("package already signed");
}
$packagexml = 'package.xml';
if (file_exists("$tmpdir/package2.xml")) {
$packagexml = 'package2.xml';
}
if (file_exists("$tmpdir/package.sig")) {
unlink("$tmpdir/package.sig");
}
$input = $this->ui->userDialog($command,
array('GnuPG Passphrase'),
array('password'));
$gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml 2>/dev/null", "w");
if (!$gpg) {
return $this->raiseError("gpg command failed");
}
fwrite($gpg, "$input[0]\n");
if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) {
return $this->raiseError("gpg sign failed");
}
$tar->addModify("$tmpdir/package.sig", '', $tmpdir);
return true;
}
 
// }}}
 
/**
* For unit testing purposes
*/
function &getInstaller(&$ui)
{
if (!class_exists('PEAR_Installer')) {
require_once 'PEAR/Installer.php';
}
$a = &new PEAR_Installer($ui);
return $a;
}
/**
* For unit testing purposes
*/
function &getCommandPackaging(&$ui, &$config)
{
if (!class_exists('PEAR_Command_Packaging')) {
if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) {
fclose($fp);
include_once 'PEAR/Command/Packaging.php';
}
}
if (class_exists('PEAR_Command_Packaging')) {
$a = &new PEAR_Command_Packaging($ui, $config);
} else {
$a = null;
}
return $a;
}
 
// {{{ doMakeRPM()
 
function doMakeRPM($command, $options, $params)
{
 
// Check to see if PEAR_Command_Packaging is installed, and
// transparently switch to use the "make-rpm-spec" command from it
// instead, if it does. Otherwise, continue to use the old version
// of "makerpm" supplied with this package (PEAR).
$packaging_cmd = $this->getCommandPackaging($this->ui, $this->config);
if ($packaging_cmd !== null) {
$this->ui->outputData('PEAR_Command_Packaging is installed; using '.
'newer "make-rpm-spec" command instead');
return $packaging_cmd->run('make-rpm-spec', $options, $params);
} else {
$this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '.
'improved version is available via "pear make-rpm-spec", which '.
'is available by installing PEAR_Command_Packaging');
}
return true;
}
 
function doConvert($command, $options, $params)
{
$packagexml = isset($params[0]) ? $params[0] : 'package.xml';
$newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) .
DIRECTORY_SEPARATOR . 'package2.xml';
$pkg = &$this->getPackageFile($this->config, $this->_debug);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL);
PEAR::staticPopErrorHandling();
if (!PEAR::isError($pf)) {
if (is_a($pf, 'PEAR_PackageFile_v2')) {
$this->ui->outputData($packagexml . ' is already a package.xml version 2.0');
return true;
}
$gen = &$pf->getDefaultGenerator();
$newpf = &$gen->toV2();
$newpf->setPackagefile($newpackagexml);
$gen = &$newpf->getDefaultGenerator();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL);
$saved = $gen->toPackageFile(dirname($newpackagexml), $state,
basename($newpackagexml));
PEAR::staticPopErrorHandling();
if (PEAR::isError($saved)) {
if (is_array($saved->getUserInfo())) {
foreach ($saved->getUserInfo() as $warning) {
$this->ui->outputData($warning['message']);
}
}
$this->ui->outputData($saved->getMessage());
return true;
}
$this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"');
return true;
} else {
if (is_array($pf->getUserInfo())) {
foreach ($pf->getUserInfo() as $warning) {
$this->ui->outputData($warning['message']);
}
}
return $this->raiseError($pf);
}
}
 
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Channels.php
New file
0,0 → 1,785
<?php
// /* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* PEAR_Command_Channels (list-channels, update-channels, channel-delete, channel-add,
* channel-update, channel-info, channel-alias, channel-discover commands)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Channels.php,v 1.46 2006/07/17 18:19:25 pajoye Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
 
/**
* PEAR commands for managing channels.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Command_Channels extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'list-channels' => array(
'summary' => 'List Available Channels',
'function' => 'doList',
'shortcut' => 'lc',
'options' => array(),
'doc' => '
List all available channels for installation.
',
),
'update-channels' => array(
'summary' => 'Update the Channel List',
'function' => 'doUpdateAll',
'shortcut' => 'uc',
'options' => array(),
'doc' => '
List all installed packages in all channels.
'
),
'channel-delete' => array(
'summary' => 'Remove a Channel From the List',
'function' => 'doDelete',
'shortcut' => 'cde',
'options' => array(),
'doc' => '<channel name>
Delete a channel from the registry. You may not
remove any channel that has installed packages.
'
),
'channel-add' => array(
'summary' => 'Add a Channel',
'function' => 'doAdd',
'shortcut' => 'ca',
'options' => array(),
'doc' => '<channel.xml>
Add a private channel to the channel list. Note that all
public channels should be synced using "update-channels".
Parameter may be either a local file or remote URL to a
channel.xml.
'
),
'channel-update' => array(
'summary' => 'Update an Existing Channel',
'function' => 'doUpdate',
'shortcut' => 'cu',
'options' => array(
'force' => array(
'shortopt' => 'f',
'doc' => 'will force download of new channel.xml if an existing channel name is used',
),
'channel' => array(
'shortopt' => 'c',
'arg' => 'CHANNEL',
'doc' => 'will force download of new channel.xml if an existing channel name is used',
),
),
'doc' => '[<channel.xml>|<channel name>]
Update a channel in the channel list directly. Note that all
public channels can be synced using "update-channels".
Parameter may be a local or remote channel.xml, or the name of
an existing channel.
'
),
'channel-info' => array(
'summary' => 'Retrieve Information on a Channel',
'function' => 'doInfo',
'shortcut' => 'ci',
'options' => array(),
'doc' => '<package>
List the files in an installed package.
'
),
'channel-alias' => array(
'summary' => 'Specify an alias to a channel name',
'function' => 'doAlias',
'shortcut' => 'cha',
'options' => array(),
'doc' => '<channel> <alias>
Specify a specific alias to use for a channel name.
The alias may not be an existing channel name or
alias.
'
),
'channel-discover' => array(
'summary' => 'Initialize a Channel from its server',
'function' => 'doDiscover',
'shortcut' => 'di',
'options' => array(),
'doc' => '[<channel.xml>|<channel name>]
Initialize a Channel from its server and creates the local channel.xml.
'
),
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Registry constructor.
*
* @access public
*/
function PEAR_Command_Channels(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ doList()
function _sortChannels($a, $b)
{
return strnatcasecmp($a->getName(), $b->getName());
}
 
function doList($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$registered = $reg->getChannels();
usort($registered, array(&$this, '_sortchannels'));
$i = $j = 0;
$data = array(
'caption' => 'Registered Channels:',
'border' => true,
'headline' => array('Channel', 'Summary')
);
foreach ($registered as $channel) {
$data['data'][] = array($channel->getName(),
$channel->getSummary());
}
if (count($registered)==0) {
$data = '(no registered channels)';
}
$this->ui->outputData($data, $command);
return true;
}
function doUpdateAll($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$savechannel = $this->config->get('default_channel');
if (isset($options['channel'])) {
if (!$reg->channelExists($options['channel'])) {
return $this->raiseError('Unknown channel "' . $options['channel'] . '"');
}
$this->config->set('default_channel', $options['channel']);
} else {
$this->config->set('default_channel', 'pear.php.net');
}
$remote = &$this->config->getRemote();
$channels = $remote->call('channel.listAll');
if (PEAR::isError($channels)) {
$this->config->set('default_channel', $savechannel);
return $channels;
}
if (!is_array($channels) || isset($channels['faultCode'])) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError("Incorrect channel listing returned from channel '$chan'");
}
if (!count($channels)) {
$data = 'no updates available';
}
$dl = &$this->getDownloader();
if (!class_exists('System')) {
require_once 'System.php';
}
$tmpdir = System::mktemp(array('-d'));
foreach ($channels as $channel) {
$channel = $channel[0];
$save = $channel;
if ($reg->channelExists($channel, true)) {
$this->ui->outputData("Updating channel \"$channel\"", $command);
$test = $reg->getChannel($channel, true);
if (PEAR::isError($test)) {
$this->ui->outputData("Channel '$channel' is corrupt in registry!", $command);
$lastmodified = false;
} else {
$lastmodified = $test->lastModified();
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$contents = $dl->downloadHttp('http://' . $test->getName() . '/channel.xml',
$this->ui, $tmpdir, null, $lastmodified);
PEAR::staticPopErrorHandling();
if (PEAR::isError($contents)) {
$this->ui->outputData('ERROR: Cannot retrieve channel.xml for channel "' .
$test->getName() . '"', $command);
continue;
}
if (!$contents) {
$this->ui->outputData("Channel \"$channel\" is up-to-date", $command);
continue;
}
list($contents, $lastmodified) = $contents;
$info = implode('', file($contents));
if (!$info) {
$this->ui->outputData("Channel \"$channel\" is up-to-date", $command);
continue;
}
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channelinfo = new PEAR_ChannelFile;
$channelinfo->fromXmlString($info);
if ($channelinfo->getErrors()) {
$this->ui->outputData("Downloaded channel data from channel \"$channel\" " .
'is corrupt, skipping', $command);
continue;
}
$channel = $channelinfo;
if ($channel->getName() != $save) {
$this->ui->outputData('ERROR: Security risk - downloaded channel ' .
'definition file for channel "'
. $channel->getName() . ' from channel "' . $save .
'". To use anyway, use channel-update', $command);
continue;
}
$reg->updateChannel($channel, $lastmodified);
} else {
if ($reg->isAlias($channel)) {
$temp = &$reg->getChannel($channel);
if (PEAR::isError($temp)) {
return $this->raiseError($temp);
}
$temp->setAlias($temp->getName(), true); // set the alias to the channel name
if ($reg->channelExists($temp->getName())) {
$this->ui->outputData('ERROR: existing channel "' . $temp->getName() .
'" is aliased to "' . $channel . '" already and cannot be ' .
're-aliased to "' . $temp->getName() . '" because a channel with ' .
'that name or alias already exists! Please re-alias and try ' .
'again.', $command);
continue;
}
}
$this->ui->outputData("Adding new channel \"$channel\"", $command);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$contents = $dl->downloadHttp('http://' . $channel . '/channel.xml',
$this->ui, $tmpdir, null, false);
PEAR::staticPopErrorHandling();
if (PEAR::isError($contents)) {
$this->ui->outputData('ERROR: Cannot retrieve channel.xml for channel "' .
$channel . '"', $command);
continue;
}
list($contents, $lastmodified) = $contents;
$info = implode('', file($contents));
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channelinfo = new PEAR_Channelfile;
$channelinfo->fromXmlString($info);
if ($channelinfo->getErrors()) {
$this->ui->outputData("Downloaded channel data from channel \"$channel\"" .
' is corrupt, skipping', $command);
continue;
}
$channel = $channelinfo;
if ($channel->getName() != $save) {
$this->ui->outputData('ERROR: Security risk - downloaded channel ' .
'definition file for channel "'
. $channel->getName() . '" from channel "' . $save .
'". To use anyway, use channel-update', $command);
continue;
}
$reg->addChannel($channel, $lastmodified);
}
}
$this->config->set('default_channel', $savechannel);
$this->ui->outputData('update-channels complete', $command);
return true;
}
function doInfo($command, $options, $params)
{
if (sizeof($params) != 1) {
return $this->raiseError("No channel specified");
}
$reg = &$this->config->getRegistry();
$channel = strtolower($params[0]);
if ($reg->channelExists($channel)) {
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
} else {
if (strpos($channel, '://')) {
$downloader = &$this->getDownloader();
if (!class_exists('System')) {
require_once 'System.php';
}
$tmpdir = System::mktemp(array('-d'));
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$loc = $downloader->downloadHttp($channel, $this->ui, $tmpdir);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError('Cannot open "' . $channel . '"');
} else {
$contents = implode('', file($loc));
}
} else {
if (file_exists($params[0])) {
$fp = fopen($params[0], 'r');
if (!$fp) {
return $this->raiseError('Cannot open "' . $params[0] . '"');
}
} else {
return $this->raiseError('Unknown channel "' . $channel . '"');
}
$contents = '';
while (!feof($fp)) {
$contents .= fread($fp, 1024);
}
fclose($fp);
}
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$chan = new PEAR_ChannelFile;
$chan->fromXmlString($contents);
$chan->validate();
if ($errs = $chan->getErrors(true)) {
foreach ($errs as $err) {
$this->ui->outputData($err['level'] . ': ' . $err['message']);
}
return $this->raiseError('Channel file "' . $params[0] . '" is not valid');
}
}
if ($chan) {
$channel = $chan->getName();
$caption = 'Channel ' . $channel . ' Information:';
$data1 = array(
'caption' => $caption,
'border' => true);
$data1['data']['server'] = array('Name and Server', $chan->getName());
if ($chan->getAlias() != $chan->getName()) {
$data1['data']['alias'] = array('Alias', $chan->getAlias());
}
$data1['data']['summary'] = array('Summary', $chan->getSummary());
$validate = $chan->getValidationPackage();
$data1['data']['vpackage'] = array('Validation Package Name', $validate['_content']);
$data1['data']['vpackageversion'] =
array('Validation Package Version', $validate['attribs']['version']);
$d = array();
$d['main'] = $data1;
 
$data['data'] = array();
$data['caption'] = 'Server Capabilities';
$data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
$capabilities = $chan->getFunctions('xmlrpc');
$soaps = $chan->getFunctions('soap');
if ($capabilities || $soaps || $chan->supportsREST()) {
if ($capabilities) {
if (!isset($capabilities[0])) {
$capabilities = array($capabilities);
}
foreach ($capabilities as $protocol) {
$data['data'][] = array('xmlrpc', $protocol['attribs']['version'],
$protocol['_content']);
}
}
if ($soaps) {
if (!isset($soaps[0])) {
$soaps = array($soaps);
}
foreach ($soaps as $protocol) {
$data['data'][] = array('soap', $protocol['attribs']['version'],
$protocol['_content']);
}
}
if ($chan->supportsREST()) {
$funcs = $chan->getFunctions('rest');
if (!isset($funcs[0])) {
$funcs = array($funcs);
}
foreach ($funcs as $protocol) {
$data['data'][] = array('rest', $protocol['attribs']['type'],
$protocol['_content']);
}
}
} else {
$data['data'][] = array('No supported protocols');
}
$d['protocols'] = $data;
$data['data'] = array();
$mirrors = $chan->getMirrors();
if ($mirrors) {
$data['caption'] = 'Channel ' . $channel . ' Mirrors:';
unset($data['headline']);
foreach ($mirrors as $mirror) {
$data['data'][] = array($mirror['attribs']['host']);
$d['mirrors'] = $data;
}
foreach ($mirrors as $mirror) {
$data['data'] = array();
$data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities';
$data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
$capabilities = $chan->getFunctions('xmlrpc', $mirror['attribs']['host']);
$soaps = $chan->getFunctions('soap', $mirror['attribs']['host']);
if ($capabilities || $soaps || $chan->supportsREST($mirror['attribs']['host'])) {
if ($capabilities) {
if (!isset($capabilities[0])) {
$capabilities = array($capabilities);
}
foreach ($capabilities as $protocol) {
$data['data'][] = array('xmlrpc', $protocol['attribs']['version'],
$protocol['_content']);
}
}
if ($soaps) {
if (!isset($soaps[0])) {
$soaps = array($soaps);
}
foreach ($soaps as $protocol) {
$data['data'][] = array('soap', $protocol['attribs']['version'],
$protocol['_content']);
}
}
if ($chan->supportsREST($mirror['attribs']['host'])) {
$funcs = $chan->getFunctions('rest', $mirror['attribs']['host']);
if (!isset($funcs[0])) {
$funcs = array($funcs);
}
foreach ($funcs as $protocol) {
$data['data'][] = array('rest', $protocol['attribs']['type'],
$protocol['_content']);
}
}
} else {
$data['data'][] = array('No supported protocols');
}
$d['mirrorprotocols'] = $data;
}
}
$this->ui->outputData($d, 'channel-info');
} else {
return $this->raiseError('Serious error: Channel "' . $params[0] .
'" has a corrupted registry entry');
}
}
 
// }}}
function doDelete($command, $options, $params)
{
if (sizeof($params) != 1) {
return $this->raiseError('channel-delete: no channel specified');
}
$reg = &$this->config->getRegistry();
if (!$reg->channelExists($params[0])) {
return $this->raiseError('channel-delete: channel "' . $params[0] . '" does not exist');
}
$channel = $reg->channelName($params[0]);
if ($channel == 'pear.php.net') {
return $this->raiseError('Cannot delete the pear.php.net channel');
}
if ($channel == 'pecl.php.net') {
return $this->raiseError('Cannot delete the pecl.php.net channel');
}
if ($channel == '__uri') {
return $this->raiseError('Cannot delete the __uri pseudo-channel');
}
if (PEAR::isError($err = $reg->listPackages($channel))) {
return $err;
}
if (count($err)) {
return $this->raiseError('Channel "' . $channel .
'" has installed packages, cannot delete');
}
if (!$reg->deleteChannel($channel)) {
return $this->raiseError('Channel "' . $channel . '" deletion failed');
} else {
$this->config->deleteChannel($channel);
$this->ui->outputData('Channel "' . $channel . '" deleted', $command);
}
}
 
function doAdd($command, $options, $params)
{
if (sizeof($params) != 1) {
return $this->raiseError('channel-add: no channel file specified');
}
if (strpos($params[0], '://')) {
$downloader = &$this->getDownloader();
if (!class_exists('System')) {
require_once 'System.php';
}
$tmpdir = System::mktemp(array('-d'));
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$loc = $downloader->downloadHttp($params[0], $this->ui, $tmpdir, null, false);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError('channel-add: Cannot open "' . $params[0] . '"');
} else {
list($loc, $lastmodified) = $loc;
$contents = implode('', file($loc));
}
} else {
$lastmodified = $fp = false;
if (file_exists($params[0])) {
$fp = fopen($params[0], 'r');
}
if (!$fp) {
return $this->raiseError('channel-add: cannot open "' . $params[0] . '"');
}
$contents = '';
while (!feof($fp)) {
$contents .= fread($fp, 1024);
}
fclose($fp);
}
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channel = new PEAR_ChannelFile;
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$result = $channel->fromXmlString($contents);
PEAR::staticPopErrorHandling();
if (!$result) {
$exit = false;
if (count($errors = $channel->getErrors(true))) {
foreach ($errors as $error) {
$this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message']));
if (!$exit) {
$exit = $error['level'] == 'error' ? true : false;
}
}
if ($exit) {
return $this->raiseError('channel-add: invalid channel.xml file');
}
}
}
$reg = &$this->config->getRegistry();
if ($reg->channelExists($channel->getName())) {
return $this->raiseError('channel-add: Channel "' . $channel->getName() .
'" exists, use channel-update to update entry');
}
$ret = $reg->addChannel($channel, $lastmodified);
if (PEAR::isError($ret)) {
return $ret;
}
if (!$ret) {
return $this->raiseError('channel-add: adding Channel "' . $channel->getName() .
'" to registry failed');
}
$this->config->setChannels($reg->listChannels());
$this->config->writeConfigFile();
$this->ui->outputData('Adding Channel "' . $channel->getName() . '" succeeded', $command);
}
 
function doUpdate($command, $options, $params)
{
if (!class_exists('System')) {
require_once 'System.php';
}
$tmpdir = System::mktemp(array('-d'));
$reg = &$this->config->getRegistry();
if (sizeof($params) != 1) {
return $this->raiseError("No channel file specified");
}
$lastmodified = false;
if ((!file_exists($params[0]) || is_dir($params[0]))
&& $reg->channelExists(strtolower($params[0]))) {
$c = $reg->getChannel(strtolower($params[0]));
if (PEAR::isError($c)) {
return $this->raiseError($c);
}
$this->ui->outputData('Retrieving channel.xml from remote server');
$dl = &$this->getDownloader(array());
// if force is specified, use a timestamp of "1" to force retrieval
$lastmodified = isset($options['force']) ? false : $c->lastModified();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$contents = $dl->downloadHttp('http://' . $c->getName() . '/channel.xml',
$this->ui, $tmpdir, null, $lastmodified);
PEAR::staticPopErrorHandling();
if (PEAR::isError($contents)) {
return $this->raiseError('Cannot retrieve channel.xml for channel "' .
$c->getName() . '"');
}
list($contents, $lastmodified) = $contents;
if (!$contents) {
$this->ui->outputData("Channel $params[0] channel.xml is up to date");
return;
}
$contents = implode('', file($contents));
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channel = new PEAR_ChannelFile;
$channel->fromXmlString($contents);
if (!$channel->getErrors()) {
// security check: is the downloaded file for the channel we got it from?
if (strtolower($channel->getName()) != strtolower($c->getName())) {
if (isset($options['force'])) {
$this->ui->log(0, 'WARNING: downloaded channel definition file' .
' for channel "' . $channel->getName() . '" from channel "' .
strtolower($c->getName()) . '"');
} else {
return $this->raiseError('ERROR: downloaded channel definition file' .
' for channel "' . $channel->getName() . '" from channel "' .
strtolower($c->getName()) . '"');
}
}
}
} else {
if (strpos($params[0], '://')) {
$dl = &$this->getDownloader();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$loc = $dl->downloadHttp($params[0],
$this->ui, $tmpdir, null, $lastmodified);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError("Cannot open " . $params[0]);
} else {
list($loc, $lastmodified) = $loc;
$contents = implode('', file($loc));
}
} else {
$fp = false;
if (file_exists($params[0])) {
$fp = fopen($params[0], 'r');
}
if (!$fp) {
return $this->raiseError("Cannot open " . $params[0]);
}
$contents = '';
while (!feof($fp)) {
$contents .= fread($fp, 1024);
}
fclose($fp);
}
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channel = new PEAR_ChannelFile;
$channel->fromXmlString($contents);
}
$exit = false;
if (count($errors = $channel->getErrors(true))) {
foreach ($errors as $error) {
$this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message']));
if (!$exit) {
$exit = $error['level'] == 'error' ? true : false;
}
}
if ($exit) {
return $this->raiseError('Invalid channel.xml file');
}
}
if (!$reg->channelExists($channel->getName())) {
return $this->raiseError('Error: Channel "' . $channel->getName() .
'" does not exist, use channel-add to add an entry');
}
$ret = $reg->updateChannel($channel, $lastmodified);
if (PEAR::isError($ret)) {
return $ret;
}
if (!$ret) {
return $this->raiseError('Updating Channel "' . $channel->getName() .
'" in registry failed');
}
$this->config->setChannels($reg->listChannels());
$this->config->writeConfigFile();
$this->ui->outputData('Update of Channel "' . $channel->getName() . '" succeeded');
}
 
function &getDownloader()
{
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
$a = new PEAR_Downloader($this->ui, array(), $this->config);
return $a;
}
 
function doAlias($command, $options, $params)
{
$reg = &$this->config->getRegistry();
if (sizeof($params) == 1) {
return $this->raiseError('No channel alias specified');
}
if (sizeof($params) != 2) {
return $this->raiseError(
'Invalid format, correct is: channel-alias channel alias');
}
if (!$reg->channelExists($params[0], true)) {
if ($reg->isAlias($params[0])) {
$extra = ' (use "channel-alias ' . $reg->channelName($params[0]) . ' ' .
strtolower($params[1]) . '")';
} else {
$extra = '';
}
return $this->raiseError('"' . $params[0] . '" is not a valid channel' . $extra);
}
if ($reg->isAlias($params[1])) {
return $this->raiseError('Channel "' . $reg->channelName($params[1]) . '" is ' .
'already aliased to "' . strtolower($params[1]) . '", cannot re-alias');
}
$chan = &$reg->getChannel($params[0]);
if (PEAR::isError($chan)) {
return $this->raiseError('Corrupt registry? Error retrieving channel "' . $params[0] .
'" information (' . $chan->getMessage() . ')');
}
// make it a local alias
if (!$chan->setAlias(strtolower($params[1]), true)) {
return $this->raiseError('Alias "' . strtolower($params[1]) .
'" is not a valid channel alias');
}
$reg->updateChannel($chan);
$this->ui->outputData('Channel "' . $chan->getName() . '" aliased successfully to "' .
strtolower($params[1]) . '"');
}
 
function doDiscover($command, $options, $params)
{
$reg = &$this->config->getRegistry();
if (sizeof($params) != 1) {
return $this->raiseError("No channel server specified");
}
if ($reg->channelExists($params[0])) {
if ($reg->isAlias($params[0])) {
return $this->raiseError("A channel alias named \"$params[0]\" " .
'already exists, aliasing channel "' . $reg->channelName($params[0])
. '"');
} else {
return $this->raiseError("Channel \"$params[0]\" is already initialized");
}
}
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->doAdd($command, $options, array('http://' . $params[0] . '/channel.xml'));
$this->popErrorHandling();
if (PEAR::isError($err)) {
return $this->raiseError("Discovery of channel \"$params[0]\" failed (" .
$err->getMessage() . ')');
}
$this->ui->outputData("Discovery of channel \"$params[0]\" succeeded", $command);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Remote.php
New file
0,0 → 1,683
<?php
/**
* PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download,
* clear-cache commands)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Remote.php,v 1.96 2006/09/24 03:08:57 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
require_once 'PEAR/REST.php';
 
/**
* PEAR commands for remote server querying
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Remote extends PEAR_Command_Common
{
// {{{ command definitions
 
var $commands = array(
'remote-info' => array(
'summary' => 'Information About Remote Packages',
'function' => 'doRemoteInfo',
'shortcut' => 'ri',
'options' => array(),
'doc' => '<package>
Get details on a package from the server.',
),
'list-upgrades' => array(
'summary' => 'List Available Upgrades',
'function' => 'doListUpgrades',
'shortcut' => 'lu',
'options' => array(),
'doc' => '[preferred_state]
List releases on the server of packages you have installed where
a newer version is available with the same release state (stable etc.)
or the state passed as the second parameter.'
),
'remote-list' => array(
'summary' => 'List Remote Packages',
'function' => 'doRemoteList',
'shortcut' => 'rl',
'options' => array(
'channel' =>
array(
'shortopt' => 'c',
'doc' => 'specify a channel other than the default channel',
'arg' => 'CHAN',
)
),
'doc' => '
Lists the packages available on the configured server along with the
latest stable release of each package.',
),
'search' => array(
'summary' => 'Search remote package database',
'function' => 'doSearch',
'shortcut' => 'sp',
'options' => array(
'channel' =>
array(
'shortopt' => 'c',
'doc' => 'specify a channel other than the default channel',
'arg' => 'CHAN',
)
),
'doc' => '[packagename] [packageinfo]
Lists all packages which match the search parameters. The first
parameter is a fragment of a packagename. The default channel
will be used unless explicitly overridden. The second parameter
will be used to match any portion of the summary/description',
),
'list-all' => array(
'summary' => 'List All Packages',
'function' => 'doListAll',
'shortcut' => 'la',
'options' => array(
'channel' =>
array(
'shortopt' => 'c',
'doc' => 'specify a channel other than the default channel',
'arg' => 'CHAN',
)
),
'doc' => '
Lists the packages available on the configured server along with the
latest stable release of each package.',
),
'download' => array(
'summary' => 'Download Package',
'function' => 'doDownload',
'shortcut' => 'd',
'options' => array(
'nocompress' => array(
'shortopt' => 'Z',
'doc' => 'download an uncompressed (.tar) file',
),
),
'doc' => '<package>...
Download package tarballs. The files will be named as suggested by the
server, for example if you download the DB package and the latest stable
version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.',
),
'clear-cache' => array(
'summary' => 'Clear Web Services Cache',
'function' => 'doClearCache',
'shortcut' => 'cc',
'options' => array(),
'doc' => '
Clear the XML-RPC/REST cache. See also the cache_ttl configuration
parameter.
',
),
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Remote constructor.
*
* @access public
*/
function PEAR_Command_Remote(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
function _checkChannelForStatus($channel, $chan)
{
if (PEAR::isError($chan)) {
$this->raiseError($chan);
}
if (!is_a($chan, 'PEAR_ChannelFile')) {
return $this->raiseError('Internal corruption error: invalid channel "' .
$channel . '"');
}
$rest = new PEAR_REST($this->config);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$a = $rest->downloadHttp('http://' . $channel .
'/channel.xml', $chan->lastModified());
PEAR::staticPopErrorHandling();
if (!PEAR::isError($a) && $a) {
$this->ui->outputData('WARNING: channel "' . $channel . '" has ' .
'updated its protocols, use "channel-update ' . $channel .
'" to update');
}
}
 
// {{{ doRemoteInfo()
 
function doRemoteInfo($command, $options, $params)
{
if (sizeof($params) != 1) {
return $this->raiseError("$command expects one param: the remote package name");
}
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
$package = $params[0];
$parsed = $reg->parsePackageName($package, $channel);
if (PEAR::isError($parsed)) {
return $this->raiseError('Invalid package name "' . $package . '"');
}
$channel = $parsed['channel'];
$this->config->set('default_channel', $channel);
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$info = $rest->packageInfo($base, $parsed['package']);
} else {
$r = &$this->config->getRemote();
$info = $r->call('package.info', $parsed['package']);
}
if (PEAR::isError($info)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError($info);
}
if (!isset($info['name'])) {
return $this->raiseError('No remote package "' . $package . '" was found');
}
 
$installed = $reg->packageInfo($info['name'], null, $channel);
$info['installed'] = $installed['version'] ? $installed['version'] : '- no -';
if (is_array($info['installed'])) {
$info['installed'] = $info['installed']['release'];
}
 
$this->ui->outputData($info, $command);
$this->config->set('default_channel', $savechannel);
 
return true;
}
 
// }}}
// {{{ doRemoteList()
 
function doRemoteList($command, $options, $params)
{
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
if (isset($options['channel'])) {
$channel = $options['channel'];
if ($reg->channelExists($channel)) {
$this->config->set('default_channel', $channel);
} else {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
}
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
$list_options = false;
if ($this->config->get('preferred_state') == 'stable') {
$list_options = true;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
// use faster list-all if available
$rest = &$this->config->getREST('1.1', array());
$available = $rest->listAll($base, $list_options);
} elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$available = $rest->listAll($base, $list_options);
} else {
$r = &$this->config->getRemote();
if ($channel == 'pear.php.net') {
// hack because of poor pearweb design
$available = $r->call('package.listAll', true, $list_options, false);
} else {
$available = $r->call('package.listAll', true, $list_options);
}
}
if (PEAR::isError($available)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError($available);
}
$i = $j = 0;
$data = array(
'caption' => 'Channel ' . $channel . ' Available packages:',
'border' => true,
'headline' => array('Package', 'Version'),
);
if (count($available)==0) {
$data = '(no packages available yet)';
} else {
foreach ($available as $name => $info) {
$data['data'][] = array($name, (isset($info['stable']) && $info['stable'])
? $info['stable'] : '-n/a-');
}
}
$this->ui->outputData($data, $command);
$this->config->set('default_channel', $savechannel);
return true;
}
 
// }}}
// {{{ doListAll()
 
function doListAll($command, $options, $params)
{
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
if (isset($options['channel'])) {
$channel = $options['channel'];
if ($reg->channelExists($channel)) {
$this->config->set('default_channel', $channel);
} else {
return $this->raiseError("Channel \"$channel\" does not exist");
}
}
$list_options = false;
if ($this->config->get('preferred_state') == 'stable') {
$list_options = true;
}
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
// use faster list-all if available
$rest = &$this->config->getREST('1.1', array());
$available = $rest->listAll($base, $list_options, false);
} elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$available = $rest->listAll($base, $list_options, false);
} else {
$r = &$this->config->getRemote();
if ($channel == 'pear.php.net') {
// hack because of poor pearweb design
$available = $r->call('package.listAll', true, $list_options, false);
} else {
$available = $r->call('package.listAll', true, $list_options);
}
}
if (PEAR::isError($available)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")');
}
$data = array(
'caption' => 'All packages:',
'border' => true,
'headline' => array('Package', 'Latest', 'Local'),
);
$local_pkgs = $reg->listPackages($channel);
 
foreach ($available as $name => $info) {
$installed = $reg->packageInfo($name, null, $channel);
if (is_array($installed['version'])) {
$installed['version'] = $installed['version']['release'];
}
$desc = $info['summary'];
if (isset($params[$name])) {
$desc .= "\n\n".$info['description'];
}
if (isset($options['mode']))
{
if ($options['mode'] == 'installed' && !isset($installed['version'])) {
continue;
}
if ($options['mode'] == 'notinstalled' && isset($installed['version'])) {
continue;
}
if ($options['mode'] == 'upgrades'
&& (!isset($installed['version']) || version_compare($installed['version'],
$info['stable'], '>='))) {
continue;
}
}
$pos = array_search(strtolower($name), $local_pkgs);
if ($pos !== false) {
unset($local_pkgs[$pos]);
}
 
if (isset($info['stable']) && !$info['stable']) {
$info['stable'] = null;
}
$data['data'][$info['category']][] = array(
$reg->channelAlias($channel) . '/' . $name,
isset($info['stable']) ? $info['stable'] : null,
isset($installed['version']) ? $installed['version'] : null,
isset($desc) ? $desc : null,
isset($info['deps']) ? $info['deps'] : null,
);
}
 
if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) {
$this->config->set('default_channel', $savechannel);
$this->ui->outputData($data, $command);
return true;
}
foreach ($local_pkgs as $name) {
$info = &$reg->getPackage($name, $channel);
$data['data']['Local'][] = array(
$reg->channelAlias($channel) . '/' . $info->getPackage(),
'',
$info->getVersion(),
$info->getSummary(),
$info->getDeps()
);
}
 
$this->config->set('default_channel', $savechannel);
$this->ui->outputData($data, $command);
return true;
}
 
// }}}
// {{{ doSearch()
 
function doSearch($command, $options, $params)
{
if ((!isset($params[0]) || empty($params[0]))
&& (!isset($params[1]) || empty($params[1])))
{
return $this->raiseError('no valid search string supplied');
};
 
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
$package = $params[0];
$summary = isset($params[1]) ? $params[1] : false;
if (isset($options['channel'])) {
$reg = &$this->config->getRegistry();
$channel = $options['channel'];
if ($reg->channelExists($channel)) {
$this->config->set('default_channel', $channel);
} else {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
}
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$available = $rest->listAll($base, false, false, $package, $summary);
} else {
$r = &$this->config->getRemote();
$available = $r->call('package.search', $package, $summary, true,
$this->config->get('preferred_state') == 'stable', true);
}
if (PEAR::isError($available)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError($available);
}
if (!$available) {
return $this->raiseError('no packages found that match pattern "' . $package . '"');
}
$data = array(
'caption' => 'Matched packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Stable/(Latest)', 'Local'),
);
 
foreach ($available as $name => $info) {
$installed = $reg->packageInfo($name, null, $channel);
$desc = $info['summary'];
if (isset($params[$name]))
$desc .= "\n\n".$info['description'];
 
$unstable = '';
if ($info['unstable']) {
$unstable = '/(' . $info['unstable'] . ' ' . $info['state'] . ')';
}
if (!isset($info['stable']) || !$info['stable']) {
$info['stable'] = 'none';
}
$version = is_array($installed['version']) ? $installed['version']['release'] :
$installed['version'];
$data['data'][$info['category']][] = array(
$name,
$info['stable'] . $unstable,
$version,
$desc,
);
}
$this->ui->outputData($data, $command);
$this->config->set('default_channel', $channel);
return true;
}
 
// }}}
function &getDownloader($options)
{
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
$a = &new PEAR_Downloader($this->ui, $options, $this->config);
return $a;
}
// {{{ doDownload()
 
function doDownload($command, $options, $params)
{
// make certain that dependencies are ignored
$options['downloadonly'] = 1;
 
// eliminate error messages for preferred_state-related errors
/* TODO: Should be an option, but until now download does respect
prefered state */
/* $options['ignorepreferred_state'] = 1; */
// eliminate error messages for preferred_state-related errors
 
$downloader = &$this->getDownloader($options);
$downloader->setDownloadDir(getcwd());
$errors = array();
$downloaded = array();
$err = $downloader->download($params);
if (PEAR::isError($err)) {
return $err;
}
$errors = $downloader->getErrorMsgs();
if (count($errors)) {
foreach ($errors as $error) {
$this->ui->outputData($error);
}
return $this->raiseError("$command failed");
}
$downloaded = $downloader->getDownloadedPackages();
foreach ($downloaded as $pkg) {
$this->ui->outputData("File $pkg[file] downloaded", $command);
}
return true;
}
 
function downloadCallback($msg, $params = null)
{
if ($msg == 'done') {
$this->bytes_downloaded = $params;
}
}
 
// }}}
// {{{ doListUpgrades()
 
function doListUpgrades($command, $options, $params)
{
require_once 'PEAR/Common.php';
if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) {
return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"');
}
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
foreach ($reg->listChannels() as $channel) {
$inst = array_flip($reg->listPackages($channel));
if (!count($inst)) {
continue;
}
if ($channel == '__uri') {
continue;
}
$this->config->set('default_channel', $channel);
if (empty($params[0])) {
$state = $this->config->get('preferred_state');
} else {
$state = $params[0];
}
$caption = $channel . ' Available Upgrades';
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
if (empty($state) || $state == 'any') {
$state = false;
} else {
$caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg);
PEAR::staticPopErrorHandling();
} else {
$remote = &$this->config->getRemote();
$remote->pushErrorHandling(PEAR_ERROR_RETURN);
if (empty($state) || $state == 'any') {
$latest = $remote->call("package.listLatestReleases");
} else {
$latest = $remote->call("package.listLatestReleases", $state);
$caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
}
$remote->popErrorHandling();
}
if (PEAR::isError($latest)) {
$this->ui->outputData($latest->getMessage());
continue;
}
$caption .= ':';
if (PEAR::isError($latest)) {
$this->config->set('default_channel', $savechannel);
return $latest;
}
$data = array(
'caption' => $caption,
'border' => 1,
'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'),
);
foreach ((array)$latest as $pkg => $info) {
$package = strtolower($pkg);
if (!isset($inst[$package])) {
// skip packages we don't have installed
continue;
}
extract($info);
$inst_version = $reg->packageInfo($package, 'version', $channel);
$inst_state = $reg->packageInfo($package, 'release_state', $channel);
if (version_compare("$version", "$inst_version", "le")) {
// installed version is up-to-date
continue;
}
if ($filesize >= 20480) {
$filesize += 1024 - ($filesize % 1024);
$fs = sprintf("%dkB", $filesize / 1024);
} elseif ($filesize > 0) {
$filesize += 103 - ($filesize % 103);
$fs = sprintf("%.1fkB", $filesize / 1024.0);
} else {
$fs = " -"; // XXX center instead
}
$data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs);
}
if (empty($data['data'])) {
$this->ui->outputData('Channel ' . $channel . ': No upgrades available');
} else {
$this->ui->outputData($data, $command);
}
}
$this->config->set('default_channel', $savechannel);
return true;
}
 
// }}}
// {{{ doClearCache()
 
function doClearCache($command, $options, $params)
{
$cache_dir = $this->config->get('cache_dir');
$verbose = $this->config->get('verbose');
$output = '';
if (!file_exists($cache_dir) || !is_dir($cache_dir)) {
return $this->raiseError("$cache_dir does not exist or is not a directory");
}
if (!($dp = @opendir($cache_dir))) {
return $this->raiseError("opendir($cache_dir) failed: $php_errormsg");
}
if ($verbose >= 1) {
$output .= "reading directory $cache_dir\n";
}
$num = 0;
while ($ent = readdir($dp)) {
if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}$/', $ent) ||
preg_match('/rest.cache(file|id)$/', $ent)) {
$path = $cache_dir . DIRECTORY_SEPARATOR . $ent;
if (file_exists($path)) {
$ok = @unlink($path);
} else {
$ok = false;
$php_errormsg = '';
}
if ($ok) {
if ($verbose >= 2) {
$output .= "deleted $path\n";
}
$num++;
} elseif ($verbose >= 1) {
$output .= "failed to delete $path $php_errormsg\n";
}
}
}
closedir($dp);
if ($verbose >= 1) {
$output .= "$num cache entries cleared\n";
}
$this->ui->outputData(rtrim($output), $command);
return $num;
}
 
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Build.php
New file
0,0 → 1,104
<?php
/**
* PEAR_Command_Auth (build command)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Build.php,v 1.13 2006/01/06 04:47:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
 
/**
* PEAR commands for building extensions.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Build extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'build' => array(
'summary' => 'Build an Extension From C Source',
'function' => 'doBuild',
'shortcut' => 'b',
'options' => array(),
'doc' => '[package.xml]
Builds one or more extensions contained in a package.'
),
);
 
// }}}
 
// {{{ constructor
 
/**
* PEAR_Command_Build constructor.
*
* @access public
*/
function PEAR_Command_Build(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ doBuild()
 
function doBuild($command, $options, $params)
{
require_once 'PEAR/Builder.php';
if (sizeof($params) < 1) {
$params[0] = 'package.xml';
}
$builder = &new PEAR_Builder($this->ui);
$this->debug = $this->config->get('verbose');
$err = $builder->build($params[0], array(&$this, 'buildCallback'));
if (PEAR::isError($err)) {
return $err;
}
return true;
}
 
// }}}
// {{{ buildCallback()
 
function buildCallback($what, $data)
{
if (($what == 'cmdoutput' && $this->debug > 1) ||
($what == 'output' && $this->debug > 0)) {
$this->ui->outputData(rtrim($data), 'build');
}
}
 
// }}}
}
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Auth.php
New file
0,0 → 1,186
<?php
/**
* PEAR_Command_Auth (login, logout commands)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Auth.php,v 1.24 2006/03/05 21:23:21 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
require_once 'PEAR/Config.php';
 
/**
* PEAR commands for login/logout
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Auth extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'login' => array(
'summary' => 'Connects and authenticates to remote server',
'shortcut' => 'li',
'function' => 'doLogin',
'options' => array(),
'doc' => '
Log in to the remote server. To use remote functions in the installer
that require any kind of privileges, you need to log in first. The
username and password you enter here will be stored in your per-user
PEAR configuration (~/.pearrc on Unix-like systems). After logging
in, your username and password will be sent along in subsequent
operations on the remote server.',
),
'logout' => array(
'summary' => 'Logs out from the remote server',
'shortcut' => 'lo',
'function' => 'doLogout',
'options' => array(),
'doc' => '
Logs out from the remote server. This command does not actually
connect to the remote server, it only deletes the stored username and
password from your user configuration.',
)
 
);
 
// }}}
 
// {{{ constructor
 
/**
* PEAR_Command_Auth constructor.
*
* @access public
*/
function PEAR_Command_Auth(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ doLogin()
 
/**
* Execute the 'login' command.
*
* @param string $command command name
*
* @param array $options option_name => value
*
* @param array $params list of additional parameters
*
* @return bool TRUE on success or
* a PEAR error on failure
*
* @access public
*/
function doLogin($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$channel = $this->config->get('default_channel');
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
$server = $this->config->get('preferred_mirror');
$remote = &$this->config->getRemote();
$username = $this->config->get('username');
if (empty($username)) {
$username = isset($_ENV['USER']) ? $_ENV['USER'] : null;
}
$this->ui->outputData("Logging in to $server.", $command);
list($username, $password) = $this->ui->userDialog(
$command,
array('Username', 'Password'),
array('text', 'password'),
array($username, '')
);
$username = trim($username);
$password = trim($password);
$this->config->set('username', $username);
$this->config->set('password', $password);
 
if ($chan->supportsREST()) {
$ok = true;
} else {
$remote->expectError(401);
$ok = $remote->call('logintest');
$remote->popExpect();
}
if ($ok === true) {
$this->ui->outputData("Logged in.", $command);
$this->config->store();
} else {
return $this->raiseError("Login failed!");
}
return true;
}
 
// }}}
// {{{ doLogout()
 
/**
* Execute the 'logout' command.
*
* @param string $command command name
*
* @param array $options option_name => value
*
* @param array $params list of additional parameters
*
* @return bool TRUE on success or
* a PEAR error on failure
*
* @access public
*/
function doLogout($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$channel = $this->config->get('default_channel');
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
$server = $this->config->get('preferred_mirror');
$this->ui->outputData("Logging out from $server.", $command);
$this->config->remove('username');
$this->config->remove('password');
$this->config->store();
return true;
}
 
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Remote.xml
New file
0,0 → 1,92
<commands version="1.0">
<remote-info>
<summary>Information About Remote Packages</summary>
<function>doRemoteInfo</function>
<shortcut>ri</shortcut>
<options />
<doc>&lt;package&gt;
Get details on a package from the server.</doc>
</remote-info>
<list-upgrades>
<summary>List Available Upgrades</summary>
<function>doListUpgrades</function>
<shortcut>lu</shortcut>
<options />
<doc>[preferred_state]
List releases on the server of packages you have installed where
a newer version is available with the same release state (stable etc.)
or the state passed as the second parameter.</doc>
</list-upgrades>
<remote-list>
<summary>List Remote Packages</summary>
<function>doRemoteList</function>
<shortcut>rl</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>
Lists the packages available on the configured server along with the
latest stable release of each package.</doc>
</remote-list>
<search>
<summary>Search remote package database</summary>
<function>doSearch</function>
<shortcut>sp</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>[packagename] [packageinfo]
Lists all packages which match the search parameters. The first
parameter is a fragment of a packagename. The default channel
will be used unless explicitly overridden. The second parameter
will be used to match any portion of the summary/description</doc>
</search>
<list-all>
<summary>List All Packages</summary>
<function>doListAll</function>
<shortcut>la</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>
Lists the packages available on the configured server along with the
latest stable release of each package.</doc>
</list-all>
<download>
<summary>Download Package</summary>
<function>doDownload</function>
<shortcut>d</shortcut>
<options>
<nocompress>
<shortopt>Z</shortopt>
<doc>download an uncompressed (.tar) file</doc>
</nocompress>
</options>
<doc>&lt;package&gt;...
Download package tarballs. The files will be named as suggested by the
server, for example if you download the DB package and the latest stable
version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.</doc>
</download>
<clear-cache>
<summary>Clear Web Services Cache</summary>
<function>doClearCache</function>
<shortcut>cc</shortcut>
<options />
<doc>
Clear the XML-RPC/REST cache. See also the cache_ttl configuration
parameter.
</doc>
</clear-cache>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Channels.xml
New file
0,0 → 1,93
<commands version="1.0">
<list-channels>
<summary>List Available Channels</summary>
<function>doList</function>
<shortcut>lc</shortcut>
<options />
<doc>
List all available channels for installation.
</doc>
</list-channels>
<update-channels>
<summary>Update the Channel List</summary>
<function>doUpdateAll</function>
<shortcut>uc</shortcut>
<options />
<doc>
List all installed packages in all channels.
</doc>
</update-channels>
<channel-delete>
<summary>Remove a Channel From the List</summary>
<function>doDelete</function>
<shortcut>cde</shortcut>
<options />
<doc>&lt;channel name&gt;
Delete a channel from the registry. You may not
remove any channel that has installed packages.
</doc>
</channel-delete>
<channel-add>
<summary>Add a Channel</summary>
<function>doAdd</function>
<shortcut>ca</shortcut>
<options />
<doc>&lt;channel.xml&gt;
Add a private channel to the channel list. Note that all
public channels should be synced using &quot;update-channels&quot;.
Parameter may be either a local file or remote URL to a
channel.xml.
</doc>
</channel-add>
<channel-update>
<summary>Update an Existing Channel</summary>
<function>doUpdate</function>
<shortcut>cu</shortcut>
<options>
<force>
<shortopt>f</shortopt>
<doc>will force download of new channel.xml if an existing channel name is used</doc>
</force>
<channel>
<shortopt>c</shortopt>
<arg>CHANNEL</arg>
<doc>will force download of new channel.xml if an existing channel name is used</doc>
</channel>
</options>
<doc>[&lt;channel.xml&gt;|&lt;channel name&gt;]
Update a channel in the channel list directly. Note that all
public channels can be synced using &quot;update-channels&quot;.
Parameter may be a local or remote channel.xml, or the name of
an existing channel.
</doc>
</channel-update>
<channel-info>
<summary>Retrieve Information on a Channel</summary>
<function>doInfo</function>
<shortcut>ci</shortcut>
<options />
<doc>&lt;package&gt;
List the files in an installed package.
</doc>
</channel-info>
<channel-alias>
<summary>Specify an alias to a channel name</summary>
<function>doAlias</function>
<shortcut>cha</shortcut>
<options />
<doc>&lt;channel&gt; &lt;alias&gt;
Specify a specific alias to use for a channel name.
The alias may not be an existing channel name or
alias.
</doc>
</channel-alias>
<channel-discover>
<summary>Initialize a Channel from its server</summary>
<function>doDiscover</function>
<shortcut>di</shortcut>
<options />
<doc>[&lt;channel.xml&gt;|&lt;channel name&gt;]
Initialize a Channel from its server and create the local channel.xml.
</doc>
</channel-discover>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Package.xml
New file
0,0 → 1,194
<commands version="1.0">
<package>
<summary>Build Package</summary>
<function>doPackage</function>
<shortcut>p</shortcut>
<options>
<nocompress>
<shortopt>Z</shortopt>
<doc>Do not gzip the package file</doc>
</nocompress>
<showname>
<shortopt>n</shortopt>
<doc>Print the name of the packaged file.</doc>
</showname>
</options>
<doc>[descfile] [descfile2]
Creates a PEAR package from its description file (usually called
package.xml). If a second packagefile is passed in, then
the packager will check to make sure that one is a package.xml
version 1.0, and the other is a package.xml version 2.0. The
package.xml version 1.0 will be saved as &quot;package.xml&quot; in the archive,
and the other as &quot;package2.xml&quot; in the archive&quot;
</doc>
</package>
<package-validate>
<summary>Validate Package Consistency</summary>
<function>doPackageValidate</function>
<shortcut>pv</shortcut>
<options />
<doc>
</doc>
</package-validate>
<cvsdiff>
<summary>Run a &quot;cvs diff&quot; for all files in a package</summary>
<function>doCvsDiff</function>
<shortcut>cd</shortcut>
<options>
<quiet>
<shortopt>q</shortopt>
<doc>Be quiet</doc>
</quiet>
<reallyquiet>
<shortopt>Q</shortopt>
<doc>Be really quiet</doc>
</reallyquiet>
<date>
<shortopt>D</shortopt>
<doc>Diff against revision of DATE</doc>
<arg>DATE</arg>
</date>
<release>
<shortopt>R</shortopt>
<doc>Diff against tag for package release REL</doc>
<arg>REL</arg>
</release>
<revision>
<shortopt>r</shortopt>
<doc>Diff against revision REV</doc>
<arg>REV</arg>
</revision>
<context>
<shortopt>c</shortopt>
<doc>Generate context diff</doc>
</context>
<unified>
<shortopt>u</shortopt>
<doc>Generate unified diff</doc>
</unified>
<ignore-case>
<shortopt>i</shortopt>
<doc>Ignore case, consider upper- and lower-case letters equivalent</doc>
</ignore-case>
<ignore-whitespace>
<shortopt>b</shortopt>
<doc>Ignore changes in amount of white space</doc>
</ignore-whitespace>
<ignore-blank-lines>
<shortopt>B</shortopt>
<doc>Ignore changes that insert or delete blank lines</doc>
</ignore-blank-lines>
<brief>
<doc>Report only whether the files differ, no details</doc>
</brief>
<dry-run>
<shortopt>n</shortopt>
<doc>Don&apos;t do anything, just pretend</doc>
</dry-run>
</options>
<doc>&lt;package.xml&gt;
Compares all the files in a package. Without any options, this
command will compare the current code with the last checked-in code.
Using the -r or -R option you may compare the current code with that
of a specific release.
</doc>
</cvsdiff>
<cvstag>
<summary>Set CVS Release Tag</summary>
<function>doCvsTag</function>
<shortcut>ct</shortcut>
<options>
<quiet>
<shortopt>q</shortopt>
<doc>Be quiet</doc>
</quiet>
<reallyquiet>
<shortopt>Q</shortopt>
<doc>Be really quiet</doc>
</reallyquiet>
<slide>
<shortopt>F</shortopt>
<doc>Move (slide) tag if it exists</doc>
</slide>
<delete>
<shortopt>d</shortopt>
<doc>Remove tag</doc>
</delete>
<dry-run>
<shortopt>n</shortopt>
<doc>Don&apos;t do anything, just pretend</doc>
</dry-run>
</options>
<doc>&lt;package.xml&gt;
Sets a CVS tag on all files in a package. Use this command after you have
packaged a distribution tarball with the &quot;package&quot; command to tag what
revisions of what files were in that release. If need to fix something
after running cvstag once, but before the tarball is released to the public,
use the &quot;slide&quot; option to move the release tag.
</doc>
</cvstag>
<package-dependencies>
<summary>Show package dependencies</summary>
<function>doPackageDependencies</function>
<shortcut>pd</shortcut>
<options />
<doc>
List all dependencies the package has.</doc>
</package-dependencies>
<sign>
<summary>Sign a package distribution file</summary>
<function>doSign</function>
<shortcut>si</shortcut>
<options />
<doc>&lt;package-file&gt;
Signs a package distribution (.tar or .tgz) file with GnuPG.</doc>
</sign>
<makerpm>
<summary>Builds an RPM spec file from a PEAR package</summary>
<function>doMakeRPM</function>
<shortcut>rpm</shortcut>
<options>
<spec-template>
<shortopt>t</shortopt>
<arg>FILE</arg>
<doc>Use FILE as RPM spec file template</doc>
</spec-template>
<rpm-pkgname>
<shortopt>p</shortopt>
<arg>FORMAT</arg>
<doc>Use FORMAT as format string for RPM package name, %s is replaced
by the PEAR package name, defaults to &quot;PEAR::%s&quot;.</doc>
</rpm-pkgname>
</options>
<doc>&lt;package-file&gt;
 
Creates an RPM .spec file for wrapping a PEAR package inside an RPM
package. Intended to be used from the SPECS directory, with the PEAR
package tarball in the SOURCES directory:
 
$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz
Wrote RPM spec file PEAR::Net_Geo-1.0.spec
$ rpm -bb PEAR::Net_Socket-1.0.spec
...
Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm
</doc>
</makerpm>
<convert>
<summary>Convert a package.xml 1.0 to package.xml 2.0 format</summary>
<function>doConvert</function>
<shortcut>c2</shortcut>
<options>
<flat>
<shortopt>f</shortopt>
<doc>do not beautify the filelist.</doc>
</flat>
</options>
<doc>[descfile] [descfile2]
Converts a package.xml in 1.0 format into a package.xml
in 2.0 format. The new file will be named package2.xml by default,
and package.xml will be used as the old file by default.
This is not the most intelligent conversion, and should only be
used for automated conversion or learning the format.
</doc>
</convert>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Config.php
New file
0,0 → 1,418
<?php
/**
* PEAR_Command_Config (config-show, config-get, config-set, config-help, config-create commands)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Config.php,v 1.52 2006/03/05 21:32:47 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
 
/**
* PEAR commands for managing configuration data.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Config extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'config-show' => array(
'summary' => 'Show All Settings',
'function' => 'doConfigShow',
'shortcut' => 'csh',
'options' => array(
'channel' => array(
'shortopt' => 'c',
'doc' => 'show configuration variables for another channel',
'arg' => 'CHAN',
),
),
'doc' => '[layer]
Displays all configuration values. An optional argument
may be used to tell which configuration layer to display. Valid
configuration layers are "user", "system" and "default". To display
configurations for different channels, set the default_channel
configuration variable and run config-show again.
',
),
'config-get' => array(
'summary' => 'Show One Setting',
'function' => 'doConfigGet',
'shortcut' => 'cg',
'options' => array(
'channel' => array(
'shortopt' => 'c',
'doc' => 'show configuration variables for another channel',
'arg' => 'CHAN',
),
),
'doc' => '<parameter> [layer]
Displays the value of one configuration parameter. The
first argument is the name of the parameter, an optional second argument
may be used to tell which configuration layer to look in. Valid configuration
layers are "user", "system" and "default". If no layer is specified, a value
will be picked from the first layer that defines the parameter, in the order
just specified. The configuration value will be retrieved for the channel
specified by the default_channel configuration variable.
',
),
'config-set' => array(
'summary' => 'Change Setting',
'function' => 'doConfigSet',
'shortcut' => 'cs',
'options' => array(
'channel' => array(
'shortopt' => 'c',
'doc' => 'show configuration variables for another channel',
'arg' => 'CHAN',
),
),
'doc' => '<parameter> <value> [layer]
Sets the value of one configuration parameter. The first argument is
the name of the parameter, the second argument is the new value. Some
parameters are subject to validation, and the command will fail with
an error message if the new value does not make sense. An optional
third argument may be used to specify in which layer to set the
configuration parameter. The default layer is "user". The
configuration value will be set for the current channel, which
is controlled by the default_channel configuration variable.
',
),
'config-help' => array(
'summary' => 'Show Information About Setting',
'function' => 'doConfigHelp',
'shortcut' => 'ch',
'options' => array(),
'doc' => '[parameter]
Displays help for a configuration parameter. Without arguments it
displays help for all configuration parameters.
',
),
'config-create' => array(
'summary' => 'Create a Default configuration file',
'function' => 'doConfigCreate',
'shortcut' => 'coc',
'options' => array(
'windows' => array(
'shortopt' => 'w',
'doc' => 'create a config file for a windows install',
),
),
'doc' => '<root path> <filename>
Create a default configuration file with all directory configuration
variables set to subdirectories of <root path>, and save it as <filename>.
This is useful especially for creating a configuration file for a remote
PEAR installation (using the --remoteconfig option of install, upgrade,
and uninstall).
',
),
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Config constructor.
*
* @access public
*/
function PEAR_Command_Config(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ doConfigShow()
 
function doConfigShow($command, $options, $params)
{
if (is_array($params)) {
$layer = isset($params[0]) ? $params[0] : NULL;
} else {
$layer = NULL;
}
 
// $params[0] -> the layer
if ($error = $this->_checkLayer($layer)) {
return $this->raiseError("config-show:$error");
}
$keys = $this->config->getKeys();
sort($keys);
$channel = isset($options['channel']) ? $options['channel'] :
$this->config->get('default_channel');
$reg = &$this->config->getRegistry();
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
$data = array('caption' => 'Configuration (channel ' . $channel . '):');
foreach ($keys as $key) {
$type = $this->config->getType($key);
$value = $this->config->get($key, $layer, $channel);
if ($type == 'password' && $value) {
$value = '********';
}
if ($value === false) {
$value = 'false';
} elseif ($value === true) {
$value = 'true';
}
$data['data'][$this->config->getGroup($key)][] = array($this->config->getPrompt($key) , $key, $value);
}
foreach ($this->config->getLayers() as $layer) {
$data['data']['Config Files'][] = array(ucfirst($layer) . ' Configuration File', 'Filename' , $this->config->getConfFile($layer));
}
 
$this->ui->outputData($data, $command);
return true;
}
 
// }}}
// {{{ doConfigGet()
 
function doConfigGet($command, $options, $params)
{
if (!is_array($params)) {
$args_cnt = 0;
} else {
$args_cnt = count($params);
}
 
switch ($args_cnt) {
case 1:
$config_key = $params[0];
$layer = NULL;
break;
case 2:
$config_key = $params[0];
$layer = $params[1];
if ($error = $this->_checkLayer($layer)) {
return $this->raiseError("config-get:$error");
}
break;
case 0:
default:
return $this->raiseError("config-get expects 1 or 2 parameters");
}
 
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
 
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
 
$this->ui->outputData($this->config->get($config_key, $layer, $channel), $command);
 
return true;
}
 
// }}}
// {{{ doConfigSet()
 
function doConfigSet($command, $options, $params)
{
// $param[0] -> a parameter to set
// $param[1] -> the value for the parameter
// $param[2] -> the layer
$failmsg = '';
if (sizeof($params) < 2 || sizeof($params) > 3) {
$failmsg .= "config-set expects 2 or 3 parameters";
return PEAR::raiseError($failmsg);
}
if (isset($params[2]) && ($error = $this->_checkLayer($params[2]))) {
$failmsg .= $error;
return PEAR::raiseError("config-set:$failmsg");
}
$channel = isset($options['channel']) ? $options['channel'] :
$this->config->get('default_channel');
$reg = &$this->config->getRegistry();
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
if ($params[0] == 'default_channel') {
if (!$reg->channelExists($params[1])) {
return $this->raiseError('Channel "' . $params[1] . '" does not exist');
}
}
if (count($params) == 2) {
array_push($params, 'user');
$layer = 'user';
} else {
$layer = $params[2];
}
array_push($params, $channel);
if (!call_user_func_array(array(&$this->config, 'set'), $params))
{
array_pop($params);
$failmsg = "config-set (" . implode(", ", $params) . ") failed, channel $channel";
} else {
$this->config->store($layer);
}
if ($failmsg) {
return $this->raiseError($failmsg);
}
$this->ui->outputData('config-set succeeded', $command);
return true;
}
 
// }}}
// {{{ doConfigHelp()
 
function doConfigHelp($command, $options, $params)
{
if (empty($params)) {
$params = $this->config->getKeys();
}
$data['caption'] = "Config help" . ((count($params) == 1) ? " for $params[0]" : '');
$data['headline'] = array('Name', 'Type', 'Description');
$data['border'] = true;
foreach ($params as $name) {
$type = $this->config->getType($name);
$docs = $this->config->getDocs($name);
if ($type == 'set') {
$docs = rtrim($docs) . "\nValid set: " .
implode(' ', $this->config->getSetValues($name));
}
$data['data'][] = array($name, $type, $docs);
}
$this->ui->outputData($data, $command);
}
 
// }}}
// {{{ doConfigCreate()
 
function doConfigCreate($command, $options, $params)
{
if (count($params) != 2) {
return PEAR::raiseError('config-create: must have 2 parameters, root path and ' .
'filename to save as');
}
$root = $params[0];
// Clean up the DIRECTORY_SEPARATOR mess
$ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
$root = preg_replace(array('!\\\\+!', '!/+!', "!$ds2+!"),
array('/', '/', '/'),
$root);
if ($root{0} != '/') {
if (isset($options['windows'])) {
if (!preg_match('/^[A-Za-z]:/', $root)) {
return PEAR::raiseError('Root directory must be an absolute path beginning ' .
'with "\\" or "C:\\", was: "' . $root . '"');
}
} else {
return PEAR::raiseError('Root directory must be an absolute path beginning ' .
'with "/", was: "' . $root . '"');
}
}
$windows = isset($options['windows']);
if ($windows) {
$root = str_replace('/', '\\', $root);
}
if (!file_exists($params[1])) {
if (!@touch($params[1])) {
return PEAR::raiseError('Could not create "' . $params[1] . '"');
}
}
$params[1] = realpath($params[1]);
$config = &new PEAR_Config($params[1], '#no#system#config#', false, false);
if ($root{strlen($root) - 1} == '/') {
$root = substr($root, 0, strlen($root) - 1);
}
$config->noRegistry();
$config->set('php_dir', $windows ? "$root\\pear\\php" : "$root/pear/php", 'user');
$config->set('data_dir', $windows ? "$root\\pear\\data" : "$root/pear/data");
$config->set('ext_dir', $windows ? "$root\\pear\\ext" : "$root/pear/ext");
$config->set('doc_dir', $windows ? "$root\\pear\\docs" : "$root/pear/docs");
$config->set('test_dir', $windows ? "$root\\pear\\tests" : "$root/pear/tests");
$config->set('cache_dir', $windows ? "$root\\pear\\cache" : "$root/pear/cache");
$config->set('bin_dir', $windows ? "$root\\pear" : "$root/pear");
$config->writeConfigFile();
$this->_showConfig($config);
$this->ui->outputData('Successfully created default configuration file "' . $params[1] . '"',
$command);
}
 
// }}}
 
function _showConfig(&$config)
{
$params = array('user');
$keys = $config->getKeys();
sort($keys);
$channel = 'pear.php.net';
$data = array('caption' => 'Configuration (channel ' . $channel . '):');
foreach ($keys as $key) {
$type = $config->getType($key);
$value = $config->get($key, 'user', $channel);
if ($type == 'password' && $value) {
$value = '********';
}
if ($value === false) {
$value = 'false';
} elseif ($value === true) {
$value = 'true';
}
$data['data'][$config->getGroup($key)][] =
array($config->getPrompt($key) , $key, $value);
}
foreach ($config->getLayers() as $layer) {
$data['data']['Config Files'][] =
array(ucfirst($layer) . ' Configuration File', 'Filename' ,
$config->getConfFile($layer));
}
 
$this->ui->outputData($data, 'config-show');
return true;
}
// {{{ _checkLayer()
 
/**
* Checks if a layer is defined or not
*
* @param string $layer The layer to search for
* @return mixed False on no error or the error message
*/
function _checkLayer($layer = null)
{
if (!empty($layer) && $layer != 'default') {
$layers = $this->config->getLayers();
if (!in_array($layer, $layers)) {
return " only the layers: \"" . implode('" or "', $layers) . "\" are supported";
}
}
return false;
}
 
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Install.php
New file
0,0 → 1,1039
<?php
/**
* PEAR_Command_Install (install, upgrade, upgrade-all, uninstall, bundle, run-scripts commands)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Install.php,v 1.122 2007/02/13 04:30:05 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
 
/**
* PEAR commands for installation or deinstallation/upgrading of
* packages.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Install extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'install' => array(
'summary' => 'Install Package',
'function' => 'doInstall',
'shortcut' => 'i',
'options' => array(
'force' => array(
'shortopt' => 'f',
'doc' => 'will overwrite newer installed packages',
),
'loose' => array(
'shortopt' => 'l',
'doc' => 'do not check for recommended dependency version',
),
'nodeps' => array(
'shortopt' => 'n',
'doc' => 'ignore dependencies, install anyway',
),
'register-only' => array(
'shortopt' => 'r',
'doc' => 'do not install files, only register the package as installed',
),
'soft' => array(
'shortopt' => 's',
'doc' => 'soft install, fail silently, or upgrade if already installed',
),
'nobuild' => array(
'shortopt' => 'B',
'doc' => 'don\'t build C extensions',
),
'nocompress' => array(
'shortopt' => 'Z',
'doc' => 'request uncompressed files when downloading',
),
'installroot' => array(
'shortopt' => 'R',
'arg' => 'DIR',
'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
),
'packagingroot' => array(
'shortopt' => 'P',
'arg' => 'DIR',
'doc' => 'root directory used when packaging files, like RPM packaging',
),
'ignore-errors' => array(
'doc' => 'force install even if there were errors',
),
'alldeps' => array(
'shortopt' => 'a',
'doc' => 'install all required and optional dependencies',
),
'onlyreqdeps' => array(
'shortopt' => 'o',
'doc' => 'install all required dependencies',
),
'offline' => array(
'shortopt' => 'O',
'doc' => 'do not attempt to download any urls or contact channels',
),
'pretend' => array(
'shortopt' => 'p',
'doc' => 'Only list the packages that would be downloaded',
),
),
'doc' => '[channel/]<package> ...
Installs one or more PEAR packages. You can specify a package to
install in four ways:
 
"Package-1.0.tgz" : installs from a local file
 
"http://example.com/Package-1.0.tgz" : installs from
anywhere on the net.
 
"package.xml" : installs the package described in
package.xml. Useful for testing, or for wrapping a PEAR package in
another package manager such as RPM.
 
"Package[-version/state][.tar]" : queries your default channel\'s server
({config master_server}) and downloads the newest package with
the preferred quality/state ({config preferred_state}).
 
To retrieve Package version 1.1, use "Package-1.1," to retrieve
Package state beta, use "Package-beta." To retrieve an uncompressed
file, append .tar (make sure there is no file by the same name first)
 
To download a package from another channel, prefix with the channel name like
"channel/Package"
 
More than one package may be specified at once. It is ok to mix these
four ways of specifying packages.
'),
'upgrade' => array(
'summary' => 'Upgrade Package',
'function' => 'doInstall',
'shortcut' => 'up',
'options' => array(
'force' => array(
'shortopt' => 'f',
'doc' => 'overwrite newer installed packages',
),
'loose' => array(
'shortopt' => 'l',
'doc' => 'do not check for recommended dependency version',
),
'nodeps' => array(
'shortopt' => 'n',
'doc' => 'ignore dependencies, upgrade anyway',
),
'register-only' => array(
'shortopt' => 'r',
'doc' => 'do not install files, only register the package as upgraded',
),
'nobuild' => array(
'shortopt' => 'B',
'doc' => 'don\'t build C extensions',
),
'nocompress' => array(
'shortopt' => 'Z',
'doc' => 'request uncompressed files when downloading',
),
'installroot' => array(
'shortopt' => 'R',
'arg' => 'DIR',
'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
),
'packagingroot' => array(
'shortopt' => 'P',
'arg' => 'DIR',
'doc' => 'root directory used when packaging files, like RPM packaging',
),
'ignore-errors' => array(
'doc' => 'force install even if there were errors',
),
'alldeps' => array(
'shortopt' => 'a',
'doc' => 'install all required and optional dependencies',
),
'onlyreqdeps' => array(
'shortopt' => 'o',
'doc' => 'install all required dependencies',
),
'offline' => array(
'shortopt' => 'O',
'doc' => 'do not attempt to download any urls or contact channels',
),
'pretend' => array(
'shortopt' => 'p',
'doc' => 'Only list the packages that would be downloaded',
),
),
'doc' => '<package> ...
Upgrades one or more PEAR packages. See documentation for the
"install" command for ways to specify a package.
 
When upgrading, your package will be updated if the provided new
package has a higher version number (use the -f option if you need to
upgrade anyway).
 
More than one package may be specified at once.
'),
'upgrade-all' => array(
'summary' => 'Upgrade All Packages',
'function' => 'doInstall',
'shortcut' => 'ua',
'options' => array(
'nodeps' => array(
'shortopt' => 'n',
'doc' => 'ignore dependencies, upgrade anyway',
),
'register-only' => array(
'shortopt' => 'r',
'doc' => 'do not install files, only register the package as upgraded',
),
'nobuild' => array(
'shortopt' => 'B',
'doc' => 'don\'t build C extensions',
),
'nocompress' => array(
'shortopt' => 'Z',
'doc' => 'request uncompressed files when downloading',
),
'installroot' => array(
'shortopt' => 'R',
'arg' => 'DIR',
'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
),
'ignore-errors' => array(
'doc' => 'force install even if there were errors',
),
'loose' => array(
'doc' => 'do not check for recommended dependency version',
),
),
'doc' => '
Upgrades all packages that have a newer release available. Upgrades are
done only if there is a release available of the state specified in
"preferred_state" (currently {config preferred_state}), or a state considered
more stable.
'),
'uninstall' => array(
'summary' => 'Un-install Package',
'function' => 'doUninstall',
'shortcut' => 'un',
'options' => array(
'nodeps' => array(
'shortopt' => 'n',
'doc' => 'ignore dependencies, uninstall anyway',
),
'register-only' => array(
'shortopt' => 'r',
'doc' => 'do not remove files, only register the packages as not installed',
),
'installroot' => array(
'shortopt' => 'R',
'arg' => 'DIR',
'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)',
),
'ignore-errors' => array(
'doc' => 'force install even if there were errors',
),
'offline' => array(
'shortopt' => 'O',
'doc' => 'do not attempt to uninstall remotely',
),
),
'doc' => '[channel/]<package> ...
Uninstalls one or more PEAR packages. More than one package may be
specified at once. Prefix with channel name to uninstall from a
channel not in your default channel ({config default_channel})
'),
'bundle' => array(
'summary' => 'Unpacks a Pecl Package',
'function' => 'doBundle',
'shortcut' => 'bun',
'options' => array(
'destination' => array(
'shortopt' => 'd',
'arg' => 'DIR',
'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)',
),
'force' => array(
'shortopt' => 'f',
'doc' => 'Force the unpacking even if there were errors in the package',
),
),
'doc' => '<package>
Unpacks a Pecl Package into the selected location. It will download the
package if needed.
'),
'run-scripts' => array(
'summary' => 'Run Post-Install Scripts bundled with a package',
'function' => 'doRunScripts',
'shortcut' => 'rs',
'options' => array(
),
'doc' => '<package>
Run post-installation scripts in package <package>, if any exist.
'),
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Install constructor.
*
* @access public
*/
function PEAR_Command_Install(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
/**
* For unit testing purposes
*/
function &getDownloader(&$ui, $options, &$config)
{
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
$a = &new PEAR_Downloader($ui, $options, $config);
return $a;
}
 
/**
* For unit testing purposes
*/
function &getInstaller(&$ui)
{
if (!class_exists('PEAR_Installer')) {
require_once 'PEAR/Installer.php';
}
$a = &new PEAR_Installer($ui);
return $a;
}
 
function enableExtension($binaries, $type)
{
if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) {
return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location');
}
$ini = $this->_parseIni($phpini);
if (PEAR::isError($ini)) {
return $ini;
}
$fp = @fopen($phpini, 'wb');
if (!$fp) {
return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
}
$line = 0;
if ($type == 'extsrc' || $type == 'extbin') {
$search = 'extensions';
$enable = 'extension';
} else {
$search = 'zend_extensions';
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$enable = 'zend_extension' . $debug . $ts;
}
foreach ($ini[$search] as $line => $extension) {
if (in_array($extension, $binaries, true) || in_array(
$ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) {
// already enabled - assume if one is, all are
return true;
}
}
if ($line) {
$newini = array_slice($ini['all'], 0, $line);
} else {
$newini = array();
}
foreach ($binaries as $binary) {
if ($ini['extension_dir']) {
$binary = basename($binary);
}
$newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n");
}
$newini = array_merge($newini, array_slice($ini['all'], $line));
foreach ($newini as $line) {
fwrite($fp, $line);
}
fclose($fp);
return true;
}
 
function disableExtension($binaries, $type)
{
if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) {
return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location');
}
$ini = $this->_parseIni($phpini);
if (PEAR::isError($ini)) {
return $ini;
}
$line = 0;
if ($type == 'extsrc' || $type == 'extbin') {
$search = 'extensions';
$enable = 'extension';
} else {
$search = 'zend_extensions';
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$enable = 'zend_extension' . $debug . $ts;
}
$found = false;
foreach ($ini[$search] as $line => $extension) {
if (in_array($extension, $binaries, true) || in_array(
$ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) {
$found = true;
break;
}
}
if (!$found) {
// not enabled
return true;
}
$fp = @fopen($phpini, 'wb');
if (!$fp) {
return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
}
if ($line) {
$newini = array_slice($ini['all'], 0, $line);
// delete the enable line
$newini = array_merge($newini, array_slice($ini['all'], $line + 1));
} else {
$newini = array_slice($ini['all'], 1);
}
foreach ($newini as $line) {
fwrite($fp, $line);
}
fclose($fp);
return true;
}
 
function _parseIni($filename)
{
if (file_exists($filename)) {
if (filesize($filename) > 300000) {
return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting');
}
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
$zend_extension_line = 'zend_extension' . $debug . $ts;
$all = @file($filename);
if (!$all) {
return PEAR::raiseError('php.ini "' . $filename .'" could not be read');
}
$zend_extensions = $extensions = array();
// assume this is right, but pull from the php.ini if it is found
$extension_dir = ini_get('extension_dir');
foreach ($all as $linenum => $line) {
$line = trim($line);
if (!$line) {
continue;
}
if ($line[0] == ';') {
continue;
}
if (strtolower(substr($line, 0, 13)) == 'extension_dir') {
$line = trim(substr($line, 13));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$extension_dir = str_replace('"', '', array_shift($x));
continue;
}
}
if (strtolower(substr($line, 0, 9)) == 'extension') {
$line = trim(substr($line, 9));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$extensions[$linenum] = str_replace('"', '', array_shift($x));
continue;
}
}
if (strtolower(substr($line, 0, strlen($zend_extension_line))) ==
$zend_extension_line) {
$line = trim(substr($line, strlen($zend_extension_line)));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$zend_extensions[$linenum] = str_replace('"', '', array_shift($x));
continue;
}
}
}
return array(
'extensions' => $extensions,
'zend_extensions' => $zend_extensions,
'extension_dir' => $extension_dir,
'all' => $all,
);
} else {
return PEAR::raiseError('php.ini "' . $filename . '" does not exist');
}
}
 
// {{{ doInstall()
 
function doInstall($command, $options, $params)
{
if (empty($this->installer)) {
$this->installer = &$this->getInstaller($this->ui);
}
if ($command == 'upgrade') {
$options['upgrade'] = true;
}
if (isset($options['installroot']) && isset($options['packagingroot'])) {
return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot');
}
if (isset($options['packagingroot']) && $this->config->get('verbose') > 2) {
$this->ui->outputData('using package root: ' . $options['packagingroot']);
}
$reg = &$this->config->getRegistry();
if ($command == 'upgrade-all') {
$options['upgrade'] = true;
$reg = &$this->config->getRegistry();
$savechannel = $this->config->get('default_channel');
$params = array();
foreach ($reg->listChannels() as $channel) {
if ($channel == '__uri') {
continue;
}
$this->config->set('default_channel', $channel);
$chan = &$reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$dorest = true;
unset($remote);
} else {
$dorest = false;
$remote = &$this->config->getRemote($this->config);
}
$state = $this->config->get('preferred_state');
$installed = array_flip($reg->listPackages($channel));
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if ($dorest) {
$rest = &$this->config->getREST('1.0', array());
$latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg);
} else {
if (empty($state) || $state == 'any') {
$latest = $remote->call("package.listLatestReleases");
} else {
$latest = $remote->call("package.listLatestReleases", $state);
}
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($latest) || !is_array($latest)) {
continue;
}
foreach ($latest as $package => $info) {
$package = strtolower($package);
if (!isset($installed[$package])) {
// skip packages we don't have installed
continue;
}
$inst_version = $reg->packageInfo($package, 'version', $channel);
if (version_compare("$info[version]", "$inst_version", "le")) {
// installed version is up-to-date
continue;
}
$params[] = $a = $reg->parsedPackageNameToString(array('package' => $package,
'channel' => $channel));
$this->ui->outputData(array('data' => "Will upgrade $a"), $command);
}
}
$this->config->set('default_channel', $savechannel);
}
$this->downloader = &$this->getDownloader($this->ui, $options, $this->config);
$errors = array();
$downloaded = array();
$downloaded = &$this->downloader->download($params);
if (PEAR::isError($downloaded)) {
return $this->raiseError($downloaded);
}
$errors = $this->downloader->getErrorMsgs();
if (count($errors)) {
$err['data'] = array();
foreach ($errors as $error) {
$err['data'][] = array($error);
}
$err['headline'] = 'Install Errors';
$this->ui->outputData($err);
if (!count($downloaded)) {
return $this->raiseError("$command failed");
}
}
$data = array(
'headline' => 'Packages that would be Installed'
);
if (isset($options['pretend'])) {
foreach ($downloaded as $package) {
$data['data'][] = array($reg->parsedPackageNameToString($package->getParsedPackage()));
}
$this->ui->outputData($data, 'pretend');
return true;
}
$this->installer->setOptions($options);
$this->installer->sortPackagesForInstall($downloaded);
if (PEAR::isError($err = $this->installer->setDownloadedPackages($downloaded))) {
$this->raiseError($err->getMessage());
return true;
}
$extrainfo = array();
if (isset($options['packagingroot'])) {
$packrootphp_dir = $this->installer->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$options['packagingroot']);
$instreg = new PEAR_Registry($packrootphp_dir);
} else {
$instreg = $reg;
}
foreach ($downloaded as $param) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$info = $this->installer->install($param, $options);
PEAR::staticPopErrorHandling();
if (PEAR::isError($info)) {
$oldinfo = $info;
$pkg = &$param->getPackageFile();
if ($info->getCode() != PEAR_INSTALLER_NOBINARY) {
if (!($info = $pkg->installBinary($this->installer))) {
$this->ui->outputData('ERROR: ' .$oldinfo->getMessage());
continue;
}
// we just installed a different package than requested,
// let's change the param and info so that the rest of this works
$param = $info[0];
$info = $info[1];
}
}
if (is_array($info)) {
if ($param->getPackageType() == 'extsrc' ||
$param->getPackageType() == 'extbin' ||
$param->getPackageType() == 'zendextsrc' ||
$param->getPackageType() == 'zendextbin') {
$pkg = &$param->getPackageFile();
if ($instbin = $pkg->getInstalledBinary()) {
$instpkg = &$instreg->getPackage($instbin, $pkg->getChannel());
} else {
$instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel());
}
foreach ($instpkg->getFilelist() as $name => $atts) {
$pinfo = pathinfo($atts['installed_as']);
if (!isset($pinfo['extension']) ||
in_array($pinfo['extension'], array('c', 'h'))) {
continue; // make sure we don't match php_blah.h
}
if ((strpos($pinfo['basename'], 'php_') === 0 &&
$pinfo['extension'] == 'dll') ||
// most unices
$pinfo['extension'] == 'so' ||
// hp-ux
$pinfo['extension'] == 'sl') {
$binaries[] = array($atts['installed_as'], $pinfo);
break;
}
}
foreach ($binaries as $pinfo) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType());
PEAR::staticPopErrorHandling();
if (PEAR::isError($ret)) {
$extrainfo[] = $ret->getMessage();
if ($param->getPackageType() == 'extsrc' ||
$param->getPackageType() == 'extbin') {
$exttype = 'extension';
} else {
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$exttype = 'zend_extension' . $debug . $ts;
}
$extrainfo[] = 'You should add "' . $exttype . '=' .
$pinfo[1]['basename'] . '" to php.ini';
} else {
$extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() .
' enabled in php.ini';
}
}
}
if ($this->config->get('verbose') > 0) {
$channel = $param->getChannel();
$label = $reg->parsedPackageNameToString(
array(
'channel' => $channel,
'package' => $param->getPackage(),
'version' => $param->getVersion(),
));
$out = array('data' => "$command ok: $label");
if (isset($info['release_warnings'])) {
$out['release_warnings'] = $info['release_warnings'];
}
$this->ui->outputData($out, $command);
if (!isset($options['register-only']) && !isset($options['offline'])) {
if ($this->config->isDefinedLayer('ftp')) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$info = $this->installer->ftpInstall($param);
PEAR::staticPopErrorHandling();
if (PEAR::isError($info)) {
$this->ui->outputData($info->getMessage());
$this->ui->outputData("remote install failed: $label");
} else {
$this->ui->outputData("remote install ok: $label");
}
}
}
}
$deps = $param->getDeps();
if ($deps) {
if (isset($deps['group'])) {
$groups = $deps['group'];
if (!isset($groups[0])) {
$groups = array($groups);
}
foreach ($groups as $group) {
if ($group['attribs']['name'] == 'default') {
// default group is always installed, unless the user
// explicitly chooses to install another group
continue;
}
$this->ui->outputData($param->getPackage() . ': Optional feature ' .
$group['attribs']['name'] . ' available (' .
$group['attribs']['hint'] . ')');
}
$extrainfo[] = 'To install use "pear install ' .
$reg->parsedPackageNameToString(
array('package' => $param->getPackage(),
'channel' => $param->getChannel()), true) .
'#featurename"';
}
}
if (isset($options['installroot'])) {
$reg = &$this->config->getRegistry();
}
if (isset($options['packagingroot'])) {
$instreg = new PEAR_Registry($packrootphp_dir);
} else {
$instreg = $reg;
}
$pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel());
// $pkg may be NULL if install is a 'fake' install via --packagingroot
if (is_object($pkg)) {
$pkg->setConfig($this->config);
if ($list = $pkg->listPostinstallScripts()) {
$pn = $reg->parsedPackageNameToString(array('channel' =>
$param->getChannel(), 'package' => $param->getPackage()), true);
$extrainfo[] = $pn . ' has post-install scripts:';
foreach ($list as $file) {
$extrainfo[] = $file;
}
$extrainfo[] = 'Use "pear run-scripts ' . $pn . '" to run';
$extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES';
}
}
} else {
return $this->raiseError("$command failed");
}
}
if (count($extrainfo)) {
foreach ($extrainfo as $info) {
$this->ui->outputData($info);
}
}
return true;
}
 
// }}}
// {{{ doUninstall()
 
function doUninstall($command, $options, $params)
{
if (empty($this->installer)) {
$this->installer = &$this->getInstaller($this->ui);
}
if (isset($options['remoteconfig'])) {
$e = $this->config->readFTPConfigFile($options['remoteconfig']);
if (!PEAR::isError($e)) {
$this->installer->setConfig($this->config);
}
}
if (sizeof($params) < 1) {
return $this->raiseError("Please supply the package(s) you want to uninstall");
}
$reg = &$this->config->getRegistry();
$newparams = array();
$badparams = array();
foreach ($params as $pkg) {
$channel = $this->config->get('default_channel');
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$parsed = $reg->parsePackageName($pkg, $channel);
PEAR::staticPopErrorHandling();
if (!$parsed || PEAR::isError($parsed)) {
$badparams[] = $pkg;
continue;
}
$package = $parsed['package'];
$channel = $parsed['channel'];
$info = &$reg->getPackage($package, $channel);
if ($info === null &&
($channel == 'pear.php.net' || $channel == 'pecl.php.net')) {
// make sure this isn't a package that has flipped from pear to pecl but
// used a package.xml 1.0
$testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net';
$info = &$reg->getPackage($package, $testc);
if ($info !== null) {
$channel = $testc;
}
}
if ($info === null) {
$badparams[] = $pkg;
} else {
$newparams[] = &$info;
// check for binary packages (this is an alias for those packages if so)
if ($installedbinary = $info->getInstalledBinary()) {
$this->ui->log('adding binary package ' .
$reg->parsedPackageNameToString(array('channel' => $channel,
'package' => $installedbinary), true));
$newparams[] = &$reg->getPackage($installedbinary, $channel);
}
// add the contents of a dependency group to the list of installed packages
if (isset($parsed['group'])) {
$group = $info->getDependencyGroup($parsed['group']);
if ($group) {
$installed = &$reg->getInstalledGroup($group);
if ($installed) {
foreach ($installed as $i => $p) {
$newparams[] = &$installed[$i];
}
}
}
}
}
}
$err = $this->installer->sortPackagesForUninstall($newparams);
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage(), $command);
return true;
}
$params = $newparams;
// twist this to use it to check on whether dependent packages are also being uninstalled
// for circular dependencies like subpackages
$this->installer->setUninstallPackages($newparams);
$params = array_merge($params, $badparams);
foreach ($params as $pkg) {
$this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
if ($err = $this->installer->uninstall($pkg, $options)) {
$this->installer->popErrorHandling();
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage(), $command);
continue;
}
if ($pkg->getPackageType() == 'extsrc' ||
$pkg->getPackageType() == 'extbin' ||
$pkg->getPackageType() == 'zendextsrc' ||
$pkg->getPackageType() == 'zendextbin') {
if ($instbin = $pkg->getInstalledBinary()) {
continue; // this will be uninstalled later
}
foreach ($pkg->getFilelist() as $name => $atts) {
$pinfo = pathinfo($atts['installed_as']);
if (!isset($pinfo['extension']) ||
in_array($pinfo['extension'], array('c', 'h'))) {
continue; // make sure we don't match php_blah.h
}
if ((strpos($pinfo['basename'], 'php_') === 0 &&
$pinfo['extension'] == 'dll') ||
// most unices
$pinfo['extension'] == 'so' ||
// hp-ux
$pinfo['extension'] == 'sl') {
$binaries[] = array($atts['installed_as'], $pinfo);
break;
}
}
foreach ($binaries as $pinfo) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType());
PEAR::staticPopErrorHandling();
if (PEAR::isError($ret)) {
$extrainfo[] = $ret->getMessage();
if ($pkg->getPackageType() == 'extsrc' ||
$pkg->getPackageType() == 'extbin') {
$exttype = 'extension';
} else {
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$exttype = 'zend_extension' . $debug . $ts;
}
$this->ui->outputData('Unable to remove "' . $exttype . '=' .
$pinfo[1]['basename'] . '" from php.ini', $command);
} else {
$this->ui->outputData('Extension ' . $pkg->getProvidesExtension() .
' disabled in php.ini', $command);
}
}
}
$savepkg = $pkg;
if ($this->config->get('verbose') > 0) {
if (is_object($pkg)) {
$pkg = $reg->parsedPackageNameToString($pkg);
}
$this->ui->outputData("uninstall ok: $pkg", $command);
}
if (!isset($options['offline']) && is_object($savepkg) &&
defined('PEAR_REMOTEINSTALL_OK')) {
if ($this->config->isDefinedLayer('ftp')) {
$this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
$info = $this->installer->ftpUninstall($savepkg);
$this->installer->popErrorHandling();
if (PEAR::isError($info)) {
$this->ui->outputData($info->getMessage());
$this->ui->outputData("remote uninstall failed: $pkg");
} else {
$this->ui->outputData("remote uninstall ok: $pkg");
}
}
}
} else {
$this->installer->popErrorHandling();
if (is_object($pkg)) {
$pkg = $reg->parsedPackageNameToString($pkg);
}
return $this->raiseError("uninstall failed: $pkg");
}
}
return true;
}
 
// }}}
 
 
// }}}
// {{{ doBundle()
/*
(cox) It just downloads and untars the package, does not do
any check that the PEAR_Installer::_installFile() does.
*/
 
function doBundle($command, $options, $params)
{
$downloader = &$this->getDownloader($this->ui, array('force' => true, 'nodeps' => true,
'soft' => true, 'downloadonly' => true), $this->config);
$reg = &$this->config->getRegistry();
if (sizeof($params) < 1) {
return $this->raiseError("Please supply the package you want to bundle");
}
 
if (isset($options['destination'])) {
if (!is_dir($options['destination'])) {
System::mkdir('-p ' . $options['destination']);
}
$dest = realpath($options['destination']);
} else {
$pwd = getcwd();
if (is_dir($pwd . DIRECTORY_SEPARATOR . 'ext')) {
$dest = $pwd . DIRECTORY_SEPARATOR . 'ext';
} else {
$dest = $pwd;
}
}
$downloader->setDownloadDir($dest);
$result = &$downloader->download(array($params[0]));
if (PEAR::isError($result)) {
return $result;
}
$pkgfile = &$result[0]->getPackageFile();
$pkgname = $pkgfile->getName();
$pkgversion = $pkgfile->getVersion();
 
// Unpacking -------------------------------------------------
$dest .= DIRECTORY_SEPARATOR . $pkgname;
$orig = $pkgname . '-' . $pkgversion;
 
$tar = &new Archive_Tar($pkgfile->getArchiveFile());
if (!$tar->extractModify($dest, $orig)) {
return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile());
}
$this->ui->outputData("Package ready at '$dest'");
// }}}
}
 
// }}}
 
function doRunScripts($command, $options, $params)
{
if (!isset($params[0])) {
return $this->raiseError('run-scripts expects 1 parameter: a package name');
}
$reg = &$this->config->getRegistry();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
PEAR::staticPopErrorHandling();
if (PEAR::isError($parsed)) {
return $this->raiseError($parsed);
}
$package = &$reg->getPackage($parsed['package'], $parsed['channel']);
if (is_object($package)) {
$package->setConfig($this->config);
$package->runPostinstallScripts();
} else {
return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry');
}
$this->ui->outputData('Install scripts complete', $command);
return true;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Pickle.php
New file
0,0 → 1,376
<?php
/**
* PEAR_Command_Pickle (pickle command)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2005-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Pickle.php,v 1.6 2006/05/12 02:38:58 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
 
/**
* PEAR commands for login/logout
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2005-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.1
*/
 
class PEAR_Command_Pickle extends PEAR_Command_Common
{
var $commands = array(
'pickle' => array(
'summary' => 'Build PECL Package',
'function' => 'doPackage',
'shortcut' => 'pi',
'options' => array(
'nocompress' => array(
'shortopt' => 'Z',
'doc' => 'Do not gzip the package file'
),
'showname' => array(
'shortopt' => 'n',
'doc' => 'Print the name of the packaged file.',
),
),
'doc' => '[descfile]
Creates a PECL package from its package2.xml file.
 
An automatic conversion will be made to a package.xml 1.0 and written out to
disk in the current directory as "package.xml". Note that
only simple package.xml 2.0 will be converted. package.xml 2.0 with:
 
- dependency types other than required/optional PECL package/ext/php/pearinstaller
- more than one extsrcrelease or zendextsrcrelease
- zendextbinrelease, extbinrelease, phprelease, or bundle release type
- dependency groups
- ignore tags in release filelist
- tasks other than replace
- custom roles
 
will cause pickle to fail, and output an error message. If your package2.xml
uses any of these features, you are best off using PEAR_PackageFileManager to
generate both package.xml.
'
),
);
 
/**
* PEAR_Command_Package constructor.
*
* @access public
*/
function PEAR_Command_Pickle(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
 
/**
* For unit-testing ease
*
* @return PEAR_Packager
*/
function &getPackager()
{
if (!class_exists('PEAR_Packager')) {
require_once 'PEAR/Packager.php';
}
$a = &new PEAR_Packager;
return $a;
}
 
/**
* For unit-testing ease
*
* @param PEAR_Config $config
* @param bool $debug
* @param string|null $tmpdir
* @return PEAR_PackageFile
*/
function &getPackageFile($config, $debug = false, $tmpdir = null)
{
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
if (!class_exists('PEAR/PackageFile.php')) {
require_once 'PEAR/PackageFile.php';
}
$a = &new PEAR_PackageFile($config, $debug, $tmpdir);
$common = new PEAR_Common;
$common->ui = $this->ui;
$a->setLogger($common);
return $a;
}
 
function doPackage($command, $options, $params)
{
$this->output = '';
$pkginfofile = isset($params[0]) ? $params[0] : 'package2.xml';
$packager = &$this->getPackager();
if (PEAR::isError($err = $this->_convertPackage($pkginfofile))) {
return $err;
}
$compress = empty($options['nocompress']) ? true : false;
$result = $packager->package($pkginfofile, $compress, 'package.xml');
if (PEAR::isError($result)) {
return $this->raiseError($result);
}
// Don't want output, only the package file name just created
if (isset($options['showname'])) {
$this->ui->outputData($result, $command);
}
return true;
}
 
function _convertPackage($packagexml)
{
$pkg = &$this->getPackageFile($this->config);
$pf2 = &$pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL);
if (!is_a($pf2, 'PEAR_PackageFile_v2')) {
return $this->raiseError('Cannot process "' .
$packagexml . '", is not a package.xml 2.0');
}
require_once 'PEAR/PackageFile/v1.php';
$pf = new PEAR_PackageFile_v1;
$pf->setConfig($this->config);
if ($pf2->getPackageType() != 'extsrc' && $pf2->getPackageType() != 'zendextsrc') {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", is not an extension source package. Using a PEAR_PackageFileManager-based ' .
'script is an option');
}
if (is_array($pf2->getUsesRole())) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains custom roles. Using a PEAR_PackageFileManager-based script or ' .
'the convert command is an option');
}
if (is_array($pf2->getUsesTask())) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains custom tasks. Using a PEAR_PackageFileManager-based script or ' .
'the convert command is an option');
}
$deps = $pf2->getDependencies();
if (isset($deps['group'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains dependency groups. Using a PEAR_PackageFileManager-based script ' .
'or the convert command is an option');
}
if (isset($deps['required']['subpackage']) ||
isset($deps['optional']['subpackage'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains subpackage dependencies. Using a PEAR_PackageFileManager-based '.
'script is an option');
}
if (isset($deps['required']['os'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains os dependencies. Using a PEAR_PackageFileManager-based '.
'script is an option');
}
if (isset($deps['required']['arch'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains arch dependencies. Using a PEAR_PackageFileManager-based '.
'script is an option');
}
$pf->setPackage($pf2->getPackage());
$pf->setSummary($pf2->getSummary());
$pf->setDescription($pf2->getDescription());
foreach ($pf2->getMaintainers() as $maintainer) {
$pf->addMaintainer($maintainer['role'], $maintainer['handle'],
$maintainer['name'], $maintainer['email']);
}
$pf->setVersion($pf2->getVersion());
$pf->setDate($pf2->getDate());
$pf->setLicense($pf2->getLicense());
$pf->setState($pf2->getState());
$pf->setNotes($pf2->getNotes());
$pf->addPhpDep($deps['required']['php']['min'], 'ge');
if (isset($deps['required']['php']['max'])) {
$pf->addPhpDep($deps['required']['php']['max'], 'le');
}
if (isset($deps['required']['package'])) {
if (!isset($deps['required']['package'][0])) {
$deps['required']['package'] = array($deps['required']['package']);
}
foreach ($deps['required']['package'] as $dep) {
if (!isset($dep['channel'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains uri-based dependency on a package. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if ($dep['channel'] != 'pear.php.net' && $dep['channel'] != 'pecl.php.net') {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains dependency on a non-standard channel package. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if (isset($dep['conflicts'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains conflicts dependency. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if (isset($dep['exclude'])) {
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
}
if (isset($dep['min'])) {
$pf->addPackageDep($dep['name'], $dep['min'], 'ge');
}
if (isset($dep['max'])) {
$pf->addPackageDep($dep['name'], $dep['max'], 'le');
}
}
}
if (isset($deps['required']['extension'])) {
if (!isset($deps['required']['extension'][0])) {
$deps['required']['extension'] = array($deps['required']['extension']);
}
foreach ($deps['required']['extension'] as $dep) {
if (isset($dep['conflicts'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains conflicts dependency. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if (isset($dep['exclude'])) {
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
}
if (isset($dep['min'])) {
$pf->addExtensionDep($dep['name'], $dep['min'], 'ge');
}
if (isset($dep['max'])) {
$pf->addExtensionDep($dep['name'], $dep['max'], 'le');
}
}
}
if (isset($deps['optional']['package'])) {
if (!isset($deps['optional']['package'][0])) {
$deps['optional']['package'] = array($deps['optional']['package']);
}
foreach ($deps['optional']['package'] as $dep) {
if (!isset($dep['channel'])) {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains uri-based dependency on a package. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if ($dep['channel'] != 'pear.php.net' && $dep['channel'] != 'pecl.php.net') {
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
' contains dependency on a non-standard channel package. Using a ' .
'PEAR_PackageFileManager-based script is an option');
}
if (isset($dep['exclude'])) {
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
}
if (isset($dep['min'])) {
$pf->addPackageDep($dep['name'], $dep['min'], 'ge', 'yes');
}
if (isset($dep['max'])) {
$pf->addPackageDep($dep['name'], $dep['max'], 'le', 'yes');
}
}
}
if (isset($deps['optional']['extension'])) {
if (!isset($deps['optional']['extension'][0])) {
$deps['optional']['extension'] = array($deps['optional']['extension']);
}
foreach ($deps['optional']['extension'] as $dep) {
if (isset($dep['exclude'])) {
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
}
if (isset($dep['min'])) {
$pf->addExtensionDep($dep['name'], $dep['min'], 'ge', 'yes');
}
if (isset($dep['max'])) {
$pf->addExtensionDep($dep['name'], $dep['max'], 'le', 'yes');
}
}
}
$contents = $pf2->getContents();
$release = $pf2->getReleases();
if (isset($releases[0])) {
return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
. 'multiple extsrcrelease/zendextsrcrelease tags. Using a PEAR_PackageFileManager-based script ' .
'or the convert command is an option');
}
if ($configoptions = $pf2->getConfigureOptions()) {
foreach ($configoptions as $option) {
$pf->addConfigureOption($option['name'], $option['prompt'],
isset($option['default']) ? $option['default'] : false);
}
}
if (isset($release['filelist']['ignore'])) {
return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
. 'ignore tags. Using a PEAR_PackageFileManager-based script or the convert' .
' command is an option');
}
if (isset($release['filelist']['install']) &&
!isset($release['filelist']['install'][0])) {
$release['filelist']['install'] = array($release['filelist']['install']);
}
if (isset($contents['dir']['attribs']['baseinstalldir'])) {
$baseinstalldir = $contents['dir']['attribs']['baseinstalldir'];
} else {
$baseinstalldir = false;
}
if (!isset($contents['dir']['file'][0])) {
$contents['dir']['file'] = array($contents['dir']['file']);
}
foreach ($contents['dir']['file'] as $file) {
if ($baseinstalldir && !isset($file['attribs']['baseinstalldir'])) {
$file['attribs']['baseinstalldir'] = $baseinstalldir;
}
$processFile = $file;
unset($processFile['attribs']);
if (count($processFile)) {
foreach ($processFile as $name => $task) {
if ($name != $pf2->getTasksNs() . ':replace') {
return $this->raiseError('Cannot safely process "' . $packagexml .
'" contains tasks other than replace. Using a ' .
'PEAR_PackageFileManager-based script is an option.');
}
$file['attribs']['replace'][] = $task;
}
}
if (!in_array($file['attribs']['role'], PEAR_Common::getFileRoles())) {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", contains custom roles. Using a PEAR_PackageFileManager-based script ' .
'or the convert command is an option');
}
if (isset($release['filelist']['install'])) {
foreach ($release['filelist']['install'] as $installas) {
if ($installas['attribs']['name'] == $file['attribs']['name']) {
$file['attribs']['install-as'] = $installas['attribs']['as'];
}
}
}
$pf->addFile('/', $file['attribs']['name'], $file['attribs']);
}
if ($pf2->getChangeLog()) {
$this->ui->outputData('WARNING: changelog is not translated to package.xml ' .
'1.0, use PEAR_PackageFileManager-based script if you need changelog-' .
'translation for package.xml 1.0');
}
$gen = &$pf->getDefaultGenerator();
$gen->toPackageFile('.');
}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Registry.php
New file
0,0 → 1,1011
<?php
/**
* PEAR_Command_Registry (list, list-files, shell-test, info commands)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Registry.php,v 1.75 2006/11/19 23:50:09 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
 
/**
* PEAR commands for registry manipulation
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Registry extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'list' => array(
'summary' => 'List Installed Packages In The Default Channel',
'function' => 'doList',
'shortcut' => 'l',
'options' => array(
'channel' => array(
'shortopt' => 'c',
'doc' => 'list installed packages from this channel',
'arg' => 'CHAN',
),
'allchannels' => array(
'shortopt' => 'a',
'doc' => 'list installed packages from all channels',
),
),
'doc' => '<package>
If invoked without parameters, this command lists the PEAR packages
installed in your php_dir ({config php_dir}). With a parameter, it
lists the files in a package.
',
),
'list-files' => array(
'summary' => 'List Files In Installed Package',
'function' => 'doFileList',
'shortcut' => 'fl',
'options' => array(),
'doc' => '<package>
List the files in an installed package.
'
),
'shell-test' => array(
'summary' => 'Shell Script Test',
'function' => 'doShellTest',
'shortcut' => 'st',
'options' => array(),
'doc' => '<package> [[relation] version]
Tests if a package is installed in the system. Will exit(1) if it is not.
<relation> The version comparison operator. One of:
<, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne
<version> The version to compare with
'),
'info' => array(
'summary' => 'Display information about a package',
'function' => 'doInfo',
'shortcut' => 'in',
'options' => array(),
'doc' => '<package>
Displays information about a package. The package argument may be a
local package file, an URL to a package file, or the name of an
installed package.'
)
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Registry constructor.
*
* @access public
*/
function PEAR_Command_Registry(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ doList()
 
function _sortinfo($a, $b)
{
$apackage = isset($a['package']) ? $a['package'] : $a['name'];
$bpackage = isset($b['package']) ? $b['package'] : $b['name'];
return strcmp($apackage, $bpackage);
}
 
function doList($command, $options, $params)
{
if (isset($options['allchannels'])) {
return $this->doListAll($command, array(), $params);
}
$reg = &$this->config->getRegistry();
if (count($params) == 1) {
return $this->doFileList($command, $options, $params);
}
if (isset($options['channel'])) {
if ($reg->channelExists($options['channel'])) {
$channel = $reg->channelName($options['channel']);
} else {
return $this->raiseError('Channel "' . $options['channel'] .'" does not exist');
}
} else {
$channel = $this->config->get('default_channel');
}
$installed = $reg->packageInfo(null, null, $channel);
usort($installed, array(&$this, '_sortinfo'));
$i = $j = 0;
$data = array(
'caption' => 'Installed packages, channel ' .
$channel . ':',
'border' => true,
'headline' => array('Package', 'Version', 'State')
);
foreach ($installed as $package) {
$pobj = $reg->getPackage(isset($package['package']) ?
$package['package'] : $package['name'], $channel);
$data['data'][] = array($pobj->getPackage(), $pobj->getVersion(),
$pobj->getState() ? $pobj->getState() : null);
}
if (count($installed)==0) {
$data = '(no packages installed from channel ' . $channel . ')';
}
$this->ui->outputData($data, $command);
return true;
}
function doListAll($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$installed = $reg->packageInfo(null, null, null);
foreach ($installed as $channel => $packages) {
usort($packages, array($this, '_sortinfo'));
$i = $j = 0;
$data = array(
'caption' => 'Installed packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Version', 'State')
);
foreach ($packages as $package) {
$pobj = $reg->getPackage(isset($package['package']) ?
$package['package'] : $package['name'], $channel);
$data['data'][] = array($pobj->getPackage(), $pobj->getVersion(),
$pobj->getState() ? $pobj->getState() : null);
}
if (count($packages)==0) {
$data = array(
'caption' => 'Installed packages, channel ' . $channel . ':',
'border' => true,
'data' => array(array('(no packages installed)')),
);
}
$this->ui->outputData($data, $command);
}
return true;
}
function doFileList($command, $options, $params)
{
if (count($params) != 1) {
return $this->raiseError('list-files expects 1 parameter');
}
$reg = &$this->config->getRegistry();
$fp = false;
if (!is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0],
'r'))) {
if ($fp) {
fclose($fp);
}
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
$pkg = &new PEAR_PackageFile($this->config, $this->_debug);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$info = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
PEAR::staticPopErrorHandling();
$headings = array('Package File', 'Install Path');
$installed = false;
} else {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
PEAR::staticPopErrorHandling();
if (PEAR::isError($parsed)) {
return $this->raiseError($parsed);
}
$info = &$reg->getPackage($parsed['package'], $parsed['channel']);
$headings = array('Type', 'Install Path');
$installed = true;
}
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
if ($info === null) {
return $this->raiseError("`$params[0]' not installed");
}
$list = ($info->getPackagexmlVersion() == '1.0' || $installed) ?
$info->getFilelist() : $info->getContents();
if ($installed) {
$caption = 'Installed Files For ' . $params[0];
} else {
$caption = 'Contents of ' . basename($params[0]);
}
$data = array(
'caption' => $caption,
'border' => true,
'headline' => $headings);
if ($info->getPackagexmlVersion() == '1.0' || $installed) {
foreach ($list as $file => $att) {
if ($installed) {
if (empty($att['installed_as'])) {
continue;
}
$data['data'][] = array($att['role'], $att['installed_as']);
} else {
if (isset($att['baseinstalldir']) && !in_array($att['role'],
array('test', 'data', 'doc'))) {
$dest = $att['baseinstalldir'] . DIRECTORY_SEPARATOR .
$file;
} else {
$dest = $file;
}
switch ($att['role']) {
case 'test':
case 'data':
case 'doc':
$role = $att['role'];
if ($role == 'test') {
$role .= 's';
}
$dest = $this->config->get($role . '_dir') . DIRECTORY_SEPARATOR .
$info->getPackage() . DIRECTORY_SEPARATOR . $dest;
break;
case 'php':
default:
$dest = $this->config->get('php_dir') . DIRECTORY_SEPARATOR .
$dest;
}
$ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
$dest = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"),
array(DIRECTORY_SEPARATOR,
DIRECTORY_SEPARATOR,
DIRECTORY_SEPARATOR),
$dest);
$file = preg_replace('!/+!', '/', $file);
$data['data'][] = array($file, $dest);
}
}
} else { // package.xml 2.0, not installed
if (!isset($list['dir']['file'][0])) {
$list['dir']['file'] = array($list['dir']['file']);
}
foreach ($list['dir']['file'] as $att) {
$att = $att['attribs'];
$file = $att['name'];
$role = &PEAR_Installer_Role::factory($info, $att['role'], $this->config);
$role->setup($this, $info, $att, $file);
if (!$role->isInstallable()) {
$dest = '(not installable)';
} else {
$dest = $role->processInstallation($info, $att, $file, '');
if (PEAR::isError($dest)) {
$dest = '(Unknown role "' . $att['role'] . ')';
} else {
list(,, $dest) = $dest;
}
}
$data['data'][] = array($file, $dest);
}
}
$this->ui->outputData($data, $command);
return true;
}
 
// }}}
// {{{ doShellTest()
 
function doShellTest($command, $options, $params)
{
if (count($params) < 1) {
return PEAR::raiseError('ERROR, usage: pear shell-test packagename [[relation] version]');
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$reg = &$this->config->getRegistry();
$info = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
if (PEAR::isError($info)) {
exit(1); // invalid package name
}
$package = $info['package'];
$channel = $info['channel'];
// "pear shell-test Foo"
if (!$reg->packageExists($package, $channel)) {
if ($channel == 'pecl.php.net') {
if ($reg->packageExists($package, 'pear.php.net')) {
$channel = 'pear.php.net'; // magically change channels for extensions
}
}
}
if (sizeof($params) == 1) {
if (!$reg->packageExists($package, $channel)) {
exit(1);
}
// "pear shell-test Foo 1.0"
} elseif (sizeof($params) == 2) {
$v = $reg->packageInfo($package, 'version', $channel);
if (!$v || !version_compare("$v", "{$params[1]}", "ge")) {
exit(1);
}
// "pear shell-test Foo ge 1.0"
} elseif (sizeof($params) == 3) {
$v = $reg->packageInfo($package, 'version', $channel);
if (!$v || !version_compare("$v", "{$params[2]}", $params[1])) {
exit(1);
}
} else {
PEAR::staticPopErrorHandling();
$this->raiseError("$command: expects 1 to 3 parameters");
exit(1);
}
}
 
// }}}
// {{{ doInfo
 
function doInfo($command, $options, $params)
{
if (count($params) != 1) {
return $this->raiseError('pear info expects 1 parameter');
}
$info = $fp = false;
$reg = &$this->config->getRegistry();
if ((file_exists($params[0]) && is_file($params[0]) && !is_dir($params[0])) || $fp = @fopen($params[0], 'r')) {
if ($fp) {
fclose($fp);
}
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
$pkg = &new PEAR_PackageFile($this->config, $this->_debug);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$obj = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
PEAR::staticPopErrorHandling();
if (PEAR::isError($obj)) {
$uinfo = $obj->getUserInfo();
if (is_array($uinfo)) {
foreach ($uinfo as $message) {
if (is_array($message)) {
$message = $message['message'];
}
$this->ui->outputData($message);
}
}
return $this->raiseError($obj);
}
if ($obj->getPackagexmlVersion() == '1.0') {
$info = $obj->toArray();
} else {
return $this->_doInfo2($command, $options, $params, $obj, false);
}
} else {
$parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
if (PEAR::isError($parsed)) {
return $this->raiseError($parsed);
}
$package = $parsed['package'];
$channel = $parsed['channel'];
$info = $reg->packageInfo($package, null, $channel);
if (isset($info['old'])) {
$obj = $reg->getPackage($package, $channel);
return $this->_doInfo2($command, $options, $params, $obj, true);
}
}
if (PEAR::isError($info)) {
return $info;
}
if (empty($info)) {
$this->raiseError("No information found for `$params[0]'");
return;
}
unset($info['filelist']);
unset($info['dirtree']);
unset($info['changelog']);
if (isset($info['xsdversion'])) {
$info['package.xml version'] = $info['xsdversion'];
unset($info['xsdversion']);
}
if (isset($info['packagerversion'])) {
$info['packaged with PEAR version'] = $info['packagerversion'];
unset($info['packagerversion']);
}
$keys = array_keys($info);
$longtext = array('description', 'summary');
foreach ($keys as $key) {
if (is_array($info[$key])) {
switch ($key) {
case 'maintainers': {
$i = 0;
$mstr = '';
foreach ($info[$key] as $m) {
if ($i++ > 0) {
$mstr .= "\n";
}
$mstr .= $m['name'] . " <";
if (isset($m['email'])) {
$mstr .= $m['email'];
} else {
$mstr .= $m['handle'] . '@php.net';
}
$mstr .= "> ($m[role])";
}
$info[$key] = $mstr;
break;
}
case 'release_deps': {
$i = 0;
$dstr = '';
foreach ($info[$key] as $d) {
if (isset($this->_deps_rel_trans[$d['rel']])) {
$rel = $this->_deps_rel_trans[$d['rel']];
} else {
$rel = $d['rel'];
}
if (isset($this->_deps_type_trans[$d['type']])) {
$type = ucfirst($this->_deps_type_trans[$d['type']]);
} else {
$type = $d['type'];
}
if (isset($d['name'])) {
$name = $d['name'] . ' ';
} else {
$name = '';
}
if (isset($d['version'])) {
$version = $d['version'] . ' ';
} else {
$version = '';
}
if (isset($d['optional']) && $d['optional'] == 'yes') {
$optional = ' (optional)';
} else {
$optional = '';
}
$dstr .= "$type $name$rel $version$optional\n";
}
$info[$key] = $dstr;
break;
}
case 'provides' : {
$debug = $this->config->get('verbose');
if ($debug < 2) {
$pstr = 'Classes: ';
} else {
$pstr = '';
}
$i = 0;
foreach ($info[$key] as $p) {
if ($debug < 2 && $p['type'] != "class") {
continue;
}
// Only print classes when verbosity mode is < 2
if ($debug < 2) {
if ($i++ > 0) {
$pstr .= ", ";
}
$pstr .= $p['name'];
} else {
if ($i++ > 0) {
$pstr .= "\n";
}
$pstr .= ucfirst($p['type']) . " " . $p['name'];
if (isset($p['explicit']) && $p['explicit'] == 1) {
$pstr .= " (explicit)";
}
}
}
$info[$key] = $pstr;
break;
}
case 'configure_options' : {
foreach ($info[$key] as $i => $p) {
$info[$key][$i] = array_map(null, array_keys($p), array_values($p));
$info[$key][$i] = array_map(create_function('$a',
'return join(" = ",$a);'), $info[$key][$i]);
$info[$key][$i] = implode(', ', $info[$key][$i]);
}
$info[$key] = implode("\n", $info[$key]);
break;
}
default: {
$info[$key] = implode(", ", $info[$key]);
break;
}
}
}
if ($key == '_lastmodified') {
$hdate = date('Y-m-d', $info[$key]);
unset($info[$key]);
$info['Last Modified'] = $hdate;
} elseif ($key == '_lastversion') {
$info['Previous Installed Version'] = $info[$key] ? $info[$key] : '- None -';
unset($info[$key]);
} else {
$info[$key] = trim($info[$key]);
if (in_array($key, $longtext)) {
$info[$key] = preg_replace('/ +/', ' ', $info[$key]);
}
}
}
$caption = 'About ' . $info['package'] . '-' . $info['version'];
$data = array(
'caption' => $caption,
'border' => true);
foreach ($info as $key => $value) {
$key = ucwords(trim(str_replace('_', ' ', $key)));
$data['data'][] = array($key, $value);
}
$data['raw'] = $info;
 
$this->ui->outputData($data, 'package-info');
}
 
// }}}
 
/**
* @access private
*/
function _doInfo2($command, $options, $params, &$obj, $installed)
{
$reg = &$this->config->getRegistry();
$caption = 'About ' . $obj->getChannel() . '/' .$obj->getPackage() . '-' .
$obj->getVersion();
$data = array(
'caption' => $caption,
'border' => true);
switch ($obj->getPackageType()) {
case 'php' :
$release = 'PEAR-style PHP-based Package';
break;
case 'extsrc' :
$release = 'PECL-style PHP extension (source code)';
break;
case 'zendextsrc' :
$release = 'PECL-style Zend extension (source code)';
break;
case 'extbin' :
$release = 'PECL-style PHP extension (binary)';
break;
case 'zendextbin' :
$release = 'PECL-style Zend extension (binary)';
break;
case 'bundle' :
$release = 'Package bundle (collection of packages)';
break;
}
$extends = $obj->getExtends();
$extends = $extends ?
$obj->getPackage() . ' (extends ' . $extends . ')' : $obj->getPackage();
if ($src = $obj->getSourcePackage()) {
$extends .= ' (source package ' . $src['channel'] . '/' . $src['package'] . ')';
}
$info = array(
'Release Type' => $release,
'Name' => $extends,
'Channel' => $obj->getChannel(),
'Summary' => preg_replace('/ +/', ' ', $obj->getSummary()),
'Description' => preg_replace('/ +/', ' ', $obj->getDescription()),
);
$info['Maintainers'] = '';
foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
$leads = $obj->{"get{$role}s"}();
if (!$leads) {
continue;
}
if (isset($leads['active'])) {
$leads = array($leads);
}
foreach ($leads as $lead) {
if (!empty($info['Maintainers'])) {
$info['Maintainers'] .= "\n";
}
$info['Maintainers'] .= $lead['name'] . ' <';
$info['Maintainers'] .= $lead['email'] . "> ($role)";
}
}
$info['Release Date'] = $obj->getDate();
if ($time = $obj->getTime()) {
$info['Release Date'] .= ' ' . $time;
}
$info['Release Version'] = $obj->getVersion() . ' (' . $obj->getState() . ')';
$info['API Version'] = $obj->getVersion('api') . ' (' . $obj->getState('api') . ')';
$info['License'] = $obj->getLicense();
$uri = $obj->getLicenseLocation();
if ($uri) {
if (isset($uri['uri'])) {
$info['License'] .= ' (' . $uri['uri'] . ')';
} else {
$extra = $obj->getInstalledLocation($info['filesource']);
if ($extra) {
$info['License'] .= ' (' . $uri['filesource'] . ')';
}
}
}
$info['Release Notes'] = $obj->getNotes();
if ($compat = $obj->getCompatible()) {
$info['Compatible with'] = '';
foreach ($compat as $package) {
$info['Compatible with'] .= $package['channel'] . '/' . $package['package'] .
"\nVersions >= " . $package['min'] . ', <= ' . $package['max'];
if (isset($package['exclude'])) {
if (is_array($package['exclude'])) {
$package['exclude'] = implode(', ', $package['exclude']);
}
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
$info['Not Compatible with'] .= "\n";
}
$info['Not Compatible with'] .= $package['channel'] . '/' .
$package['package'] . "\nVersions " . $package['exclude'];
}
}
}
$usesrole = $obj->getUsesrole();
if ($usesrole) {
if (!isset($usesrole[0])) {
$usesrole = array($usesrole);
}
foreach ($usesrole as $roledata) {
if (isset($info['Uses Custom Roles'])) {
$info['Uses Custom Roles'] .= "\n";
} else {
$info['Uses Custom Roles'] = '';
}
if (isset($roledata['package'])) {
$rolepackage = $reg->parsedPackageNameToString($roledata, true);
} else {
$rolepackage = $roledata['uri'];
}
$info['Uses Custom Roles'] .= $roledata['role'] . ' (' . $rolepackage . ')';
}
}
$usestask = $obj->getUsestask();
if ($usestask) {
if (!isset($usestask[0])) {
$usestask = array($usestask);
}
foreach ($usestask as $taskdata) {
if (isset($info['Uses Custom Tasks'])) {
$info['Uses Custom Tasks'] .= "\n";
} else {
$info['Uses Custom Tasks'] = '';
}
if (isset($taskdata['package'])) {
$taskpackage = $reg->parsedPackageNameToString($taskdata, true);
} else {
$taskpackage = $taskdata['uri'];
}
$info['Uses Custom Tasks'] .= $taskdata['task'] . ' (' . $taskpackage . ')';
}
}
$deps = $obj->getDependencies();
$info['Required Dependencies'] = 'PHP version ' . $deps['required']['php']['min'];
if (isset($deps['required']['php']['max'])) {
$info['Required Dependencies'] .= '-' . $deps['required']['php']['max'] . "\n";
} else {
$info['Required Dependencies'] .= "\n";
}
if (isset($deps['required']['php']['exclude'])) {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
$info['Not Compatible with'] .= "\n";
}
if (is_array($deps['required']['php']['exclude'])) {
$deps['required']['php']['exclude'] =
implode(', ', $deps['required']['php']['exclude']);
}
$info['Not Compatible with'] .= "PHP versions\n " .
$deps['required']['php']['exclude'];
}
$info['Required Dependencies'] .= 'PEAR installer version';
if (isset($deps['required']['pearinstaller']['max'])) {
$info['Required Dependencies'] .= 's ' .
$deps['required']['pearinstaller']['min'] . '-' .
$deps['required']['pearinstaller']['max'];
} else {
$info['Required Dependencies'] .= ' ' .
$deps['required']['pearinstaller']['min'] . ' or newer';
}
if (isset($deps['required']['pearinstaller']['exclude'])) {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
$info['Not Compatible with'] .= "\n";
}
if (is_array($deps['required']['pearinstaller']['exclude'])) {
$deps['required']['pearinstaller']['exclude'] =
implode(', ', $deps['required']['pearinstaller']['exclude']);
}
$info['Not Compatible with'] .= "PEAR installer\n Versions " .
$deps['required']['pearinstaller']['exclude'];
}
foreach (array('Package', 'Extension') as $type) {
$index = strtolower($type);
if (isset($deps['required'][$index])) {
if (isset($deps['required'][$index]['name'])) {
$deps['required'][$index] = array($deps['required'][$index]);
}
foreach ($deps['required'][$index] as $package) {
if (isset($package['conflicts'])) {
$infoindex = 'Not Compatible with';
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
$info['Not Compatible with'] .= "\n";
}
} else {
$infoindex = 'Required Dependencies';
$info[$infoindex] .= "\n";
}
if ($index == 'extension') {
$name = $package['name'];
} else {
if (isset($package['channel'])) {
$name = $package['channel'] . '/' . $package['name'];
} else {
$name = '__uri/' . $package['name'] . ' (static URI)';
}
}
$info[$infoindex] .= "$type $name";
if (isset($package['uri'])) {
$info[$infoindex] .= "\n Download URI: $package[uri]";
continue;
}
if (isset($package['max']) && isset($package['min'])) {
$info[$infoindex] .= " \n Versions " .
$package['min'] . '-' . $package['max'];
} elseif (isset($package['min'])) {
$info[$infoindex] .= " \n Version " .
$package['min'] . ' or newer';
} elseif (isset($package['max'])) {
$info[$infoindex] .= " \n Version " .
$package['max'] . ' or older';
}
if (isset($package['recommended'])) {
$info[$infoindex] .= "\n Recommended version: $package[recommended]";
}
if (isset($package['exclude'])) {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
$info['Not Compatible with'] .= "\n";
}
if (is_array($package['exclude'])) {
$package['exclude'] = implode(', ', $package['exclude']);
}
$package['package'] = $package['name']; // for parsedPackageNameToString
if (isset($package['conflicts'])) {
$info['Not Compatible with'] .= '=> except ';
}
$info['Not Compatible with'] .= 'Package ' .
$reg->parsedPackageNameToString($package, true);
$info['Not Compatible with'] .= "\n Versions " . $package['exclude'];
}
}
}
}
if (isset($deps['required']['os'])) {
if (isset($deps['required']['os']['name'])) {
$dep['required']['os']['name'] = array($dep['required']['os']['name']);
}
foreach ($dep['required']['os'] as $os) {
if (isset($os['conflicts']) && $os['conflicts'] == 'yes') {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
$info['Not Compatible with'] .= "\n";
}
$info['Not Compatible with'] .= "$os[name] Operating System";
} else {
$info['Required Dependencies'] .= "\n";
$info['Required Dependencies'] .= "$os[name] Operating System";
}
}
}
if (isset($deps['required']['arch'])) {
if (isset($deps['required']['arch']['pattern'])) {
$dep['required']['arch']['pattern'] = array($dep['required']['os']['pattern']);
}
foreach ($dep['required']['arch'] as $os) {
if (isset($os['conflicts']) && $os['conflicts'] == 'yes') {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
$info['Not Compatible with'] .= "\n";
}
$info['Not Compatible with'] .= "OS/Arch matching pattern '/$os[pattern]/'";
} else {
$info['Required Dependencies'] .= "\n";
$info['Required Dependencies'] .= "OS/Arch matching pattern '/$os[pattern]/'";
}
}
}
if (isset($deps['optional'])) {
foreach (array('Package', 'Extension') as $type) {
$index = strtolower($type);
if (isset($deps['optional'][$index])) {
if (isset($deps['optional'][$index]['name'])) {
$deps['optional'][$index] = array($deps['optional'][$index]);
}
foreach ($deps['optional'][$index] as $package) {
if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
$infoindex = 'Not Compatible with';
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
$info['Not Compatible with'] .= "\n";
}
} else {
$infoindex = 'Optional Dependencies';
if (!isset($info['Optional Dependencies'])) {
$info['Optional Dependencies'] = '';
} else {
$info['Optional Dependencies'] .= "\n";
}
}
if ($index == 'extension') {
$name = $package['name'];
} else {
if (isset($package['channel'])) {
$name = $package['channel'] . '/' . $package['name'];
} else {
$name = '__uri/' . $package['name'] . ' (static URI)';
}
}
$info[$infoindex] .= "$type $name";
if (isset($package['uri'])) {
$info[$infoindex] .= "\n Download URI: $package[uri]";
continue;
}
if ($infoindex == 'Not Compatible with') {
// conflicts is only used to say that all versions conflict
continue;
}
if (isset($package['max']) && isset($package['min'])) {
$info[$infoindex] .= " \n Versions " .
$package['min'] . '-' . $package['max'];
} elseif (isset($package['min'])) {
$info[$infoindex] .= " \n Version " .
$package['min'] . ' or newer';
} elseif (isset($package['max'])) {
$info[$infoindex] .= " \n Version " .
$package['min'] . ' or older';
}
if (isset($package['recommended'])) {
$info[$infoindex] .= "\n Recommended version: $package[recommended]";
}
if (isset($package['exclude'])) {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
$info['Not Compatible with'] .= "\n";
}
if (is_array($package['exclude'])) {
$package['exclude'] = implode(', ', $package['exclude']);
}
$info['Not Compatible with'] .= "Package $package\n Versions " .
$package['exclude'];
}
}
}
}
}
if (isset($deps['group'])) {
if (!isset($deps['group'][0])) {
$deps['group'] = array($deps['group']);
}
foreach ($deps['group'] as $group) {
$info['Dependency Group ' . $group['attribs']['name']] = $group['attribs']['hint'];
$groupindex = $group['attribs']['name'] . ' Contents';
$info[$groupindex] = '';
foreach (array('Package', 'Extension') as $type) {
$index = strtolower($type);
if (isset($group[$index])) {
if (isset($group[$index]['name'])) {
$group[$index] = array($group[$index]);
}
foreach ($group[$index] as $package) {
if (!empty($info[$groupindex])) {
$info[$groupindex] .= "\n";
}
if ($index == 'extension') {
$name = $package['name'];
} else {
if (isset($package['channel'])) {
$name = $package['channel'] . '/' . $package['name'];
} else {
$name = '__uri/' . $package['name'] . ' (static URI)';
}
}
if (isset($package['uri'])) {
if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
$info[$groupindex] .= "Not Compatible with $type $name";
} else {
$info[$groupindex] .= "$type $name";
}
$info[$groupindex] .= "\n Download URI: $package[uri]";
continue;
}
if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
$info[$groupindex] .= "Not Compatible with $type $name";
continue;
}
$info[$groupindex] .= "$type $name";
if (isset($package['max']) && isset($package['min'])) {
$info[$groupindex] .= " \n Versions " .
$package['min'] . '-' . $package['max'];
} elseif (isset($package['min'])) {
$info[$groupindex] .= " \n Version " .
$package['min'] . ' or newer';
} elseif (isset($package['max'])) {
$info[$groupindex] .= " \n Version " .
$package['min'] . ' or older';
}
if (isset($package['recommended'])) {
$info[$groupindex] .= "\n Recommended version: $package[recommended]";
}
if (isset($package['exclude'])) {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
$info[$groupindex] .= "Not Compatible with\n";
}
if (is_array($package['exclude'])) {
$package['exclude'] = implode(', ', $package['exclude']);
}
$info[$groupindex] .= " Package $package\n Versions " .
$package['exclude'];
}
}
}
}
}
}
if ($obj->getPackageType() == 'bundle') {
$info['Bundled Packages'] = '';
foreach ($obj->getBundledPackages() as $package) {
if (!empty($info['Bundled Packages'])) {
$info['Bundled Packages'] .= "\n";
}
if (isset($package['uri'])) {
$info['Bundled Packages'] .= '__uri/' . $package['name'];
$info['Bundled Packages'] .= "\n (URI: $package[uri]";
} else {
$info['Bundled Packages'] .= $package['channel'] . '/' . $package['name'];
}
}
}
$info['package.xml version'] = '2.0';
if ($installed) {
if ($obj->getLastModified()) {
$info['Last Modified'] = date('Y-m-d H:i', $obj->getLastModified());
}
$v = $obj->getLastInstalledVersion();
$info['Previous Installed Version'] = $v ? $v : '- None -';
}
foreach ($info as $key => $value) {
$data['data'][] = array($key, $value);
}
$data['raw'] = $obj->getArray(); // no validation needed
 
$this->ui->outputData($data, 'package-info');
}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Build.xml
New file
0,0 → 1,10
<commands version="1.0">
<build>
<summary>Build an Extension From C Source</summary>
<function>doBuild</function>
<shortcut>b</shortcut>
<options />
<doc>[package.xml]
Builds one or more extensions contained in a package.</doc>
</build>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Auth.xml
New file
0,0 → 1,25
<commands version="1.0">
<login>
<summary>Connects and authenticates to remote server</summary>
<shortcut>li</shortcut>
<function>doLogin</function>
<options />
<doc>
Log in to the remote server. To use remote functions in the installer
that require any kind of privileges, you need to log in first. The
username and password you enter here will be stored in your per-user
PEAR configuration (~/.pearrc on Unix-like systems). After logging
in, your username and password will be sent along in subsequent
operations on the remote server.</doc>
</login>
<logout>
<summary>Logs out from the remote server</summary>
<shortcut>lo</shortcut>
<function>doLogout</function>
<options />
<doc>
Logs out from the remote server. This command does not actually
connect to the remote server, it only deletes the stored username and
password from your user configuration.</doc>
</logout>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Mirror.php
New file
0,0 → 1,153
<?php
/**
* PEAR_Command_Mirror (download-all command)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Alexander Merz <alexmerz@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Mirror.php,v 1.18 2006/03/02 18:14:13 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.2.0
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
 
/**
* PEAR commands for providing file mirrors
*
* @category pear
* @package PEAR
* @author Alexander Merz <alexmerz@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.2.0
*/
class PEAR_Command_Mirror extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'download-all' => array(
'summary' => 'Downloads each available package from the default channel',
'function' => 'doDownloadAll',
'shortcut' => 'da',
'options' => array(
'channel' =>
array(
'shortopt' => 'c',
'doc' => 'specify a channel other than the default channel',
'arg' => 'CHAN',
),
),
'doc' => '
Requests a list of available packages from the default channel ({config default_channel})
and downloads them to current working directory. Note: only
packages within preferred_state ({config preferred_state}) will be downloaded'
),
);
 
// }}}
 
// {{{ constructor
 
/**
* PEAR_Command_Mirror constructor.
*
* @access public
* @param object PEAR_Frontend a reference to an frontend
* @param object PEAR_Config a reference to the configuration data
*/
function PEAR_Command_Mirror(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
/**
* For unit-testing
*/
function &factory($a)
{
$a = &PEAR_Command::factory($a, $this->config);
return $a;
}
 
// {{{ doDownloadAll()
/**
* retrieves a list of avaible Packages from master server
* and downloads them
*
* @access public
* @param string $command the command
* @param array $options the command options before the command
* @param array $params the stuff after the command name
* @return bool true if succesful
* @throw PEAR_Error
*/
function doDownloadAll($command, $options, $params)
{
$savechannel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
$channel = isset($options['channel']) ? $options['channel'] :
$this->config->get('default_channel');
if (!$reg->channelExists($channel)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
$this->config->set('default_channel', $channel);
$this->ui->outputData('Using Channel ' . $this->config->get('default_channel'));
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$remoteInfo = array_flip($rest->listPackages($base));
} else {
$remote = &$this->config->getRemote();
$stable = ($this->config->get('preferred_state') == 'stable');
$remoteInfo = $remote->call("package.listAll", true, $stable, false);
}
if (PEAR::isError($remoteInfo)) {
return $remoteInfo;
}
$cmd = &$this->factory("download");
if (PEAR::isError($cmd)) {
return $cmd;
}
$this->ui->outputData('Using Preferred State of ' .
$this->config->get('preferred_state'));
$this->ui->outputData('Gathering release information, please wait...');
/**
* Error handling not necessary, because already done by
* the download command
*/
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $cmd->run('download', array('downloadonly' => true), array_keys($remoteInfo));
PEAR::staticPopErrorHandling();
$this->config->set('default_channel', $savechannel);
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage());
}
return true;
}
 
// }}}
}
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Config.xml
New file
0,0 → 1,92
<commands version="1.0">
<config-show>
<summary>Show All Settings</summary>
<function>doConfigShow</function>
<shortcut>csh</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>show configuration variables for another channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>[layer]
Displays all configuration values. An optional argument
may be used to tell which configuration layer to display. Valid
configuration layers are &quot;user&quot;, &quot;system&quot; and &quot;default&quot;. To display
configurations for different channels, set the default_channel
configuration variable and run config-show again.
</doc>
</config-show>
<config-get>
<summary>Show One Setting</summary>
<function>doConfigGet</function>
<shortcut>cg</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>show configuration variables for another channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>&lt;parameter&gt; [layer]
Displays the value of one configuration parameter. The
first argument is the name of the parameter, an optional second argument
may be used to tell which configuration layer to look in. Valid configuration
layers are &quot;user&quot;, &quot;system&quot; and &quot;default&quot;. If no layer is specified, a value
will be picked from the first layer that defines the parameter, in the order
just specified. The configuration value will be retrieved for the channel
specified by the default_channel configuration variable.
</doc>
</config-get>
<config-set>
<summary>Change Setting</summary>
<function>doConfigSet</function>
<shortcut>cs</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>show configuration variables for another channel</doc>
<arg>CHAN</arg>
</channel>
</options>
<doc>&lt;parameter&gt; &lt;value&gt; [layer]
Sets the value of one configuration parameter. The first argument is
the name of the parameter, the second argument is the new value. Some
parameters are subject to validation, and the command will fail with
an error message if the new value does not make sense. An optional
third argument may be used to specify in which layer to set the
configuration parameter. The default layer is &quot;user&quot;. The
configuration value will be set for the current channel, which
is controlled by the default_channel configuration variable.
</doc>
</config-set>
<config-help>
<summary>Show Information About Setting</summary>
<function>doConfigHelp</function>
<shortcut>ch</shortcut>
<options />
<doc>[parameter]
Displays help for a configuration parameter. Without arguments it
displays help for all configuration parameters.
</doc>
</config-help>
<config-create>
<summary>Create a Default configuration file</summary>
<function>doConfigCreate</function>
<shortcut>coc</shortcut>
<options>
<windows>
<shortopt>w</shortopt>
<doc>create a config file for a windows install</doc>
</windows>
</options>
<doc>&lt;root path&gt; &lt;filename&gt;
Create a default configuration file with all directory configuration
variables set to subdirectories of &lt;root path&gt;, and save it as &lt;filename&gt;.
This is useful especially for creating a configuration file for a remote
PEAR installation (using the --remoteconfig option of install, upgrade,
and uninstall).
</doc>
</config-create>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Test.php
New file
0,0 → 1,308
<?php
/**
* PEAR_Command_Test (run-tests)
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Test.php,v 1.15 2007/02/17 17:51:25 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
 
/**
* PEAR commands for login/logout
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
 
class PEAR_Command_Test extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'run-tests' => array(
'summary' => 'Run Regression Tests',
'function' => 'doRunTests',
'shortcut' => 'rt',
'options' => array(
'recur' => array(
'shortopt' => 'r',
'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum',
),
'ini' => array(
'shortopt' => 'i',
'doc' => 'actual string of settings to pass to php in format " -d setting=blah"',
'arg' => 'SETTINGS'
),
'realtimelog' => array(
'shortopt' => 'l',
'doc' => 'Log test runs/results as they are run',
),
'quiet' => array(
'shortopt' => 'q',
'doc' => 'Only display detail for failed tests',
),
'simple' => array(
'shortopt' => 's',
'doc' => 'Display simple output for all tests',
),
'package' => array(
'shortopt' => 'p',
'doc' => 'Treat parameters as installed packages from which to run tests',
),
'phpunit' => array(
'shortopt' => 'u',
'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests',
),
'tapoutput' => array(
'shortopt' => 't',
'doc' => 'Output run-tests.log in TAP-compliant format',
),
'cgi' => array(
'shortopt' => 'c',
'doc' => 'CGI php executable (needed for tests with POST/GET section)',
'arg' => 'PHPCGI',
),
),
'doc' => '[testfile|dir ...]
Run regression tests with PHP\'s regression testing script (run-tests.php).',
),
);
 
var $output;
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Test constructor.
*
* @access public
*/
function PEAR_Command_Test(&$ui, &$config)
{
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
// {{{ doRunTests()
 
function doRunTests($command, $options, $params)
{
if (isset($options['phpunit']) && isset($options['tapoutput'])) {
return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time');
}
require_once 'PEAR/Common.php';
require_once 'PEAR/RunTest.php';
require_once 'System.php';
$log = new PEAR_Common;
$log->ui = &$this->ui; // slightly hacky, but it will work
$run = new PEAR_RunTest($log, $options);
$tests = array();
if (isset($options['recur'])) {
$depth = 4;
} else {
$depth = 1;
}
if (!count($params)) {
$params[] = '.';
}
if (isset($options['package'])) {
$oldparams = $params;
$params = array();
$reg = &$this->config->getRegistry();
foreach ($oldparams as $param) {
$pname = $reg->parsePackageName($param, $this->config->get('default_channel'));
if (PEAR::isError($pname)) {
return $this->raiseError($pname);
}
$package = &$reg->getPackage($pname['package'], $pname['channel']);
if (!$package) {
return PEAR::raiseError('Unknown package "' .
$reg->parsedPackageNameToString($pname) . '"');
}
$filelist = $package->getFilelist();
foreach ($filelist as $name => $atts) {
if (isset($atts['role']) && $atts['role'] != 'test') {
continue;
}
if (isset($options['phpunit'])) {
if (!preg_match('/AllTests\.php$/i', $name)) {
continue;
}
} else {
if (!preg_match('/\.phpt$/', $name)) {
continue;
}
}
$params[] = $atts['installed_as'];
}
}
}
foreach ($params as $p) {
if (is_dir($p)) {
if (isset($options['phpunit'])) {
$dir = System::find(array($p, '-type', 'f',
'-maxdepth', $depth,
'-name', 'AllTests.php'));
} else {
$dir = System::find(array($p, '-type', 'f',
'-maxdepth', $depth,
'-name', '*.phpt'));
}
$tests = array_merge($tests, $dir);
} else {
if (isset($options['phpunit'])) {
if (!preg_match('/AllTests\.php$/i', $p)) {
continue;
}
$tests[] = $p;
} else {
if (!file_exists($p)) {
if (!preg_match('/\.phpt$/', $p)) {
$p .= '.phpt';
}
$dir = System::find(array(dirname($p), '-type', 'f',
'-maxdepth', $depth,
'-name', $p));
$tests = array_merge($tests, $dir);
} else {
$tests[] = $p;
}
}
}
}
$ini_settings = '';
if (isset($options['ini'])) {
$ini_settings .= $options['ini'];
}
if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) {
$ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}";
}
if ($ini_settings) {
$this->ui->outputData('Using INI settings: "' . $ini_settings . '"');
}
$skipped = $passed = $failed = array();
$this->ui->outputData('Running ' . count($tests) . ' tests', $command);
$start = time();
if (isset($options['realtimelog'])) {
if (file_exists('run-tests.log')) {
unlink('run-tests.log');
}
}
if (isset($options['tapoutput'])) {
$tap = '1..' . count($tests) . "\n";
}
$i = 1;
foreach ($tests as $t) {
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
if ($fp) {
fwrite($fp, "Running test $t...");
fclose($fp);
}
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$result = $run->run($t, $ini_settings);
PEAR::staticPopErrorHandling();
if (PEAR::isError($result)) {
$this->ui->log($result->getMessage());
continue;
}
if (isset($options['tapoutput'])) {
$tap .= $result[0] . ' ' . $i . $result[1] . "\n";
$i++;
continue;
}
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
if ($fp) {
fwrite($fp, "$result\n");
fclose($fp);
}
}
if ($result == 'FAILED') {
$failed[] = $t;
}
if ($result == 'PASSED') {
$passed[] = $t;
}
if ($result == 'SKIPPED') {
$skipped[] = $t;
}
}
$total = date('i:s', time() - $start);
if (isset($options['tapoutput'])) {
$fp = @fopen('run-tests.log', 'w');
if ($fp) {
fwrite($fp, $tap, strlen($tap));
fclose($fp);
$this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') .
'"', $command);
}
} else {
if (count($failed)) {
$output = "TOTAL TIME: $total\n";
$output .= count($passed) . " PASSED TESTS\n";
$output .= count($skipped) . " SKIPPED TESTS\n";
$output .= count($failed) . " FAILED TESTS:\n";
foreach ($failed as $failure) {
$output .= $failure . "\n";
}
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
} else {
$fp = @fopen('run-tests.log', 'w');
}
if ($fp) {
fwrite($fp, $output, strlen($output));
fclose($fp);
$this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command);
}
} elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) {
@unlink('run-tests.log');
}
}
$this->ui->outputData('TOTAL TIME: ' . $total);
$this->ui->outputData(count($passed) . ' PASSED TESTS', $command);
$this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command);
if (count($failed)) {
$this->ui->outputData(count($failed) . ' FAILED TESTS:', $command);
foreach ($failed as $failure) {
$this->ui->outputData($failure, $command);
}
}
 
return true;
}
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Install.xml
New file
0,0 → 1,254
<commands version="1.0">
<install>
<summary>Install Package</summary>
<function>doInstall</function>
<shortcut>i</shortcut>
<options>
<force>
<shortopt>f</shortopt>
<doc>will overwrite newer installed packages</doc>
</force>
<loose>
<shortopt>l</shortopt>
<doc>do not check for recommended dependency version</doc>
</loose>
<nodeps>
<shortopt>n</shortopt>
<doc>ignore dependencies, install anyway</doc>
</nodeps>
<register-only>
<shortopt>r</shortopt>
<doc>do not install files, only register the package as installed</doc>
</register-only>
<soft>
<shortopt>s</shortopt>
<doc>soft install, fail silently, or upgrade if already installed</doc>
</soft>
<nobuild>
<shortopt>B</shortopt>
<doc>don&apos;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
<doc>request uncompressed files when downloading</doc>
</nocompress>
<installroot>
<shortopt>R</shortopt>
<arg>DIR</arg>
<doc>root directory used when installing files (ala PHP&apos;s INSTALL_ROOT)</doc>
</installroot>
<ignore-errors>
<doc>force install even if there were errors</doc>
</ignore-errors>
<alldeps>
<shortopt>a</shortopt>
<doc>install all required and optional dependencies</doc>
</alldeps>
<onlyreqdeps>
<shortopt>o</shortopt>
<doc>install all required dependencies</doc>
</onlyreqdeps>
<offline>
<shortopt>O</shortopt>
<doc>do not attempt to download any urls or contact channels</doc>
</offline>
<pretend>
<shortopt>p</shortopt>
<doc>Only list the packages that would be downloaded</doc>
</pretend>
</options>
<doc>[channel/]&lt;package&gt; ...
Installs one or more PEAR packages. You can specify a package to
install in four ways:
 
&quot;Package-1.0.tgz&quot; : installs from a local file
 
&quot;http://example.com/Package-1.0.tgz&quot; : installs from
anywhere on the net.
 
&quot;package.xml&quot; : installs the package described in
package.xml. Useful for testing, or for wrapping a PEAR package in
another package manager such as RPM.
 
&quot;Package[-version/state][.tar]&quot; : queries your default channel&apos;s server
({config master_server}) and downloads the newest package with
the preferred quality/state ({config preferred_state}).
 
To retrieve Package version 1.1, use &quot;Package-1.1,&quot; to retrieve
Package state beta, use &quot;Package-beta.&quot; To retrieve an uncompressed
file, append .tar (make sure there is no file by the same name first)
 
To download a package from another channel, prefix with the channel name like
&quot;channel/Package&quot;
 
More than one package may be specified at once. It is ok to mix these
four ways of specifying packages.
</doc>
</install>
<upgrade>
<summary>Upgrade Package</summary>
<function>doInstall</function>
<shortcut>up</shortcut>
<options>
<force>
<shortopt>f</shortopt>
<doc>overwrite newer installed packages</doc>
</force>
<loose>
<shortopt>l</shortopt>
<doc>do not check for recommended dependency version</doc>
</loose>
<nodeps>
<shortopt>n</shortopt>
<doc>ignore dependencies, upgrade anyway</doc>
</nodeps>
<register-only>
<shortopt>r</shortopt>
<doc>do not install files, only register the package as upgraded</doc>
</register-only>
<nobuild>
<shortopt>B</shortopt>
<doc>don&apos;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
<doc>request uncompressed files when downloading</doc>
</nocompress>
<installroot>
<shortopt>R</shortopt>
<arg>DIR</arg>
<doc>root directory used when installing files (ala PHP&apos;s INSTALL_ROOT)</doc>
</installroot>
<ignore-errors>
<doc>force install even if there were errors</doc>
</ignore-errors>
<alldeps>
<shortopt>a</shortopt>
<doc>install all required and optional dependencies</doc>
</alldeps>
<onlyreqdeps>
<shortopt>o</shortopt>
<doc>install all required dependencies</doc>
</onlyreqdeps>
<offline>
<shortopt>O</shortopt>
<doc>do not attempt to download any urls or contact channels</doc>
</offline>
<pretend>
<shortopt>p</shortopt>
<doc>Only list the packages that would be downloaded</doc>
</pretend>
</options>
<doc>&lt;package&gt; ...
Upgrades one or more PEAR packages. See documentation for the
&quot;install&quot; command for ways to specify a package.
 
When upgrading, your package will be updated if the provided new
package has a higher version number (use the -f option if you need to
upgrade anyway).
 
More than one package may be specified at once.
</doc>
</upgrade>
<upgrade-all>
<summary>Upgrade All Packages</summary>
<function>doInstall</function>
<shortcut>ua</shortcut>
<options>
<nodeps>
<shortopt>n</shortopt>
<doc>ignore dependencies, upgrade anyway</doc>
</nodeps>
<register-only>
<shortopt>r</shortopt>
<doc>do not install files, only register the package as upgraded</doc>
</register-only>
<nobuild>
<shortopt>B</shortopt>
<doc>don&apos;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
<doc>request uncompressed files when downloading</doc>
</nocompress>
<installroot>
<shortopt>R</shortopt>
<arg>DIR</arg>
<doc>root directory used when installing files (ala PHP&apos;s INSTALL_ROOT)</doc>
</installroot>
<ignore-errors>
<doc>force install even if there were errors</doc>
</ignore-errors>
<loose>
<doc>do not check for recommended dependency version</doc>
</loose>
</options>
<doc>
Upgrades all packages that have a newer release available. Upgrades are
done only if there is a release available of the state specified in
&quot;preferred_state&quot; (currently {config preferred_state}), or a state considered
more stable.
</doc>
</upgrade-all>
<uninstall>
<summary>Un-install Package</summary>
<function>doUninstall</function>
<shortcut>un</shortcut>
<options>
<nodeps>
<shortopt>n</shortopt>
<doc>ignore dependencies, uninstall anyway</doc>
</nodeps>
<register-only>
<shortopt>r</shortopt>
<doc>do not remove files, only register the packages as not installed</doc>
</register-only>
<installroot>
<shortopt>R</shortopt>
<arg>DIR</arg>
<doc>root directory used when installing files (ala PHP&apos;s INSTALL_ROOT)</doc>
</installroot>
<ignore-errors>
<doc>force install even if there were errors</doc>
</ignore-errors>
<offline>
<shortopt>O</shortopt>
<doc>do not attempt to uninstall remotely</doc>
</offline>
</options>
<doc>[channel/]&lt;package&gt; ...
Uninstalls one or more PEAR packages. More than one package may be
specified at once. Prefix with channel name to uninstall from a
channel not in your default channel ({config default_channel})
</doc>
</uninstall>
<bundle>
<summary>Unpacks a Pecl Package</summary>
<function>doBundle</function>
<shortcut>bun</shortcut>
<options>
<destination>
<shortopt>d</shortopt>
<arg>DIR</arg>
<doc>Optional destination directory for unpacking (defaults to current path or &quot;ext&quot; if exists)</doc>
</destination>
<force>
<shortopt>f</shortopt>
<doc>Force the unpacking even if there were errors in the package</doc>
</force>
</options>
<doc>&lt;package&gt;
Unpacks a Pecl Package into the selected location. It will download the
package if needed.
</doc>
</bundle>
<run-scripts>
<summary>Run Post-Install Scripts bundled with a package</summary>
<function>doRunScripts</function>
<shortcut>rs</shortcut>
<options />
<doc>&lt;package&gt;
Run post-installation scripts in package &lt;package&gt;, if any exist.
</doc>
</run-scripts>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Pickle.xml
New file
0,0 → 1,40
<commands version="1.0">
<pickle>
<summary>Build PECL Package</summary>
<function>doPackage</function>
<shortcut>pi</shortcut>
<options>
<nocompress>
<shortopt>Z</shortopt>
<doc>Do not gzip the package file</doc>
</nocompress>
<showname>
<shortopt>n</shortopt>
<doc>Print the name of the packaged file.</doc>
</showname>
</options>
<doc>[descfile] [descfile2]
Creates a PECL package from its description file (usually called
package.xml). If a second packagefile is passed in, then
the packager will check to make sure that one is a package.xml
version 1.0, and the other is a package.xml version 2.0. The
package.xml version 1.0 will be saved as &quot;package.xml&quot; in the archive,
and the other as &quot;package2.xml&quot; in the archive&quot;
 
If no second file is passed in, and [descfile] is a package.xml 2.0,
an automatic conversion will be made to a package.xml 1.0. Note that
only simple package.xml 2.0 will be converted. package.xml 2.0 with:
 
- dependency types other than required/optional PECL package/ext/php/pearinstaller
- more than one extsrcrelease/zendextsrcrelease
- zendextbinrelease, extbinrelease, phprelease, or bundle release type
- dependency groups
- ignore tags in release filelist
- tasks other than replace
- custom roles
 
will cause pickle to fail, and output an error message. If your package2.xml
uses any of these features, you are best off using PEAR_PackageFileManager to
generate both package.xml.</doc>
</pickle>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Command/Registry.xml
New file
0,0 → 1,54
<commands version="1.0">
<list>
<summary>List Installed Packages In The Default Channel</summary>
<function>doList</function>
<shortcut>l</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>list installed packages from this channel</doc>
<arg>CHAN</arg>
</channel>
<allchannels>
<shortopt>a</shortopt>
<doc>list installed packages from all channels</doc>
</allchannels>
</options>
<doc>&lt;package&gt;
If invoked without parameters, this command lists the PEAR packages
installed in your php_dir ({config php_dir}). With a parameter, it
lists the files in a package.
</doc>
</list>
<list-files>
<summary>List Files In Installed Package</summary>
<function>doFileList</function>
<shortcut>fl</shortcut>
<options />
<doc>&lt;package&gt;
List the files in an installed package.
</doc>
</list-files>
<shell-test>
<summary>Shell Script Test</summary>
<function>doShellTest</function>
<shortcut>st</shortcut>
<options />
<doc>&lt;package&gt; [[relation] version]
Tests if a package is installed in the system. Will exit(1) if it is not.
&lt;relation&gt; The version comparison operator. One of:
&lt;, lt, &lt;=, le, &gt;, gt, &gt;=, ge, ==, =, eq, !=, &lt;&gt;, ne
&lt;version&gt; The version to compare with
</doc>
</shell-test>
<info>
<summary>Display information about a package</summary>
<function>doInfo</function>
<shortcut>in</shortcut>
<options />
<doc>&lt;package&gt;
Displays information about a package. The package argument may be a
local package file, an URL to a package file, or the name of an
installed package.</doc>
</info>
</commands>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Frontend/CLI.php
New file
0,0 → 1,790
<?php
/**
* PEAR_Frontend_CLI
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: CLI.php,v 1.66 2006/11/19 23:56:32 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
/**
* base class
*/
require_once 'PEAR/Frontend.php';
 
/**
* Command-line Frontend for the PEAR Installer
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Frontend_CLI extends PEAR_Frontend
{
// {{{ properties
 
/**
* What type of user interface this frontend is for.
* @var string
* @access public
*/
var $type = 'CLI';
var $lp = ''; // line prefix
 
var $params = array();
var $term = array(
'bold' => '',
'normal' => '',
);
 
// }}}
 
// {{{ constructor
 
function PEAR_Frontend_CLI()
{
parent::PEAR();
$term = getenv('TERM'); //(cox) $_ENV is empty for me in 4.1.1
if (function_exists('posix_isatty') && !posix_isatty(1)) {
// output is being redirected to a file or through a pipe
} elseif ($term) {
// XXX can use ncurses extension here, if available
if (preg_match('/^(xterm|vt220|linux)/', $term)) {
$this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109);
$this->term['normal']=sprintf("%c%c%c", 27, 91, 109);
} elseif (preg_match('/^vt100/', $term)) {
$this->term['bold'] = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0);
$this->term['normal']=sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0);
}
} elseif (OS_WINDOWS) {
// XXX add ANSI codes here
}
}
 
// }}}
 
// {{{ displayLine(text)
 
function displayLine($text)
{
trigger_error("PEAR_Frontend_CLI::displayLine deprecated", E_USER_ERROR);
}
 
function _displayLine($text)
{
print "$this->lp$text\n";
}
 
// }}}
// {{{ display(text)
 
function display($text)
{
trigger_error("PEAR_Frontend_CLI::display deprecated", E_USER_ERROR);
}
 
function _display($text)
{
print $text;
}
 
// }}}
// {{{ displayError(eobj)
 
/**
* @param object PEAR_Error object
*/
function displayError($eobj)
{
return $this->_displayLine($eobj->getMessage());
}
 
// }}}
// {{{ displayFatalError(eobj)
 
/**
* @param object PEAR_Error object
*/
function displayFatalError($eobj)
{
$this->displayError($eobj);
if (class_exists('PEAR_Config')) {
$config = &PEAR_Config::singleton();
if ($config->get('verbose') > 5) {
if (function_exists('debug_print_backtrace')) {
debug_print_backtrace();
} elseif (function_exists('debug_backtrace')) {
$trace = debug_backtrace();
$raised = false;
foreach ($trace as $i => $frame) {
if (!$raised) {
if (isset($frame['class']) && strtolower($frame['class']) ==
'pear' && strtolower($frame['function']) == 'raiseerror') {
$raised = true;
} else {
continue;
}
}
if (!isset($frame['class'])) {
$frame['class'] = '';
}
if (!isset($frame['type'])) {
$frame['type'] = '';
}
if (!isset($frame['function'])) {
$frame['function'] = '';
}
if (!isset($frame['line'])) {
$frame['line'] = '';
}
$this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]");
}
}
}
}
exit(1);
}
 
// }}}
// {{{ displayHeading(title)
 
function displayHeading($title)
{
trigger_error("PEAR_Frontend_CLI::displayHeading deprecated", E_USER_ERROR);
}
 
function _displayHeading($title)
{
print $this->lp.$this->bold($title)."\n";
print $this->lp.str_repeat("=", strlen($title))."\n";
}
 
// }}}
 
/**
* Instruct the runInstallScript method to skip a paramgroup that matches the
* id value passed in.
*
* This method is useful for dynamically configuring which sections of a post-install script
* will be run based on the user's setup, which is very useful for making flexible
* post-install scripts without losing the cross-Frontend ability to retrieve user input
* @param string
*/
function skipParamgroup($id)
{
$this->_skipSections[$id] = true;
}
 
function runPostinstallScripts(&$scripts)
{
foreach ($scripts as $i => $script) {
$this->runInstallScript($scripts[$i]->_params, $scripts[$i]->_obj);
}
}
 
/**
* @param array $xml contents of postinstallscript tag
* @param object $script post-installation script
* @param string install|upgrade
*/
function runInstallScript($xml, &$script)
{
$this->_skipSections = array();
if (!is_array($xml) || !isset($xml['paramgroup'])) {
$script->run(array(), '_default');
} else {
$completedPhases = array();
if (!isset($xml['paramgroup'][0])) {
$xml['paramgroup'] = array($xml['paramgroup']);
}
foreach ($xml['paramgroup'] as $group) {
if (isset($this->_skipSections[$group['id']])) {
// the post-install script chose to skip this section dynamically
continue;
}
if (isset($group['name'])) {
$paramname = explode('::', $group['name']);
if ($lastgroup['id'] != $paramname[0]) {
continue;
}
$group['name'] = $paramname[1];
if (isset($answers)) {
if (isset($answers[$group['name']])) {
switch ($group['conditiontype']) {
case '=' :
if ($answers[$group['name']] != $group['value']) {
continue 2;
}
break;
case '!=' :
if ($answers[$group['name']] == $group['value']) {
continue 2;
}
break;
case 'preg_match' :
if (!@preg_match('/' . $group['value'] . '/',
$answers[$group['name']])) {
continue 2;
}
break;
default :
return;
}
}
} else {
return;
}
}
$lastgroup = $group;
if (isset($group['instructions'])) {
$this->_display($group['instructions']);
}
if (!isset($group['param'][0])) {
$group['param'] = array($group['param']);
}
if (isset($group['param'])) {
if (method_exists($script, 'postProcessPrompts')) {
$prompts = $script->postProcessPrompts($group['param'], $group['id']);
if (!is_array($prompts) || count($prompts) != count($group['param'])) {
$this->outputData('postinstall', 'Error: post-install script did not ' .
'return proper post-processed prompts');
$prompts = $group['param'];
} else {
foreach ($prompts as $i => $var) {
if (!is_array($var) || !isset($var['prompt']) ||
!isset($var['name']) ||
($var['name'] != $group['param'][$i]['name']) ||
($var['type'] != $group['param'][$i]['type'])) {
$this->outputData('postinstall', 'Error: post-install script ' .
'modified the variables or prompts, severe security risk. ' .
'Will instead use the defaults from the package.xml');
$prompts = $group['param'];
}
}
}
$answers = $this->confirmDialog($prompts);
} else {
$answers = $this->confirmDialog($group['param']);
}
}
if ((isset($answers) && $answers) || !isset($group['param'])) {
if (!isset($answers)) {
$answers = array();
}
array_unshift($completedPhases, $group['id']);
if (!$script->run($answers, $group['id'])) {
$script->run($completedPhases, '_undoOnError');
return;
}
} else {
$script->run($completedPhases, '_undoOnError');
return;
}
}
}
}
 
/**
* Ask for user input, confirm the answers and continue until the user is satisfied
* @param array an array of arrays, format array('name' => 'paramname', 'prompt' =>
* 'text to display', 'type' => 'string'[, default => 'default value'])
* @return array
*/
function confirmDialog($params)
{
$answers = array();
$prompts = $types = array();
foreach ($params as $param) {
$prompts[$param['name']] = $param['prompt'];
$types[$param['name']] = $param['type'];
if (isset($param['default'])) {
$answers[$param['name']] = $param['default'];
} else {
$answers[$param['name']] = '';
}
}
$tried = false;
do {
if ($tried) {
$i = 1;
foreach ($answers as $var => $value) {
if (!strlen($value)) {
echo $this->bold("* Enter an answer for #" . $i . ": ({$prompts[$var]})\n");
}
$i++;
}
}
$answers = $this->userDialog('', $prompts, $types, $answers);
$tried = true;
} while (is_array($answers) && count(array_filter($answers)) != count($prompts));
return $answers;
}
// {{{ userDialog(prompt, [type], [default])
 
function userDialog($command, $prompts, $types = array(), $defaults = array(),
$screensize = 20)
{
if (!is_array($prompts)) {
return array();
}
$testprompts = array_keys($prompts);
$result = $defaults;
if (!defined('STDIN')) {
$fp = fopen('php://stdin', 'r');
} else {
$fp = STDIN;
}
reset($prompts);
if (count($prompts) == 1 && $types[key($prompts)] == 'yesno') {
foreach ($prompts as $key => $prompt) {
$type = $types[$key];
$default = @$defaults[$key];
print "$prompt ";
if ($default) {
print "[$default] ";
}
print ": ";
if (version_compare(phpversion(), '5.0.0', '<')) {
$line = fgets($fp, 2048);
} else {
if (!defined('STDIN')) {
define('STDIN', fopen('php://stdin', 'r'));
}
$line = fgets(STDIN, 2048);
}
if ($default && trim($line) == "") {
$result[$key] = $default;
} else {
$result[$key] = trim($line);
}
}
return $result;
}
while (true) {
$descLength = max(array_map('strlen', $prompts));
$descFormat = "%-{$descLength}s";
$last = count($prompts);
 
$i = 0;
foreach ($prompts as $n => $var) {
printf("%2d. $descFormat : %s\n", ++$i, $prompts[$n], isset($result[$n]) ?
$result[$n] : null);
}
 
print "\n1-$last, 'all', 'abort', or Enter to continue: ";
$tmp = trim(fgets($fp, 1024));
if (empty($tmp)) {
break;
}
if ($tmp == 'abort') {
return false;
}
if (isset($testprompts[(int)$tmp - 1])) {
$var = $testprompts[(int)$tmp - 1];
$desc = $prompts[$var];
$current = @$result[$var];
print "$desc [$current] : ";
$tmp = trim(fgets($fp, 1024));
if (trim($tmp) !== '') {
$result[$var] = trim($tmp);
}
} elseif ($tmp == 'all') {
foreach ($prompts as $var => $desc) {
$current = $result[$var];
print "$desc [$current] : ";
$tmp = trim(fgets($fp, 1024));
if (trim($tmp) !== '') {
$result[$var] = trim($tmp);
}
}
}
}
if (!defined('STDIN')) {
fclose($fp);
}
return $result;
}
 
// }}}
// {{{ userConfirm(prompt, [default])
 
function userConfirm($prompt, $default = 'yes')
{
trigger_error("PEAR_Frontend_CLI::userConfirm not yet converted", E_USER_ERROR);
static $positives = array('y', 'yes', 'on', '1');
static $negatives = array('n', 'no', 'off', '0');
print "$this->lp$prompt [$default] : ";
$fp = fopen("php://stdin", "r");
$line = fgets($fp, 2048);
fclose($fp);
$answer = strtolower(trim($line));
if (empty($answer)) {
$answer = $default;
}
if (in_array($answer, $positives)) {
return true;
}
if (in_array($answer, $negatives)) {
return false;
}
if (in_array($default, $positives)) {
return true;
}
return false;
}
 
// }}}
// {{{ startTable([params])
 
function startTable($params = array())
{
trigger_error("PEAR_Frontend_CLI::startTable deprecated", E_USER_ERROR);
}
 
function _startTable($params = array())
{
$params['table_data'] = array();
$params['widest'] = array(); // indexed by column
$params['highest'] = array(); // indexed by row
$params['ncols'] = 0;
$this->params = $params;
}
 
// }}}
// {{{ tableRow(columns, [rowparams], [colparams])
 
function tableRow($columns, $rowparams = array(), $colparams = array())
{
trigger_error("PEAR_Frontend_CLI::tableRow deprecated", E_USER_ERROR);
}
 
function _tableRow($columns, $rowparams = array(), $colparams = array())
{
$highest = 1;
for ($i = 0; $i < sizeof($columns); $i++) {
$col = &$columns[$i];
if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) {
$col = wordwrap($col, $colparams[$i]['wrap'], "\n", 0);
}
if (strpos($col, "\n") !== false) {
$multiline = explode("\n", $col);
$w = 0;
foreach ($multiline as $n => $line) {
if (strlen($line) > $w) {
$w = strlen($line);
}
}
$lines = sizeof($multiline);
} else {
$w = strlen($col);
}
 
if (isset($this->params['widest'][$i])) {
if ($w > $this->params['widest'][$i]) {
$this->params['widest'][$i] = $w;
}
} else {
$this->params['widest'][$i] = $w;
}
$tmp = count_chars($columns[$i], 1);
// handle unix, mac and windows formats
$lines = (isset($tmp[10]) ? $tmp[10] : (isset($tmp[13]) ? $tmp[13] : 0)) + 1;
if ($lines > $highest) {
$highest = $lines;
}
}
if (sizeof($columns) > $this->params['ncols']) {
$this->params['ncols'] = sizeof($columns);
}
$new_row = array(
'data' => $columns,
'height' => $highest,
'rowparams' => $rowparams,
'colparams' => $colparams,
);
$this->params['table_data'][] = $new_row;
}
 
// }}}
// {{{ endTable()
 
function endTable()
{
trigger_error("PEAR_Frontend_CLI::endTable deprecated", E_USER_ERROR);
}
 
function _endTable()
{
extract($this->params);
if (!empty($caption)) {
$this->_displayHeading($caption);
}
if (count($table_data) == 0) {
return;
}
if (!isset($width)) {
$width = $widest;
} else {
for ($i = 0; $i < $ncols; $i++) {
if (!isset($width[$i])) {
$width[$i] = $widest[$i];
}
}
}
$border = false;
if (empty($border)) {
$cellstart = '';
$cellend = ' ';
$rowend = '';
$padrowend = false;
$borderline = '';
} else {
$cellstart = '| ';
$cellend = ' ';
$rowend = '|';
$padrowend = true;
$borderline = '+';
foreach ($width as $w) {
$borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1);
$borderline .= '+';
}
}
if ($borderline) {
$this->_displayLine($borderline);
}
for ($i = 0; $i < sizeof($table_data); $i++) {
extract($table_data[$i]);
if (!is_array($rowparams)) {
$rowparams = array();
}
if (!is_array($colparams)) {
$colparams = array();
}
$rowlines = array();
if ($height > 1) {
for ($c = 0; $c < sizeof($data); $c++) {
$rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]);
if (sizeof($rowlines[$c]) < $height) {
$rowlines[$c] = array_pad($rowlines[$c], $height, '');
}
}
} else {
for ($c = 0; $c < sizeof($data); $c++) {
$rowlines[$c] = array($data[$c]);
}
}
for ($r = 0; $r < $height; $r++) {
$rowtext = '';
for ($c = 0; $c < sizeof($data); $c++) {
if (isset($colparams[$c])) {
$attribs = array_merge($rowparams, $colparams);
} else {
$attribs = $rowparams;
}
$w = isset($width[$c]) ? $width[$c] : 0;
//$cell = $data[$c];
$cell = $rowlines[$c][$r];
$l = strlen($cell);
if ($l > $w) {
$cell = substr($cell, 0, $w);
}
if (isset($attribs['bold'])) {
$cell = $this->bold($cell);
}
if ($l < $w) {
// not using str_pad here because we may
// add bold escape characters to $cell
$cell .= str_repeat(' ', $w - $l);
}
 
$rowtext .= $cellstart . $cell . $cellend;
}
if (!$border) {
$rowtext = rtrim($rowtext);
}
$rowtext .= $rowend;
$this->_displayLine($rowtext);
}
}
if ($borderline) {
$this->_displayLine($borderline);
}
}
 
// }}}
// {{{ outputData()
 
function outputData($data, $command = '_default')
{
switch ($command) {
case 'channel-info':
foreach ($data as $type => $section) {
if ($type == 'main') {
$section['data'] = array_values($section['data']);
}
$this->outputData($section);
}
break;
case 'install':
case 'upgrade':
case 'upgrade-all':
if (isset($data['release_warnings'])) {
$this->_displayLine('');
$this->_startTable(array(
'border' => false,
'caption' => 'Release Warnings'
));
$this->_tableRow(array($data['release_warnings']), null, array(1 => array('wrap' => 55)));
$this->_endTable();
$this->_displayLine('');
}
$this->_displayLine($data['data']);
break;
case 'search':
$this->_startTable($data);
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
}
 
foreach($data['data'] as $category) {
foreach($category as $pkg) {
$this->_tableRow($pkg, null, array(1 => array('wrap' => 55)));
}
};
$this->_endTable();
break;
case 'list-all':
$this->_startTable($data);
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
}
 
foreach($data['data'] as $category) {
foreach($category as $pkg) {
unset($pkg[4]);
unset($pkg[5]);
$this->_tableRow($pkg, null, array(1 => array('wrap' => 55)));
}
};
$this->_endTable();
break;
case 'config-show':
$data['border'] = false;
$opts = array(0 => array('wrap' => 30),
1 => array('wrap' => 20),
2 => array('wrap' => 35));
$this->_startTable($data);
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'],
array('bold' => true),
$opts);
}
foreach($data['data'] as $group) {
foreach($group as $value) {
if ($value[2] == '') {
$value[2] = "<not set>";
}
$this->_tableRow($value, null, $opts);
}
}
$this->_endTable();
break;
case 'remote-info':
$d = $data;
$data = array(
'caption' => 'Package details:',
'border' => false,
'data' => array(
array("Latest", $data['stable']),
array("Installed", $data['installed']),
array("Package", $data['name']),
array("License", $data['license']),
array("Category", $data['category']),
array("Summary", $data['summary']),
array("Description", $data['description']),
),
);
if (isset($d['deprecated']) && $d['deprecated']) {
$conf = &PEAR_Config::singleton();
$reg = $conf->getRegistry();
$name = $reg->parsedPackageNameToString($d['deprecated'], true);
$data['data'][] = array('Deprecated! use', $name);
}
default: {
if (is_array($data)) {
$this->_startTable($data);
$count = count($data['data'][0]);
if ($count == 2) {
$opts = array(0 => array('wrap' => 25),
1 => array('wrap' => 48)
);
} elseif ($count == 3) {
$opts = array(0 => array('wrap' => 30),
1 => array('wrap' => 20),
2 => array('wrap' => 35)
);
} else {
$opts = null;
}
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'],
array('bold' => true),
$opts);
}
foreach($data['data'] as $row) {
$this->_tableRow($row, null, $opts);
}
$this->_endTable();
} else {
$this->_displayLine($data);
}
}
}
}
 
// }}}
// {{{ log(text)
 
 
function log($text, $append_crlf = true)
{
if ($append_crlf) {
return $this->_displayLine($text);
}
return $this->_display($text);
}
 
 
// }}}
// {{{ bold($text)
 
function bold($text)
{
if (empty($this->term['bold'])) {
return strtoupper($text);
}
return $this->term['bold'] . $text . $this->term['normal'];
}
 
// }}}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Validate.php
New file
0,0 → 1,634
<?php
/**
* PEAR_Validate
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Validate.php,v 1.50 2006/09/25 05:12:21 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**#@+
* Constants for install stage
*/
define('PEAR_VALIDATE_INSTALLING', 1);
define('PEAR_VALIDATE_UNINSTALLING', 2); // this is not bit-mapped like the others
define('PEAR_VALIDATE_NORMAL', 3);
define('PEAR_VALIDATE_DOWNLOADING', 4); // this is not bit-mapped like the others
define('PEAR_VALIDATE_PACKAGING', 7);
/**#@-*/
require_once 'PEAR/Common.php';
require_once 'PEAR/Validator/PECL.php';
 
/**
* Validation class for package.xml - channel-level advanced validation
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Validate
{
var $packageregex = _PEAR_COMMON_PACKAGE_NAME_PREG;
/**
* @var PEAR_PackageFile_v1|PEAR_PackageFile_v2
*/
var $_packagexml;
/**
* @var int one of the PEAR_VALIDATE_* constants
*/
var $_state = PEAR_VALIDATE_NORMAL;
/**
* Format: ('error' => array('field' => name, 'reason' => reason), 'warning' => same)
* @var array
* @access private
*/
var $_failures = array('error' => array(), 'warning' => array());
 
/**
* Override this method to handle validation of normal package names
* @param string
* @return bool
* @access protected
*/
function _validPackageName($name)
{
return (bool) preg_match('/^' . $this->packageregex . '$/', $name);
}
 
/**
* @param string package name to validate
* @param string name of channel-specific validation package
* @final
*/
function validPackageName($name, $validatepackagename = false)
{
if ($validatepackagename) {
if (strtolower($name) == strtolower($validatepackagename)) {
return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*$/', $name);
}
}
return $this->_validPackageName($name);
}
 
/**
* This validates a bundle name, and bundle names must conform
* to the PEAR naming convention, so the method is final and static.
* @param string
* @final
* @static
*/
function validGroupName($name)
{
return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '$/', $name);
}
 
/**
* Determine whether $state represents a valid stability level
* @param string
* @return bool
* @static
* @final
*/
function validState($state)
{
return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable'));
}
 
/**
* Get a list of valid stability levels
* @return array
* @static
* @final
*/
function getValidStates()
{
return array('snapshot', 'devel', 'alpha', 'beta', 'stable');
}
 
/**
* Determine whether a version is a properly formatted version number that can be used
* by version_compare
* @param string
* @return bool
* @static
* @final
*/
function validVersion($ver)
{
return (bool) preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver);
}
 
/**
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
*/
function setPackageFile(&$pf)
{
$this->_packagexml = &$pf;
}
 
/**
* @access private
*/
function _addFailure($field, $reason)
{
$this->_failures['errors'][] = array('field' => $field, 'reason' => $reason);
}
 
/**
* @access private
*/
function _addWarning($field, $reason)
{
$this->_failures['warnings'][] = array('field' => $field, 'reason' => $reason);
}
 
function getFailures()
{
$failures = $this->_failures;
$this->_failures = array('warnings' => array(), 'errors' => array());
return $failures;
}
 
/**
* @param int one of the PEAR_VALIDATE_* constants
*/
function validate($state = null)
{
if (!isset($this->_packagexml)) {
return false;
}
if ($state !== null) {
$this->_state = $state;
}
$this->_failures = array('warnings' => array(), 'errors' => array());
$this->validatePackageName();
$this->validateVersion();
$this->validateMaintainers();
$this->validateDate();
$this->validateSummary();
$this->validateDescription();
$this->validateLicense();
$this->validateNotes();
if ($this->_packagexml->getPackagexmlVersion() == '1.0') {
$this->validateState();
$this->validateFilelist();
} elseif ($this->_packagexml->getPackagexmlVersion() == '2.0' ||
$this->_packagexml->getPackagexmlVersion() == '2.1') {
$this->validateTime();
$this->validateStability();
$this->validateDeps();
$this->validateMainFilelist();
$this->validateReleaseFilelist();
//$this->validateGlobalTasks();
$this->validateChangelog();
}
return !((bool) count($this->_failures['errors']));
}
 
/**
* @access protected
*/
function validatePackageName()
{
if ($this->_state == PEAR_VALIDATE_PACKAGING ||
$this->_state == PEAR_VALIDATE_NORMAL) {
if (($this->_packagexml->getPackagexmlVersion() == '2.0' ||
$this->_packagexml->getPackagexmlVersion() == '2.1') &&
$this->_packagexml->getExtends()) {
$version = $this->_packagexml->getVersion() . '';
$name = $this->_packagexml->getPackage();
$test = array_shift($a = explode('.', $version));
if ($test == '0') {
return true;
}
$vlen = strlen($test);
$majver = substr($name, strlen($name) - $vlen);
while ($majver && !is_numeric($majver{0})) {
$majver = substr($majver, 1);
}
if ($majver != $test) {
$this->_addWarning('package', "package $name extends package " .
$this->_packagexml->getExtends() . ' and so the name should ' .
'have a postfix equal to the major version like "' .
$this->_packagexml->getExtends() . $test . '"');
return true;
} elseif (substr($name, 0, strlen($name) - $vlen) !=
$this->_packagexml->getExtends()) {
$this->_addWarning('package', "package $name extends package " .
$this->_packagexml->getExtends() . ' and so the name must ' .
'be an extension like "' . $this->_packagexml->getExtends() .
$test . '"');
return true;
}
}
}
if (!$this->validPackageName($this->_packagexml->getPackage())) {
$this->_addFailure('name', 'package name "' .
$this->_packagexml->getPackage() . '" is invalid');
return false;
}
}
 
/**
* @access protected
*/
function validateVersion()
{
if ($this->_state != PEAR_VALIDATE_PACKAGING) {
if (!$this->validVersion($this->_packagexml->getVersion())) {
$this->_addFailure('version',
'Invalid version number "' . $this->_packagexml->getVersion() . '"');
}
return false;
}
$version = $this->_packagexml->getVersion();
$versioncomponents = explode('.', $version);
if (count($versioncomponents) != 3) {
$this->_addWarning('version',
'A version number should have 3 decimals (x.y.z)');
return true;
}
$name = $this->_packagexml->getPackage();
// version must be based upon state
switch ($this->_packagexml->getState()) {
case 'snapshot' :
return true;
case 'devel' :
if ($versioncomponents[0] . 'a' == '0a') {
return true;
}
if ($versioncomponents[0] == 0) {
$versioncomponents[0] = '0';
$this->_addWarning('version',
'version "' . $version . '" should be "' .
implode('.' ,$versioncomponents) . '"');
} else {
$this->_addWarning('version',
'packages with devel stability must be < version 1.0.0');
}
return true;
break;
case 'alpha' :
case 'beta' :
// check for a package that extends a package,
// like Foo and Foo2
if ($this->_state == PEAR_VALIDATE_PACKAGING) {
if (substr($versioncomponents[2], 1, 2) == 'rc') {
$this->_addFailure('version', 'Release Candidate versions ' .
'must have capital RC, not lower-case rc');
return false;
}
}
if (!$this->_packagexml->getExtends()) {
if ($versioncomponents[0] == '1') {
if ($versioncomponents[2]{0} == '0') {
if ($versioncomponents[2] == '0') {
// version 1.*.0000
$this->_addWarning('version',
'version 1.' . $versioncomponents[1] .
'.0 probably should not be alpha or beta');
return true;
} elseif (strlen($versioncomponents[2]) > 1) {
// version 1.*.0RC1 or 1.*.0beta24 etc.
return true;
} else {
// version 1.*.0
$this->_addWarning('version',
'version 1.' . $versioncomponents[1] .
'.0 probably should not be alpha or beta');
return true;
}
} else {
$this->_addWarning('version',
'bugfix versions (1.3.x where x > 0) probably should ' .
'not be alpha or beta');
return true;
}
} elseif ($versioncomponents[0] != '0') {
$this->_addWarning('version',
'major versions greater than 1 are not allowed for packages ' .
'without an <extends> tag or an identical postfix (foo2 v2.0.0)');
return true;
}
if ($versioncomponents[0] . 'a' == '0a') {
return true;
}
if ($versioncomponents[0] == 0) {
$versioncomponents[0] = '0';
$this->_addWarning('version',
'version "' . $version . '" should be "' .
implode('.' ,$versioncomponents) . '"');
}
} else {
$vlen = strlen($versioncomponents[0] . '');
$majver = substr($name, strlen($name) - $vlen);
while ($majver && !is_numeric($majver{0})) {
$majver = substr($majver, 1);
}
if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) {
$this->_addWarning('version', 'first version number "' .
$versioncomponents[0] . '" must match the postfix of ' .
'package name "' . $name . '" (' .
$majver . ')');
return true;
}
if ($versioncomponents[0] == $majver) {
if ($versioncomponents[2]{0} == '0') {
if ($versioncomponents[2] == '0') {
// version 2.*.0000
$this->_addWarning('version',
"version $majver." . $versioncomponents[1] .
'.0 probably should not be alpha or beta');
return false;
} elseif (strlen($versioncomponents[2]) > 1) {
// version 2.*.0RC1 or 2.*.0beta24 etc.
return true;
} else {
// version 2.*.0
$this->_addWarning('version',
"version $majver." . $versioncomponents[1] .
'.0 cannot be alpha or beta');
return true;
}
} else {
$this->_addWarning('version',
"bugfix versions ($majver.x.y where y > 0) should " .
'not be alpha or beta');
return true;
}
} elseif ($versioncomponents[0] != '0') {
$this->_addWarning('version',
"only versions 0.x.y and $majver.x.y are allowed for alpha/beta releases");
return true;
}
if ($versioncomponents[0] . 'a' == '0a') {
return true;
}
if ($versioncomponents[0] == 0) {
$versioncomponents[0] = '0';
$this->_addWarning('version',
'version "' . $version . '" should be "' .
implode('.' ,$versioncomponents) . '"');
}
}
return true;
break;
case 'stable' :
if ($versioncomponents[0] == '0') {
$this->_addWarning('version', 'versions less than 1.0.0 cannot ' .
'be stable');
return true;
}
if (!is_numeric($versioncomponents[2])) {
if (preg_match('/\d+(rc|a|alpha|b|beta)\d*/i',
$versioncomponents[2])) {
$this->_addWarning('version', 'version "' . $version . '" or any ' .
'RC/beta/alpha version cannot be stable');
return true;
}
}
// check for a package that extends a package,
// like Foo and Foo2
if ($this->_packagexml->getExtends()) {
$vlen = strlen($versioncomponents[0] . '');
$majver = substr($name, strlen($name) - $vlen);
while ($majver && !is_numeric($majver{0})) {
$majver = substr($majver, 1);
}
if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) {
$this->_addWarning('version', 'first version number "' .
$versioncomponents[0] . '" must match the postfix of ' .
'package name "' . $name . '" (' .
$majver . ')');
return true;
}
} elseif ($versioncomponents[0] > 1) {
$this->_addWarning('version', 'major version x in x.y.z may not be greater than ' .
'1 for any package that does not have an <extends> tag');
}
return true;
break;
default :
return false;
break;
}
}
 
/**
* @access protected
*/
function validateMaintainers()
{
// maintainers can only be truly validated server-side for most channels
// but allow this customization for those who wish it
return true;
}
 
/**
* @access protected
*/
function validateDate()
{
if ($this->_state == PEAR_VALIDATE_NORMAL ||
$this->_state == PEAR_VALIDATE_PACKAGING) {
 
if (!preg_match('/(\d\d\d\d)\-(\d\d)\-(\d\d)/',
$this->_packagexml->getDate(), $res) ||
count($res) < 4
|| !checkdate($res[2], $res[3], $res[1])
) {
$this->_addFailure('date', 'invalid release date "' .
$this->_packagexml->getDate() . '"');
return false;
}
 
 
if ($this->_state == PEAR_VALIDATE_PACKAGING &&
$this->_packagexml->getDate() != date('Y-m-d')) {
$this->_addWarning('date', 'Release Date "' .
$this->_packagexml->getDate() . '" is not today');
}
}
return true;
}
 
/**
* @access protected
*/
function validateTime()
{
if (!$this->_packagexml->getTime()) {
// default of no time value set
return true;
}
// packager automatically sets time, so only validate if
// pear validate is called
if ($this->_state = PEAR_VALIDATE_NORMAL) {
if (!preg_match('/\d\d:\d\d:\d\d/',
$this->_packagexml->getTime())) {
$this->_addFailure('time', 'invalid release time "' .
$this->_packagexml->getTime() . '"');
return false;
}
if (strtotime($this->_packagexml->getTime()) == -1) {
$this->_addFailure('time', 'invalid release time "' .
$this->_packagexml->getTime() . '"');
return false;
}
}
return true;
}
 
/**
* @access protected
*/
function validateState()
{
// this is the closest to "final" php4 can get
if (!PEAR_Validate::validState($this->_packagexml->getState())) {
if (strtolower($this->_packagexml->getState() == 'rc')) {
$this->_addFailure('state', 'RC is not a state, it is a version ' .
'postfix, use ' . $this->_packagexml->getVersion() . 'RC1, state beta');
}
$this->_addFailure('state', 'invalid release state "' .
$this->_packagexml->getState() . '", must be one of: ' .
implode(', ', PEAR_Validate::getValidStates()));
return false;
}
return true;
}
 
/**
* @access protected
*/
function validateStability()
{
$ret = true;
$packagestability = $this->_packagexml->getState();
$apistability = $this->_packagexml->getState('api');
if (!PEAR_Validate::validState($packagestability)) {
$this->_addFailure('state', 'invalid release stability "' .
$this->_packagexml->getState() . '", must be one of: ' .
implode(', ', PEAR_Validate::getValidStates()));
$ret = false;
}
$apistates = PEAR_Validate::getValidStates();
array_shift($apistates); // snapshot is not allowed
if (!in_array($apistability, $apistates)) {
$this->_addFailure('state', 'invalid API stability "' .
$this->_packagexml->getState('api') . '", must be one of: ' .
implode(', ', $apistates));
$ret = false;
}
return $ret;
}
 
/**
* @access protected
*/
function validateSummary()
{
return true;
}
 
/**
* @access protected
*/
function validateDescription()
{
return true;
}
 
/**
* @access protected
*/
function validateLicense()
{
return true;
}
 
/**
* @access protected
*/
function validateNotes()
{
return true;
}
 
/**
* for package.xml 2.0 only - channels can't use package.xml 1.0
* @access protected
*/
function validateDependencies()
{
return true;
}
 
/**
* for package.xml 1.0 only
* @access private
*/
function _validateFilelist()
{
return true; // placeholder for now
}
 
/**
* for package.xml 2.0 only
* @access protected
*/
function validateMainFilelist()
{
return true; // placeholder for now
}
 
/**
* for package.xml 2.0 only
* @access protected
*/
function validateReleaseFilelist()
{
return true; // placeholder for now
}
 
/**
* @access protected
*/
function validateChangelog()
{
return true;
}
 
/**
* @access protected
*/
function validateFilelist()
{
return true;
}
 
/**
* @access protected
*/
function validateDeps()
{
return true;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Info.php
New file
0,0 → 1,420
<?php
/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Davey Shafik <davey@pixelated-dreams.com> |
// +----------------------------------------------------------------------+
//
// $Id: Info.php,v 1.19 2005/01/03 17:33:43 davey Exp $
 
require_once 'PEAR/Remote.php';
require_once 'PEAR/Registry.php';
 
/**
* PEAR_Info generate phpinfo() style PEAR information
*/
 
class PEAR_Info
{
 
/**
* PEAR_Info Constructor
* @param pear_dir string[optional]
* @return bool
* @access public
*/
 
function PEAR_Info($pear_dir = FALSE, $pear_user_config = FALSE)
{
if($pear_user_config === FALSE) {
$this->config = new PEAR_Config();
} else {
$this->config = new PEAR_Config($pear_user_config);
}
if ($pear_dir != FALSE) {
$this->config->set('php_dir',$pear_dir);
}
if (defined('PEAR_INFO_PROXY')) {
$this->config->set('http_proxy',PEAR_INFO_PROXY);
}
$this->r = new PEAR_Remote($this->config);
$this->reg = new PEAR_Registry($this->config->get('php_dir'));
// get PEARs packageInfo to show version number at the top of the HTML
$pear = $this->reg->packageInfo("PEAR");
$this->list_options = false;
if ($this->config->get('preferred_state') == 'stable') {
$this->list_options = true;
}
ob_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>PEAR :: PEAR_Info()</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<style type="text/css">
body {background-color: #ffffff; color: #000000; white-space: normal;}
body, td, th, h1, h2 {font-family: sans-serif;}
a:link {color: #006600; text-decoration: none;}
a:visited { color: #003300; text-decoration: none;}
a:hover {text-decoration: underline;}
table {border-collapse: collapse; width: 600px; max-width: 600px; margin-left: auto; margin-right: auto; border: 0px; padding: 0px;}
td, th { border: 1px solid #000000; font-size: 75%; vertical-align: baseline;}
h1 {font-size: 150%; text-align: center;}
h2 {font-size: 125%; text-align: center;}
.p {text-align: left;}
.e {background-color: #006600; font-weight: bold; color: #FFFFFF; width: 100px;}
.e a:link { color: #FFFFFF; }
.e a:visited { color: #FFFFFF; }
.h {background-color: #339900; font-weight: bold;}
.v {background-color: #D9D9D9;}
img {float: right; border: 0px;}
</style>
</head>
<body>
<table>
<tr class="h">
<td>
<a href="http://pear.php.net/"><img src="<?php echo $_SERVER['PHP_SELF'];?>?pear_image=true" alt="PEAR Logo" /></a><h1 class="p">PEAR <?php echo $pear['version']; ?></h1>
</td>
</tr>
</table>
<?php
if (!isset($_GET['credits'])) {
echo '<h1><a href="' .$_SERVER['PHP_SELF']. '?credits=true">PEAR Credits</a></h1>';
// Get packageInfo and Show the HTML for the Packages
$this->getConfig();
echo '<br />';
$this->getPackages();
 
} else {
$this->getCredits();
}
?>
</body>
</html>
<?php
$this->info = ob_get_contents();
ob_end_clean();
/* With later versions of this where we properly implement the CLI such and stuff
this will return the actual status of whether or not creating the PEAR_Info object worked */
return true;
}
 
/**
* Set PEAR http_proxy for remote calls
* @param proxy string
* @return bool
* @access public
*/
 
function setProxy($proxy)
{
define('PEAR_INFO_PROXY',$proxy);
return true;
}
 
/**
* Retrieve and format PEAR Packages info
* @return void
* @access private
*/
 
function getPackages()
{
$latest = @$this->r->call('package.listLatestReleases');
$available = $this->reg->listPackages();
if (PEAR::isError($available)) {
echo '<h1 style="font-size: 12px;">An Error occured fetching the package list. Please try again.</h1>';
return FALSE;
}
if (!is_array($available)) {
echo '<h1 style="font-size: 12px;">The package list could not be fetched from the remote server. Please try again.</h1>';
return FALSE;
}
natcasesort($available);
if ((PEAR::isError($latest)) || (!is_array($latest))) {
$latest = FALSE;
}
$packages = '';
foreach ($available as $name) {
$installed = $this->reg->packageInfo($name);
if (strlen($installed['package']) > 1) {
if (!isset($old_index)) {
$old_index = '';
}
$current_index = $name{0};
if (strtolower($current_index) != strtolower($old_index)) {
$packages .= '<a name="' .$current_index. '"></a>';
$old_index = $current_index;
$this->index[] = $current_index;
}
$packages .= '
<h2><a name="pkg_' .trim($installed['package']). '">' .trim($installed['package']). '</a></h2>
<table>
<tr class="v">
<td class="e">
Summary
</td>
<td>
' .nl2br(htmlentities(trim($installed['summary']))). '
</td>
</tr>
<tr class="v">
<td class="e">
Version
</td>
<td>
' .trim($installed['version']). '
</td>
</tr>
<tr class="v">
<td class="e">
Description
</td>
<td>
' .nl2br(htmlentities(trim($installed['description']))). '
</td>
</tr>
<tr class="v">
<td class="e">
State
</td>
<td>
' .trim($installed['release_state']). '
</td>
</tr>
<tr class="v">
<td class="e">
Information
</td>
</tr>';
if ($latest != FALSE) {
if (isset($latest[$installed['package']])) {
if (version_compare($latest[$installed['package']]['version'],$installed['version'],'>')) {
$packages .= '<tr class="v">
<td class="e">
Latest Version
</td>
<td>
<a href="http://pear.php.net/get/' .trim($installed['package']). '">' .$latest[$installed['package']]['version'] . '</a>
('. $latest[$installed['package']]['state']. ')
</td>
</tr>';
}
}
}
$packages .= ' <tr>
<td colspan="2" class="v"><a href="#top">Top</a></td>
</tr>
</table>';
}
}
?>
<h2><a name="top">PEAR Packages</a></h2>
<table style="padding: 3px;">
<tr>
<td class="e">
Index
</td>
</tr>
<tr>
<td class ="v" style="text-align: center">
<?php
foreach ($this->index as $i) {
?>
| <a href="#<?php echo $i; ?>"><?php echo strtoupper($i); ?></a>
<?php
}
?>|
</td>
</tr>
</table>
<br />
<?php
echo $packages;
}
 
/**
* Retrieves and formats the PEAR Config data
* @return void
* @access private
*/
 
function getConfig()
{
$keys = $this->config->getKeys();
sort($keys);
?>
<h2>PEAR Config</h2>
<table>
<?php
foreach ($keys as $key) {
if (($key != 'password') && ($key != 'username') && ($key != 'sig_keyid') && ($key != 'http_proxy')) {
?>
<tr class="v">
<td class="e"><?php echo $key; ?></td>
<td><?php echo $this->config->get($key); ?></td>
</tr>
<?php
}
}
?>
</table>
<?php
}
 
/**
* Retrieves and formats the PEAR Credits
* @return void
* @access private
*/
 
function getCredits()
{
?>
<h1>PEAR Credits</h1>
<table>
<tr class="h">
<td>
PEAR Website Team
</td>
</tr>
<tr class="v">
<td>
<a href="http://pear.php.net/account-info.php?handle=ssb">Stig Bakken</a>,
<a href="http://pear.php.net/account-info.php?handle=cox">Thomas V.V.Cox</a>,
<a href="http://pear.php.net/account-info.php?handle=mj">Martin Jansen</a>,
<a href="http://pear.php.net/account-info.php?handle=cmv">Colin Viebrock</a>,
<a href="http://pear.php.net/account-info.php?handle=richard">Richard Heyes</a>
</td>
</tr>
</table>
<br />
<table>
<tr class="h">
<td>
PEAR documentation team
</td>
</tr>
<tr class="v">
<td>
<a href="http://pear.php.net/account-info.php?handle=cox">Thomas V.V.Cox</a>,
<a href="http://pear.php.net/account-info.php?handle=mj">Martin Jansen</a>,
<a href="http://pear.php.net/account-info.php?handle=alexmerz">Alexander Merz</a>
</td>
</tr>
</table>
<?php
$available = $this->reg->listPackages();
 
if (PEAR::isError($available)) {
echo '<h1 style="font-size: 12px;">An Error occured fetching the credits from the remote server. Please try again.</h1>';
return FALSE;
}
if (!is_array($available)) {
echo '<h1 style="font-size: 12px;">The credits could not be fetched from the remote server. Please try again.</h1>';
return FALSE;
}
echo '<br /><table border="0" cellpadding="3" width="600">';
echo '<tr class="h"><td>Package</td><td>Maintainers</td></tr>';
foreach ($available as $name) {
$installed = $this->reg->packageInfo($name);
if (strlen($installed['package']) > 1) {
?>
<tr>
<td class="e">
<a href="http://pear.php.net/<?php echo trim(strtolower($installed['package'])); ?>"><?php echo trim($installed['package']); ?></a>
 
</td>
<td class="v">
<?php
$maintainers = array();
foreach ($installed['maintainers'] as $i) {
$maintainers[] = '<a href="http://pear.php.net/account-info.php?handle=' .$i['handle']. '">' .htmlentities($i['name']). '</a>' .' (' .$i['role']. ')';
}
echo implode(', ',$maintainers);
?>
</td>
</tr>
<?php
}
}
echo '</table>';
}
 
/**
* outputs the PEAR logo
* @return void
* @access public
*/
 
function pearImage()
{
$pear_image = 'R0lGODlhaAAyAMT/AMDAwP3+/TWaAvD47Pj89vz++zebBDmcBj6fDEekFluvKmu3PvX68ujz4XvBS8LgrNXqxeHw1ZnPaa/dgvv9+cLqj8LmltD2msnuls';
$pear_image .= '3xmszwmf7+/f///wAAAAAAAAAAACH5BAEAAAAALAAAAABoADIAQAX/ICCOZGmeaKqubOtWWjwJphLLgH1XUu//C1Jisfj9YLEKQnSY3GaixWQqQTkYHM4';
$pear_image .= 'AMulNLJFC9pEwIW/odKU8cqTfsWoTTtcomU4ZjbR4ZP+AgYKCG0EiZ1AuiossEhwEXRMEg5SVWQ6MmZqKWD0QlqCUEHubpaYlExwRPRZioZZVp7KzKQoS';
$pear_image .= 'DxANDLsNXA5simd2FcQYb4YAc2jEU80TmAAIztPCMcjKdg4OEsZJmwIWWQPQI4ikIwtoVQnddgrv8PFlCWgYCwkI+fp5dkvJ/IlUKMCy6tYrDhNIIKLFE';
$pear_image .= 'AWCTxse+ABD4SClWA0zovAjcUJFi6EwahxZwoGqHhFA/4IqoICkyxQSKkbo0gDkuBXV4FRAJkRCnTgi2P28IcEfk5xpWppykFJVuScmEvDTEETAVJ6bEp';
$pear_image .= 'ypcADPkz3pvKVAICHChkC7siQ08zVqu4Q6hgIFEFZuEn/KMgRUkaBmAQs+cEHgIiHVH5EAFpIgW4+NT6LnaqhDwe/Ov7YOmWZp4MkiAWBIl0kAVsJWuzc';
$pear_image .= 'YpdiNgddc0E8cKBAu/FElBwagMb88ZZKDRAkWJtkWhHh3wwUbKHQJN3wQAaXGR2LpArv5oFHRR34C7Mf6oLXZNfqBgNI7oOLhj1f8PaGpygHQ0xtP8MDV';
$pear_image .= 'KwYTSKcgxr9/hS6/pCCAAg5M4B9/sWh1YP9/XSgQWRML/idBfKUc4IBET9lFjggKhDYZAELZJYEBI2BDB3ouNBEABwE8gAwiCcSYgAKqPdEVAG7scM8BP';
$pear_image .= 'PZ4AIlM+OgjAgpMhRE24OVoBwsIFEGFA7ZkQQBWienWxmRa7XDjKZXhBdAeSmKQwgLuUVLICa6VEKIGcK2mQWoVZHCBXJblJUFkY06yAXlGsPIHBEYdYi';
$pear_image .= 'WHb+WQBgaIJqqoHFNpgMGB7dT5ZQuG/WbBAIAUEEFNfwxAWpokTIXJAWdgoJ9kRFG2g5eDRpXSBpEIF0oEQFaZhDbaSFANRgqcJoEDRARLREtxOQpsPO9';
$pear_image .= '06ZUeJgjQB6dZUPBAdwcF8KLXXRVQaKFcsRRLJ6vMiiCNKxRE8ECZKgUA3Va4arOAAqdGRWO7uMZH5AL05gvsjQbg6y4NCjQ1kw8TVGcbdoKGKx8j3bGH';
$pear_image .= '7nARBArqwi0gkFJBrZiXBQRbHoIgnhSjcEBKfD7c3HMhz+JIQSY3t8GGKW+SUhfUajxGzKd0IoHBNkNQK86ZYEqdzYA8AHQpqXRUm80oHs1CAgMoBxzRq';
$pear_image .= 'vzs9CIKECC1JBp7enUpfXHApwVYNAfo16c4IrYPLVdSAJVob7IAtCBFQGHcs/RRdiUDPHA33oADEAIAOw==';
header('content-type: image/gif');
echo base64_decode($pear_image);
}
 
/**
* Shows PEAR_Info output
* @return void
* @access public
*/
 
function show()
{
echo $this->info;
}
/**
* Check if a package is installed
*/
function packageInstalled($package_name, $version = null, $pear_user_config = null)
{
if(is_null($pear_user_config)) {
$config = new PEAR_Config();
} else {
$config = new PEAR_Config($pear_user_config);
}
$reg = new PEAR_Registry($config->get('php_dir'));
if (is_null($version)) {
return $reg->packageExists($package_name);
} else {
$installed = $reg->packageInfo($package_name);
return version_compare($version, $installed['version'], '<=');
}
}
}
 
if (isset($_GET['pear_image'])) {
PEAR_Info::pearImage();
exit;
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFile.php
New file
0,0 → 1,474
<?php
/**
* PEAR_PackageFile, package.xml parsing utility class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: PackageFile.php,v 1.40 2006/09/25 05:12:21 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* needed for PEAR_VALIDATE_* constants
*/
require_once 'PEAR/Validate.php';
/**
* Error code if the package.xml <package> tag does not contain a valid version
*/
define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1);
/**
* Error code if the package.xml <package> tag version is not supported (version 1.0 and 1.1 are the only supported versions,
* currently
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2);
/**
* Abstraction for the package.xml package description file
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_PackageFile
{
/**
* @var PEAR_Config
*/
var $_config;
var $_debug;
/**
* Temp directory for uncompressing tgz files.
* @var string|false
*/
var $_tmpdir;
var $_logger = false;
/**
* @var boolean
*/
var $_rawReturn = false;
 
/**
*
* @param PEAR_Config $config
* @param ? $debug
* @param string @tmpdir Optional temporary directory for uncompressing
* files
*/
function PEAR_PackageFile(&$config, $debug = false, $tmpdir = false)
{
$this->_config = $config;
$this->_debug = $debug;
$this->_tmpdir = $tmpdir;
}
 
/**
* Turn off validation - return a parsed package.xml without checking it
*
* This is used by the package-validate command
*/
function rawReturn()
{
$this->_rawReturn = true;
}
 
function setLogger(&$l)
{
$this->_logger = &$l;
}
 
/**
* Create a PEAR_PackageFile_Parser_v* of a given version.
* @param int $version
* @return PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1
*/
function &parserFactory($version)
{
if (!in_array($version{0}, array('1', '2'))) {
$a = false;
return $a;
}
include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php';
$version = $version{0};
$class = "PEAR_PackageFile_Parser_v$version";
$a = new $class;
return $a;
}
 
/**
* For simpler unit-testing
* @return string
*/
function getClassPrefix()
{
return 'PEAR_PackageFile_v';
}
 
/**
* Create a PEAR_PackageFile_v* of a given version.
* @param int $version
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v1
*/
function &factory($version)
{
if (!in_array($version{0}, array('1', '2'))) {
$a = false;
return $a;
}
include_once 'PEAR/PackageFile/v' . $version{0} . '.php';
$version = $version{0};
$class = $this->getClassPrefix() . $version;
$a = new $class;
return $a;
}
 
/**
* Create a PEAR_PackageFile_v* from its toArray() method
*
* WARNING: no validation is performed, the array is assumed to be valid,
* always parse from xml if you want validation.
* @param array $arr
* @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2
* @uses factory() to construct the returned object.
*/
function &fromArray($arr)
{
if (isset($arr['xsdversion'])) {
$obj = &$this->factory($arr['xsdversion']);
if ($this->_logger) {
$obj->setLogger($this->_logger);
}
$obj->setConfig($this->_config);
$obj->fromArray($arr);
return $obj;
} else {
if (isset($arr['package']['attribs']['version'])) {
$obj = &$this->factory($arr['package']['attribs']['version']);
} else {
$obj = &$this->factory('1.0');
}
if ($this->_logger) {
$obj->setLogger($this->_logger);
}
$obj->setConfig($this->_config);
$obj->fromArray($arr);
return $obj;
}
}
 
/**
* Create a PEAR_PackageFile_v* from an XML string.
* @access public
* @param string $data contents of package.xml file
* @param int $state package state (one of PEAR_VALIDATE_* constants)
* @param string $file full path to the package.xml file (and the files
* it references)
* @param string $archive optional name of the archive that the XML was
* extracted from, if any
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @uses parserFactory() to construct a parser to load the package.
*/
function &fromXmlString($data, $state, $file, $archive = false)
{
if (preg_match('/<package[^>]+version="([0-9]+\.[0-9]+)"/', $data, $packageversion)) {
if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) {
return PEAR::raiseError('package.xml version "' . $packageversion[1] .
'" is not supported, only 1.0, 2.0, and 2.1 are supported.');
}
$object = &$this->parserFactory($packageversion[1]);
if ($this->_logger) {
$object->setLogger($this->_logger);
}
$object->setConfig($this->_config);
$pf = $object->parse($data, $file, $archive);
if (PEAR::isError($pf)) {
return $pf;
}
if ($this->_rawReturn) {
return $pf;
}
if ($pf->validate($state)) {
if ($this->_logger) {
if ($pf->getValidationWarnings(false)) {
foreach ($pf->getValidationWarnings() as $warning) {
$this->_logger->log(0, 'WARNING: ' . $warning['message']);
}
}
}
if (method_exists($pf, 'flattenFilelist')) {
$pf->flattenFilelist(); // for v2
}
return $pf;
} else {
if ($this->_config->get('verbose') > 0) {
if ($this->_logger) {
if ($pf->getValidationWarnings(false)) {
foreach ($pf->getValidationWarnings(false) as $warning) {
$this->_logger->log(0, 'ERROR: ' . $warning['message']);
}
}
}
}
$a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed',
2, null, null, $pf->getValidationWarnings());
return $a;
}
} elseif (preg_match('/<package[^>]+version="([^"]+)"/', $data, $packageversion)) {
$a = PEAR::raiseError('package.xml file "' . $file .
'" has unsupported package.xml <package> version "' . $packageversion[1] . '"');
return $a;
} else {
if (!class_exists('PEAR_ErrorStack')) {
require_once 'PEAR/ErrorStack.php';
}
PEAR_ErrorStack::staticPush('PEAR_PackageFile',
PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION,
'warning', array('xml' => $data), 'package.xml "' . $file .
'" has no package.xml <package> version');
$object = &$this->parserFactory('1.0');
$object->setConfig($this->_config);
$pf = $object->parse($data, $file, $archive);
if (PEAR::isError($pf)) {
return $pf;
}
if ($this->_rawReturn) {
return $pf;
}
if ($pf->validate($state)) {
if ($this->_logger) {
if ($pf->getValidationWarnings(false)) {
foreach ($pf->getValidationWarnings() as $warning) {
$this->_logger->log(0, 'WARNING: ' . $warning['message']);
}
}
}
if (method_exists($pf, 'flattenFilelist')) {
$pf->flattenFilelist(); // for v2
}
return $pf;
} else {
$a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed',
2, null, null, $pf->getValidationWarnings());
return $a;
}
}
}
 
/**
* Register a temporary file or directory. When the destructor is
* executed, all registered temporary files and directories are
* removed.
*
* @param string $file name of file or directory
* @return void
*/
function addTempFile($file)
{
$GLOBALS['_PEAR_Common_tempfiles'][] = $file;
}
 
/**
* Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file.
* @access public
* @param string contents of package.xml file
* @param int package state (one of PEAR_VALIDATE_* constants)
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @using Archive_Tar to extract the files
* @using fromPackageFile() to load the package after the package.xml
* file is extracted.
*/
function &fromTgzFile($file, $state)
{
if (!class_exists('Archive_Tar')) {
require_once 'Archive/Tar.php';
}
$tar = new Archive_Tar($file);
if ($this->_debug <= 1) {
$tar->pushErrorHandling(PEAR_ERROR_RETURN);
}
$content = $tar->listContent();
if ($this->_debug <= 1) {
$tar->popErrorHandling();
}
if (!is_array($content)) {
if (is_string($file) && strlen($file < 255) &&
(!file_exists($file) || !@is_file($file))) {
$ret = PEAR::raiseError("could not open file \"$file\"");
return $ret;
}
$file = realpath($file);
$ret = PEAR::raiseError("Could not get contents of package \"$file\"".
'. Invalid tgz file.');
return $ret;
} else {
if (!count($content) && !@is_file($file)) {
$ret = PEAR::raiseError("could not open file \"$file\"");
return $ret;
}
}
$xml = null;
$origfile = $file;
foreach ($content as $file) {
$name = $file['filename'];
if ($name == 'package2.xml') { // allow a .tgz to distribute both versions
$xml = $name;
break;
}
if ($name == 'package.xml') {
$xml = $name;
break;
} elseif (ereg('package.xml$', $name, $match)) {
$xml = $name;
break;
}
}
if ($this->_tmpdir) {
$tmpdir = $this->_tmpdir;
} else {
$tmpdir = System::mkTemp(array('-d', 'pear'));
PEAR_PackageFile::addTempFile($tmpdir);
}
$this->_extractErrors();
PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors'));
if (!$xml || !$tar->extractList(array($xml), $tmpdir)) {
$extra = implode("\n", $this->_extractErrors());
if ($extra) {
$extra = ' ' . $extra;
}
PEAR::staticPopErrorHandling();
$ret = PEAR::raiseError('could not extract the package.xml file from "' .
$origfile . '"' . $extra);
return $ret;
}
PEAR::staticPopErrorHandling();
$ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile);
return $ret;
}
 
/**
* helper for extracting Archive_Tar errors
* @var array
* @access private
*/
var $_extractErrors = array();
 
/**
* helper callback for extracting Archive_Tar errors
*
* @param PEAR_Error|null $err
* @return array
* @access private
*/
function _extractErrors($err = null)
{
static $errors = array();
if ($err === null) {
$e = $errors;
$errors = array();
return $e;
}
$errors[] = $err->getMessage();
}
 
/**
* Create a PEAR_PackageFile_v* from a package.xml file.
*
* @access public
* @param string $descfile name of package xml file
* @param int $state package state (one of PEAR_VALIDATE_* constants)
* @param string|false $archive name of the archive this package.xml came
* from, if any
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @uses PEAR_PackageFile::fromXmlString to create the oject after the
* XML is loaded from the package.xml file.
*/
function &fromPackageFile($descfile, $state, $archive = false)
{
if (is_string($descfile) && strlen($descfile) < 255 &&
(!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) ||
(!$fp = @fopen($descfile, 'r')))) {
$a = PEAR::raiseError("Unable to open $descfile");
return $a;
}
 
// read the whole thing so we only get one cdata callback
// for each block of cdata
fclose($fp);
$data = file_get_contents($descfile);
$ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive);
return $ret;
}
 
 
/**
* Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file.
*
* This method is able to extract information about a package from a .tgz
* archive or from a XML package definition file.
*
* @access public
* @param string $info file name
* @param int $state package state (one of PEAR_VALIDATE_* constants)
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @uses fromPackageFile() if the file appears to be XML
* @uses fromTgzFile() to load all non-XML files
*/
function &fromAnyFile($info, $state)
{
if (is_dir($info)) {
$dir_name = realpath($info);
if (file_exists($dir_name . '/package.xml')) {
$info = PEAR_PackageFile::fromPackageFile($dir_name . '/package.xml', $state);
} elseif (file_exists($dir_name . '/package2.xml')) {
$info = PEAR_PackageFile::fromPackageFile($dir_name . '/package2.xml', $state);
} else {
$info = PEAR::raiseError("No package definition found in '$info' directory");
}
return $info;
}
 
$fp = false;
if (is_string($info) && strlen($info) < 255 &&
(file_exists($info) || ($fp = @fopen($info, 'r')))) {
if ($fp) {
fclose($fp);
}
$tmp = substr($info, -4);
if ($tmp == '.xml') {
$info = &PEAR_PackageFile::fromPackageFile($info, $state);
} elseif ($tmp == '.tar' || $tmp == '.tgz') {
$info = &PEAR_PackageFile::fromTgzFile($info, $state);
} else {
$fp = fopen($info, "r");
$test = fread($fp, 5);
fclose($fp);
if ($test == "<?xml") {
$info = &PEAR_PackageFile::fromPackageFile($info, $state);
} else {
$info = &PEAR_PackageFile::fromTgzFile($info, $state);
}
}
} else {
$info = PEAR::raiseError("Cannot open '$info' for parsing");
return $info;
}
return $info;
}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer.php
New file
0,0 → 1,1672
<?php
/**
* PEAR_Installer
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Installer.php,v 1.243 2007/02/16 04:00:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* Used for installation groups in package.xml 2.0 and platform exceptions
*/
require_once 'OS/Guess.php';
require_once 'PEAR/Downloader.php';
 
define('PEAR_INSTALLER_NOBINARY', -240);
/**
* Administration class used to install PEAR packages and maintain the
* installed package database.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Installer extends PEAR_Downloader
{
// {{{ properties
 
/** name of the package directory, for example Foo-1.0
* @var string
*/
var $pkgdir;
 
/** directory where PHP code files go
* @var string
*/
var $phpdir;
 
/** directory where PHP extension files go
* @var string
*/
var $extdir;
 
/** directory where documentation goes
* @var string
*/
var $docdir;
 
/** installation root directory (ala PHP's INSTALL_ROOT or
* automake's DESTDIR
* @var string
*/
var $installroot = '';
 
/** debug level
* @var int
*/
var $debug = 1;
 
/** temporary directory
* @var string
*/
var $tmpdir;
 
/**
* PEAR_Registry object used by the installer
* @var PEAR_Registry
*/
var $registry;
 
/**
* array of PEAR_Downloader_Packages
* @var array
*/
var $_downloadedPackages;
 
/** List of file transactions queued for an install/upgrade/uninstall.
*
* Format:
* array(
* 0 => array("rename => array("from-file", "to-file")),
* 1 => array("delete" => array("file-to-delete")),
* ...
* )
*
* @var array
*/
var $file_operations = array();
 
// }}}
 
// {{{ constructor
 
/**
* PEAR_Installer constructor.
*
* @param object $ui user interface object (instance of PEAR_Frontend_*)
*
* @access public
*/
function PEAR_Installer(&$ui)
{
parent::PEAR_Common();
$this->setFrontendObject($ui);
$this->debug = $this->config->get('verbose');
}
 
function setOptions($options)
{
$this->_options = $options;
}
 
function setConfig(&$config)
{
$this->config = &$config;
$this->_registry = &$config->getRegistry();
}
 
// }}}
 
function _removeBackups($files)
{
foreach ($files as $path) {
$this->addFileOperation('removebackup', array($path));
}
}
 
// {{{ _deletePackageFiles()
 
/**
* Delete a package's installed files, does not remove empty directories.
*
* @param string package name
* @param string channel name
* @param bool if true, then files are backed up first
* @return bool TRUE on success, or a PEAR error on failure
* @access protected
*/
function _deletePackageFiles($package, $channel = false, $backup = false)
{
if (!$channel) {
$channel = 'pear.php.net';
}
if (!strlen($package)) {
return $this->raiseError("No package to uninstall given");
}
if (strtolower($package) == 'pear' && $channel == 'pear.php.net') {
// to avoid race conditions, include all possible needed files
require_once 'PEAR/Task/Common.php';
require_once 'PEAR/Task/Replace.php';
require_once 'PEAR/Task/Unixeol.php';
require_once 'PEAR/Task/Windowseol.php';
require_once 'PEAR/PackageFile/v1.php';
require_once 'PEAR/PackageFile/v2.php';
require_once 'PEAR/PackageFile/Generator/v1.php';
require_once 'PEAR/PackageFile/Generator/v2.php';
}
$filelist = $this->_registry->packageInfo($package, 'filelist', $channel);
if ($filelist == null) {
return $this->raiseError("$channel/$package not installed");
}
$ret = array();
foreach ($filelist as $file => $props) {
if (empty($props['installed_as'])) {
continue;
}
$path = $props['installed_as'];
if ($backup) {
$this->addFileOperation('backup', array($path));
$ret[] = $path;
}
$this->addFileOperation('delete', array($path));
}
if ($backup) {
return $ret;
}
return true;
}
 
// }}}
// {{{ _installFile()
 
/**
* @param string filename
* @param array attributes from <file> tag in package.xml
* @param string path to install the file in
* @param array options from command-line
* @access private
*/
function _installFile($file, $atts, $tmp_path, $options)
{
// {{{ return if this file is meant for another platform
static $os;
if (!isset($this->_registry)) {
$this->_registry = &$this->config->getRegistry();
}
if (isset($atts['platform'])) {
if (empty($os)) {
$os = new OS_Guess();
}
if (strlen($atts['platform']) && $atts['platform']{0} == '!') {
$negate = true;
$platform = substr($atts['platform'], 1);
} else {
$negate = false;
$platform = $atts['platform'];
}
if ((bool) $os->matchSignature($platform) === $negate) {
$this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")");
return PEAR_INSTALLER_SKIPPED;
}
}
// }}}
 
$channel = $this->pkginfo->getChannel();
// {{{ assemble the destination paths
switch ($atts['role']) {
case 'doc':
case 'data':
case 'test':
$dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel) .
DIRECTORY_SEPARATOR . $this->pkginfo->getPackage();
unset($atts['baseinstalldir']);
break;
case 'ext':
case 'php':
$dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel);
break;
case 'script':
$dest_dir = $this->config->get('bin_dir', null, $channel);
break;
case 'src':
case 'extsrc':
$this->source_files++;
return;
default:
return $this->raiseError("Invalid role `$atts[role]' for file $file");
}
$save_destdir = $dest_dir;
if (!empty($atts['baseinstalldir'])) {
$dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
}
if (dirname($file) != '.' && empty($atts['install-as'])) {
$dest_dir .= DIRECTORY_SEPARATOR . dirname($file);
}
if (empty($atts['install-as'])) {
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file);
} else {
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as'];
}
$orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file;
 
// Clean up the DIRECTORY_SEPARATOR mess
$ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
list($dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"),
array(DIRECTORY_SEPARATOR,
DIRECTORY_SEPARATOR,
DIRECTORY_SEPARATOR),
array($dest_file, $orig_file));
$final_dest_file = $installed_as = $dest_file;
if (isset($this->_options['packagingroot'])) {
$installedas_dest_dir = dirname($final_dest_file);
$installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
$final_dest_file = $this->_prependPath($final_dest_file,
$this->_options['packagingroot']);
} else {
$installedas_dest_dir = dirname($final_dest_file);
$installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
}
$dest_dir = dirname($final_dest_file);
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
// }}}
 
if (empty($this->_options['register-only']) &&
(!file_exists($dest_dir) || !is_dir($dest_dir))) {
if (!$this->mkDirHier($dest_dir)) {
return $this->raiseError("failed to mkdir $dest_dir",
PEAR_INSTALLER_FAILED);
}
$this->log(3, "+ mkdir $dest_dir");
}
// pretty much nothing happens if we are only registering the install
if (empty($this->_options['register-only'])) {
if (empty($atts['replacements'])) {
if (!file_exists($orig_file)) {
return $this->raiseError("file $orig_file does not exist",
PEAR_INSTALLER_FAILED);
}
if (!@copy($orig_file, $dest_file)) {
return $this->raiseError("failed to write $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
$this->log(3, "+ cp $orig_file $dest_file");
if (isset($atts['md5sum'])) {
$md5sum = md5_file($dest_file);
}
} else {
// {{{ file with replacements
if (!file_exists($orig_file)) {
return $this->raiseError("file does not exist",
PEAR_INSTALLER_FAILED);
}
$contents = file_get_contents($orig_file);
if ($contents === false) {
$contents = '';
}
if (isset($atts['md5sum'])) {
$md5sum = md5($contents);
}
$subst_from = $subst_to = array();
foreach ($atts['replacements'] as $a) {
$to = '';
if ($a['type'] == 'php-const') {
if (preg_match('/^[a-z0-9_]+$/i', $a['to'])) {
eval("\$to = $a[to];");
} else {
if (!isset($options['soft'])) {
$this->log(0, "invalid php-const replacement: $a[to]");
}
continue;
}
} elseif ($a['type'] == 'pear-config') {
if ($a['to'] == 'master_server') {
$chan = $this->_registry->getChannel($channel);
if (!PEAR::isError($chan)) {
$to = $chan->getServer();
} else {
$to = $this->config->get($a['to'], null, $channel);
}
} else {
$to = $this->config->get($a['to'], null, $channel);
}
if (is_null($to)) {
if (!isset($options['soft'])) {
$this->log(0, "invalid pear-config replacement: $a[to]");
}
continue;
}
} elseif ($a['type'] == 'package-info') {
if ($t = $this->pkginfo->packageInfo($a['to'])) {
$to = $t;
} else {
if (!isset($options['soft'])) {
$this->log(0, "invalid package-info replacement: $a[to]");
}
continue;
}
}
if (!is_null($to)) {
$subst_from[] = $a['from'];
$subst_to[] = $to;
}
}
$this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file");
if (sizeof($subst_from)) {
$contents = str_replace($subst_from, $subst_to, $contents);
}
$wp = @fopen($dest_file, "wb");
if (!is_resource($wp)) {
return $this->raiseError("failed to create $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
if (@fwrite($wp, $contents) === false) {
return $this->raiseError("failed writing to $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
fclose($wp);
// }}}
}
// {{{ check the md5
if (isset($md5sum)) {
if (strtolower($md5sum) == strtolower($atts['md5sum'])) {
$this->log(2, "md5sum ok: $final_dest_file");
} else {
if (empty($options['force'])) {
// delete the file
if (file_exists($dest_file)) {
unlink($dest_file);
}
if (!isset($options['ignore-errors'])) {
return $this->raiseError("bad md5sum for file $final_dest_file",
PEAR_INSTALLER_FAILED);
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
}
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
}
}
}
// }}}
// {{{ set file permissions
if (!OS_WINDOWS) {
if ($atts['role'] == 'script') {
$mode = 0777 & ~(int)octdec($this->config->get('umask'));
$this->log(3, "+ chmod +x $dest_file");
} else {
$mode = 0666 & ~(int)octdec($this->config->get('umask'));
}
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
$this->log(0, "failed to change mode of $dest_file: $php_errormsg");
}
}
}
// }}}
$this->addFileOperation("rename", array($dest_file, $final_dest_file,
$atts['role'] == 'ext'));
}
// Store the full path where the file was installed for easy unistall
$this->addFileOperation("installed_as", array($file, $installed_as,
$save_destdir, dirname(substr($installedas_dest_file, strlen($save_destdir)))));
 
//$this->log(2, "installed: $dest_file");
return PEAR_INSTALLER_OK;
}
 
// }}}
// {{{ _installFile2()
 
/**
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param string filename
* @param array attributes from <file> tag in package.xml
* @param string path to install the file in
* @param array options from command-line
* @access private
*/
function _installFile2(&$pkg, $file, $atts, $tmp_path, $options)
{
if (!isset($this->_registry)) {
$this->_registry = &$this->config->getRegistry();
}
 
$channel = $pkg->getChannel();
// {{{ assemble the destination paths
if (!in_array($atts['attribs']['role'],
PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) {
return $this->raiseError('Invalid role `' . $atts['attribs']['role'] .
"' for file $file");
}
$role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config);
$err = $role->setup($this, $pkg, $atts['attribs'], $file);
if (PEAR::isError($err)) {
return $err;
}
if (!$role->isInstallable()) {
return;
}
$info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path);
if (PEAR::isError($info)) {
return $info;
} else {
list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info;
}
$final_dest_file = $installed_as = $dest_file;
if (isset($this->_options['packagingroot'])) {
$final_dest_file = $this->_prependPath($final_dest_file,
$this->_options['packagingroot']);
}
$dest_dir = dirname($final_dest_file);
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
// }}}
 
if (empty($this->_options['register-only'])) {
if (!file_exists($dest_dir) || !is_dir($dest_dir)) {
if (!$this->mkDirHier($dest_dir)) {
return $this->raiseError("failed to mkdir $dest_dir",
PEAR_INSTALLER_FAILED);
}
$this->log(3, "+ mkdir $dest_dir");
}
}
$attribs = $atts['attribs'];
unset($atts['attribs']);
// pretty much nothing happens if we are only registering the install
if (empty($this->_options['register-only'])) {
if (!count($atts)) { // no tasks
if (!file_exists($orig_file)) {
return $this->raiseError("file $orig_file does not exist",
PEAR_INSTALLER_FAILED);
}
if (!@copy($orig_file, $dest_file)) {
return $this->raiseError("failed to write $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
$this->log(3, "+ cp $orig_file $dest_file");
if (isset($attribs['md5sum'])) {
$md5sum = md5_file($dest_file);
}
} else { // file with tasks
if (!file_exists($orig_file)) {
return $this->raiseError("file $orig_file does not exist",
PEAR_INSTALLER_FAILED);
}
$contents = file_get_contents($orig_file);
if ($contents === false) {
$contents = '';
}
if (isset($attribs['md5sum'])) {
$md5sum = md5($contents);
}
foreach ($atts as $tag => $raw) {
$tag = str_replace(array($pkg->getTasksNs() . ':', '-'),
array('', '_'), $tag);
$task = "PEAR_Task_$tag";
$task = &new $task($this->config, $this, PEAR_TASK_INSTALL);
if (!$task->isScript()) { // scripts are only handled after installation
$task->init($raw, $attribs, $pkg->getLastInstalledVersion());
$res = $task->startSession($pkg, $contents, $final_dest_file);
if ($res === false) {
continue; // skip this file
}
if (PEAR::isError($res)) {
return $res;
}
$contents = $res; // save changes
}
$wp = @fopen($dest_file, "wb");
if (!is_resource($wp)) {
return $this->raiseError("failed to create $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
if (fwrite($wp, $contents) === false) {
return $this->raiseError("failed writing to $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
fclose($wp);
}
}
// {{{ check the md5
if (isset($md5sum)) {
if (strtolower($md5sum) == strtolower($attribs['md5sum'])) {
$this->log(2, "md5sum ok: $final_dest_file");
} else {
if (empty($options['force'])) {
// delete the file
if (file_exists($dest_file)) {
unlink($dest_file);
}
if (!isset($options['ignore-errors'])) {
return $this->raiseError("bad md5sum for file $final_dest_file",
PEAR_INSTALLER_FAILED);
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
}
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
}
}
}
// }}}
// {{{ set file permissions
if (!OS_WINDOWS) {
if ($role->isExecutable()) {
$mode = 0777 & ~(int)octdec($this->config->get('umask'));
$this->log(3, "+ chmod +x $dest_file");
} else {
$mode = 0666 & ~(int)octdec($this->config->get('umask'));
}
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
$this->log(0, "failed to change mode of $dest_file: $php_errormsg");
}
}
}
// }}}
$this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension()));
}
// Store the full path where the file was installed for easy uninstall
$this->addFileOperation("installed_as", array($file, $installed_as,
$save_destdir, dirname(substr($dest_file, strlen($save_destdir)))));
 
//$this->log(2, "installed: $dest_file");
return PEAR_INSTALLER_OK;
}
 
// }}}
// {{{ addFileOperation()
 
/**
* Add a file operation to the current file transaction.
*
* @see startFileTransaction()
* @param string $type This can be one of:
* - rename: rename a file ($data has 3 values)
* - backup: backup an existing file ($data has 1 value)
* - removebackup: clean up backups created during install ($data has 1 value)
* - chmod: change permissions on a file ($data has 2 values)
* - delete: delete a file ($data has 1 value)
* - rmdir: delete a directory if empty ($data has 1 value)
* - installed_as: mark a file as installed ($data has 4 values).
* @param array $data For all file operations, this array must contain the
* full path to the file or directory that is being operated on. For
* the rename command, the first parameter must be the file to rename,
* the second its new name, the third whether this is a PHP extension.
*
* The installed_as operation contains 4 elements in this order:
* 1. Filename as listed in the filelist element from package.xml
* 2. Full path to the installed file
* 3. Full path from the php_dir configuration variable used in this
* installation
* 4. Relative path from the php_dir that this file is installed in
*/
function addFileOperation($type, $data)
{
if (!is_array($data)) {
return $this->raiseError('Internal Error: $data in addFileOperation'
. ' must be an array, was ' . gettype($data));
}
if ($type == 'chmod') {
$octmode = decoct($data[0]);
$this->log(3, "adding to transaction: $type $octmode $data[1]");
} else {
$this->log(3, "adding to transaction: $type " . implode(" ", $data));
}
$this->file_operations[] = array($type, $data);
}
 
// }}}
// {{{ startFileTransaction()
 
function startFileTransaction($rollback_in_case = false)
{
if (count($this->file_operations) && $rollback_in_case) {
$this->rollbackFileTransaction();
}
$this->file_operations = array();
}
 
// }}}
// {{{ commitFileTransaction()
 
function commitFileTransaction()
{
$n = count($this->file_operations);
$this->log(2, "about to commit $n file operations");
// {{{ first, check permissions and such manually
$errors = array();
foreach ($this->file_operations as $tr) {
list($type, $data) = $tr;
switch ($type) {
case 'rename':
if (!file_exists($data[0])) {
$errors[] = "cannot rename file $data[0], doesn't exist";
}
// check that dest dir. is writable
if (!is_writable(dirname($data[1]))) {
$errors[] = "permission denied ($type): $data[1]";
}
break;
case 'chmod':
// check that file is writable
if (!is_writable($data[1])) {
$errors[] = "permission denied ($type): $data[1] " . decoct($data[0]);
}
break;
case 'delete':
if (!file_exists($data[0])) {
$this->log(2, "warning: file $data[0] doesn't exist, can't be deleted");
}
// check that directory is writable
if (file_exists($data[0])) {
if (!is_writable(dirname($data[0]))) {
$errors[] = "permission denied ($type): $data[0]";
} else {
// make sure the file to be deleted can be opened for writing
$fp = false;
if (!is_dir($data[0]) &&
(!is_writable($data[0]) || !($fp = @fopen($data[0], 'a')))) {
$errors[] = "permission denied ($type): $data[0]";
} elseif ($fp) {
fclose($fp);
}
}
}
break;
}
 
}
// }}}
$m = sizeof($errors);
if ($m > 0) {
foreach ($errors as $error) {
if (!isset($this->_options['soft'])) {
$this->log(1, $error);
}
}
if (!isset($this->_options['ignore-errors'])) {
return false;
}
}
$this->_dirtree = array();
// {{{ really commit the transaction
foreach ($this->file_operations as $i => $tr) {
if (!$tr) {
// support removal of non-existing backups
continue;
}
list($type, $data) = $tr;
switch ($type) {
case 'backup':
if (!file_exists($data[0])) {
$this->file_operations[$i] = false;
break;
}
if (!@copy($data[0], $data[0] . '.bak')) {
$this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] .
'.bak ' . $php_errormsg);
return false;
}
$this->log(3, "+ backup $data[0] to $data[0].bak");
break;
case 'removebackup':
if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) {
unlink($data[0] . '.bak');
$this->log(3, "+ rm backup of $data[0] ($data[0].bak)");
}
break;
case 'rename':
if (file_exists($data[1])) {
$test = @unlink($data[1]);
} else {
$test = null;
}
if (!$test && file_exists($data[1])) {
if ($data[2]) {
$extra = ', this extension must be installed manually. Rename to "' .
basename($data[1]) . '"';
} else {
$extra = '';
}
if (!isset($this->_options['soft'])) {
$this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' .
$data[0] . $extra);
}
if (!isset($this->_options['ignore-errors'])) {
return false;
}
}
// permissions issues with rename - copy() is far superior
$perms = @fileperms($data[0]);
if (!@copy($data[0], $data[1])) {
$this->log(1, 'Could not rename ' . $data[0] . ' to ' . $data[1] .
' ' . $php_errormsg);
return false;
}
// copy over permissions, otherwise they are lost
@chmod($data[1], $perms);
@unlink($data[0]);
$this->log(3, "+ mv $data[0] $data[1]");
break;
case 'chmod':
if (!@chmod($data[1], $data[0])) {
$this->log(1, 'Could not chmod ' . $data[1] . ' to ' .
decoct($data[0]) . ' ' . $php_errormsg);
return false;
}
$octmode = decoct($data[0]);
$this->log(3, "+ chmod $octmode $data[1]");
break;
case 'delete':
if (file_exists($data[0])) {
if (!@unlink($data[0])) {
$this->log(1, 'Could not delete ' . $data[0] . ' ' .
$php_errormsg);
return false;
}
$this->log(3, "+ rm $data[0]");
}
break;
case 'rmdir':
if (file_exists($data[0])) {
do {
$testme = opendir($data[0]);
while (false !== ($entry = readdir($testme))) {
if ($entry == '.' || $entry == '..') {
continue;
}
closedir($testme);
break 2; // this directory is not empty and can't be
// deleted
}
closedir($testme);
if (!@rmdir($data[0])) {
$this->log(1, 'Could not rmdir ' . $data[0] . ' ' .
$php_errormsg);
return false;
}
$this->log(3, "+ rmdir $data[0]");
} while (false);
}
break;
case 'installed_as':
$this->pkginfo->setInstalledAs($data[0], $data[1]);
if (!isset($this->_dirtree[dirname($data[1])])) {
$this->_dirtree[dirname($data[1])] = true;
$this->pkginfo->setDirtree(dirname($data[1]));
 
while(!empty($data[3]) && $data[3] != '/' && $data[3] != '\\'
&& $data[3] != '.') {
$this->pkginfo->setDirtree($pp =
$this->_prependPath($data[3], $data[2]));
$this->_dirtree[$pp] = true;
$data[3] = dirname($data[3]);
}
}
break;
}
}
// }}}
$this->log(2, "successfully committed $n file operations");
$this->file_operations = array();
return true;
}
 
// }}}
// {{{ rollbackFileTransaction()
 
function rollbackFileTransaction()
{
$n = count($this->file_operations);
$this->log(2, "rolling back $n file operations");
foreach ($this->file_operations as $tr) {
list($type, $data) = $tr;
switch ($type) {
case 'backup':
if (file_exists($data[0] . '.bak')) {
if (file_exists($data[0] && is_writable($data[0]))) {
unlink($data[0]);
}
@copy($data[0] . '.bak', $data[0]);
$this->log(3, "+ restore $data[0] from $data[0].bak");
}
break;
case 'removebackup':
if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) {
unlink($data[0] . '.bak');
$this->log(3, "+ rm backup of $data[0] ($data[0].bak)");
}
break;
case 'rename':
@unlink($data[0]);
$this->log(3, "+ rm $data[0]");
break;
case 'mkdir':
@rmdir($data[0]);
$this->log(3, "+ rmdir $data[0]");
break;
case 'chmod':
break;
case 'delete':
break;
case 'installed_as':
$this->pkginfo->setInstalledAs($data[0], false);
break;
}
}
$this->pkginfo->resetDirtree();
$this->file_operations = array();
}
 
// }}}
// {{{ mkDirHier($dir)
 
function mkDirHier($dir)
{
$this->addFileOperation('mkdir', array($dir));
return parent::mkDirHier($dir);
}
 
// }}}
// {{{ download()
 
/**
* Download any files and their dependencies, if necessary
*
* @param array a mixed list of package names, local files, or package.xml
* @param PEAR_Config
* @param array options from the command line
* @param array this is the array that will be populated with packages to
* install. Format of each entry:
*
* <code>
* array('pkg' => 'package_name', 'file' => '/path/to/local/file',
* 'info' => array() // parsed package.xml
* );
* </code>
* @param array this will be populated with any error messages
* @param false private recursion variable
* @param false private recursion variable
* @param false private recursion variable
* @deprecated in favor of PEAR_Downloader
*/
function download($packages, $options, &$config, &$installpackages,
&$errors, $installed = false, $willinstall = false, $state = false)
{
// trickiness: initialize here
parent::PEAR_Downloader($this->ui, $options, $config);
$ret = parent::download($packages);
$errors = $this->getErrorMsgs();
$installpackages = $this->getDownloadedPackages();
trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " .
"in favor of PEAR_Downloader class", E_USER_WARNING);
return $ret;
}
 
// }}}
// {{{ _parsePackageXml()
 
function _parsePackageXml(&$descfile, &$tmpdir)
{
if (substr($descfile, -4) == '.xml') {
$tmpdir = false;
} else {
// {{{ Decompress pack in tmp dir -------------------------------------
 
// To allow relative package file names
$descfile = realpath($descfile);
 
if (PEAR::isError($tmpdir = System::mktemp('-d'))) {
return $tmpdir;
}
$this->log(3, '+ tmp dir created at ' . $tmpdir);
// }}}
}
// Parse xml file -----------------------------------------------
$pkg = new PEAR_PackageFile($this->config, $this->debug, $tmpdir);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING);
PEAR::staticPopErrorHandling();
if (PEAR::isError($p)) {
if (is_array($p->getUserInfo())) {
foreach ($p->getUserInfo() as $err) {
$loglevel = $err['level'] == 'error' ? 0 : 1;
if (!isset($this->_options['soft'])) {
$this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']);
}
}
}
return $this->raiseError('Installation failed: invalid package file');
} else {
$descfile = $p->getPackageFile();
}
return $p;
}
 
// }}}
/**
* Set the list of PEAR_Downloader_Package objects to allow more sane
* dependency validation
* @param array
*/
function setDownloadedPackages(&$pkgs)
{
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->analyzeDependencies($pkgs);
PEAR::popErrorHandling();
if (PEAR::isError($err)) {
return $err;
}
$this->_downloadedPackages = &$pkgs;
}
 
/**
* Set the list of PEAR_Downloader_Package objects to allow more sane
* dependency validation
* @param array
*/
function setUninstallPackages(&$pkgs)
{
$this->_downloadedPackages = &$pkgs;
}
 
function getInstallPackages()
{
return $this->_downloadedPackages;
}
 
// {{{ install()
 
/**
* Installs the files within the package file specified.
*
* @param string|PEAR_Downloader_Package $pkgfile path to the package file,
* or a pre-initialized packagefile object
* @param array $options
* recognized options:
* - installroot : optional prefix directory for installation
* - force : force installation
* - register-only : update registry but don't install files
* - upgrade : upgrade existing install
* - soft : fail silently
* - nodeps : ignore dependency conflicts/missing dependencies
* - alldeps : install all dependencies
* - onlyreqdeps : install only required dependencies
*
* @return array|PEAR_Error package info if successful
*/
 
function install($pkgfile, $options = array())
{
$this->_options = $options;
$this->_registry = &$this->config->getRegistry();
if (is_object($pkgfile)) {
$dlpkg = &$pkgfile;
$pkg = $pkgfile->getPackageFile();
$pkgfile = $pkg->getArchiveFile();
$descfile = $pkg->getPackageFile();
$tmpdir = dirname($descfile);
} else {
$descfile = $pkgfile;
$tmpdir = '';
if (PEAR::isError($pkg = &$this->_parsePackageXml($descfile, $tmpdir))) {
return $pkg;
}
}
 
if (realpath($descfile) != realpath($pkgfile)) {
$tar = new Archive_Tar($pkgfile);
if (!$tar->extract($tmpdir)) {
return $this->raiseError("unable to unpack $pkgfile");
}
}
 
$pkgname = $pkg->getName();
$channel = $pkg->getChannel();
if (isset($this->_options['packagingroot'])) {
$regdir = $this->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$this->_options['packagingroot']);
$packrootphp_dir = $this->_prependPath(
$this->config->get('php_dir', null, $channel),
$this->_options['packagingroot']);
}
 
if (isset($options['installroot'])) {
$this->config->setInstallRoot($options['installroot']);
$this->_registry = &$this->config->getRegistry();
$installregistry = &$this->_registry;
$this->installroot = ''; // all done automagically now
$php_dir = $this->config->get('php_dir', null, $channel);
} else {
$this->config->setInstallRoot(false);
$this->_registry = &$this->config->getRegistry();
if (isset($this->_options['packagingroot'])) {
$installregistry = &new PEAR_Registry($regdir);
if (!$installregistry->channelExists($channel, true)) {
// we need to fake a channel-discover of this channel
$chanobj = $this->_registry->getChannel($channel, true);
$installregistry->addChannel($chanobj);
}
$php_dir = $packrootphp_dir;
} else {
$installregistry = &$this->_registry;
$php_dir = $this->config->get('php_dir', null, $channel);
}
$this->installroot = '';
}
 
// {{{ checks to do when not in "force" mode
if (empty($options['force']) &&
(file_exists($this->config->get('php_dir')) &&
is_dir($this->config->get('php_dir')))) {
$testp = $channel == 'pear.php.net' ? $pkgname : array($channel, $pkgname);
$instfilelist = $pkg->getInstallationFileList(true);
if (PEAR::isError($instfilelist)) {
return $instfilelist;
}
// ensure we have the most accurate registry
$installregistry->flushFileMap();
$test = $installregistry->checkFileMap($instfilelist, $testp, '1.1');
if (PEAR::isError($test)) {
return $test;
}
if (sizeof($test)) {
$pkgs = $this->getInstallPackages();
$found = false;
foreach ($pkgs as $param) {
if ($pkg->isSubpackageOf($param)) {
$found = true;
break;
}
}
if ($found) {
// subpackages can conflict with earlier versions of parent packages
$parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel());
$tmp = $test;
foreach ($tmp as $file => $info) {
if (is_array($info)) {
if (strtolower($info[1]) == strtolower($param->getPackage()) &&
strtolower($info[0]) == strtolower($param->getChannel())) {
unset($test[$file]);
unset($parentreg['filelist'][$file]);
}
} else {
if (strtolower($param->getChannel()) != 'pear.php.net') {
continue;
}
if (strtolower($info) == strtolower($param->getPackage())) {
unset($test[$file]);
unset($parentreg['filelist'][$file]);
}
}
}
$pfk = &new PEAR_PackageFile($this->config);
$parentpkg = &$pfk->fromArray($parentreg);
$installregistry->updatePackage2($parentpkg);
}
if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) {
$tmp = $test;
foreach ($tmp as $file => $info) {
if (is_string($info)) {
// pear.php.net packages are always stored as strings
if (strtolower($info) == strtolower($param->getPackage())) {
// upgrading existing package
unset($test[$file]);
}
}
}
}
if (sizeof($test)) {
$msg = "$channel/$pkgname: conflicting files found:\n";
$longest = max(array_map("strlen", array_keys($test)));
$fmt = "%${longest}s (%s)\n";
foreach ($test as $file => $info) {
if (!is_array($info)) {
$info = array('pear.php.net', $info);
}
$info = $info[0] . '/' . $info[1];
$msg .= sprintf($fmt, $file, $info);
}
if (!isset($options['ignore-errors'])) {
return $this->raiseError($msg);
} else {
if (!isset($options['soft'])) {
$this->log(0, "WARNING: $msg");
}
}
}
}
}
// }}}
 
$this->startFileTransaction();
 
if (empty($options['upgrade']) && empty($options['soft'])) {
// checks to do only when installing new packages
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
if (!$test) {
$test = $installregistry->packageExists($pkgname, 'pear.php.net');
}
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
if (empty($options['force']) && $test) {
return $this->raiseError("$channel/$pkgname is already installed");
}
} else {
$usechannel = $channel;
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
if (!$test) {
$test = $installregistry->packageExists($pkgname, 'pear.php.net');
$usechannel = 'pear.php.net';
}
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
if ($test) {
$v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel);
$v2 = $pkg->getVersion();
$cmp = version_compare("$v1", "$v2", 'gt');
if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) {
return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)");
}
if (empty($options['register-only'])) {
// when upgrading, remove old release's files first:
if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel,
true))) {
if (!isset($options['ignore-errors'])) {
return $this->raiseError($err);
} else {
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $err->getMessage());
}
}
} else {
$backedup = $err;
}
}
}
}
 
// {{{ Copy files to dest dir ---------------------------------------
 
// info from the package it self we want to access from _installFile
$this->pkginfo = &$pkg;
// used to determine whether we should build any C code
$this->source_files = 0;
 
$savechannel = $this->config->get('default_channel');
if (empty($options['register-only']) && !is_dir($php_dir)) {
if (PEAR::isError(System::mkdir(array('-p'), $php_dir))) {
return $this->raiseError("no installation destination directory '$php_dir'\n");
}
}
 
$tmp_path = dirname($descfile);
if (substr($pkgfile, -4) != '.xml') {
$tmp_path .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion();
}
 
$this->configSet('default_channel', $channel);
// {{{ install files
 
$ver = $pkg->getPackagexmlVersion();
if (version_compare($ver, '2.0', '>=')) {
$filelist = $pkg->getInstallationFilelist();
} else {
$filelist = $pkg->getFileList();
}
if (PEAR::isError($filelist)) {
return $filelist;
}
$pkg->resetFilelist();
$pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(),
'version', $pkg->getChannel()));
foreach ($filelist as $file => $atts) {
if ($pkg->getPackagexmlVersion() == '1.0') {
$this->expectError(PEAR_INSTALLER_FAILED);
$res = $this->_installFile($file, $atts, $tmp_path, $options);
$this->popExpect();
} else {
$this->expectError(PEAR_INSTALLER_FAILED);
$res = $this->_installFile2($pkg, $file, $atts, $tmp_path, $options);
$this->popExpect();
}
if (PEAR::isError($res)) {
if (empty($options['ignore-errors'])) {
$this->rollbackFileTransaction();
if ($res->getMessage() == "file does not exist") {
$this->raiseError("file $file in package.xml does not exist");
}
return $this->raiseError($res);
} else {
if (!isset($options['soft'])) {
$this->log(0, "Warning: " . $res->getMessage());
}
}
}
if ($res == PEAR_INSTALLER_OK) {
// Register files that were installed
$pkg->installedFile($file, $atts);
}
}
// }}}
 
// {{{ compile and install source files
if ($this->source_files > 0 && empty($options['nobuild'])) {
if (PEAR::isError($err =
$this->_compileSourceFiles($savechannel, $pkg))) {
return $err;
}
}
// }}}
 
if (isset($backedup)) {
$this->_removeBackups($backedup);
}
if (!$this->commitFileTransaction()) {
$this->rollbackFileTransaction();
$this->configSet('default_channel', $savechannel);
return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED);
}
// }}}
 
$ret = false;
$installphase = 'install';
$oldversion = false;
// {{{ Register that the package is installed -----------------------
if (empty($options['upgrade'])) {
// if 'force' is used, replace the info in registry
$usechannel = $channel;
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
if (!$test) {
$test = $installregistry->packageExists($pkgname, 'pear.php.net');
$usechannel = 'pear.php.net';
}
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
if (!empty($options['force']) && $test) {
$oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel);
$installregistry->deletePackage($pkgname, $usechannel);
}
$ret = $installregistry->addPackage2($pkg);
} else {
$usechannel = $channel;
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
if (!$test) {
$test = $installregistry->packageExists($pkgname, 'pear.php.net');
$usechannel = 'pear.php.net';
}
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
// new: upgrade installs a package if it isn't installed
if (!$test) {
$ret = $installregistry->addPackage2($pkg);
} else {
if ($usechannel != $channel) {
$installregistry->deletePackage($pkgname, $usechannel);
$ret = $installregistry->addPackage2($pkg);
} else {
$ret = $installregistry->updatePackage2($pkg);
}
$installphase = 'upgrade';
}
}
if (!$ret) {
$this->configSet('default_channel', $savechannel);
return $this->raiseError("Adding package $channel/$pkgname to registry failed");
}
// }}}
$this->configSet('default_channel', $savechannel);
if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist
if (PEAR_Task_Common::hasPostinstallTasks()) {
PEAR_Task_Common::runPostinstallTasks($installphase);
}
}
return $pkg->toArray(true);
}
 
// }}}
 
// {{{ _compileSourceFiles()
/**
* @param string
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
*/
function _compileSourceFiles($savechannel, &$filelist)
{
require_once 'PEAR/Builder.php';
$this->log(1, "$this->source_files source files, building");
$bob = &new PEAR_Builder($this->ui);
$bob->debug = $this->debug;
$built = $bob->build($filelist, array(&$this, '_buildCallback'));
if (PEAR::isError($built)) {
$this->rollbackFileTransaction();
$this->configSet('default_channel', $savechannel);
return $built;
}
$this->log(1, "\nBuild process completed successfully");
foreach ($built as $ext) {
$bn = basename($ext['file']);
list($_ext_name, $_ext_suff) = explode('.', $bn);
if ($_ext_suff == '.so' || $_ext_suff == '.dll') {
if (extension_loaded($_ext_name)) {
$this->raiseError("Extension '$_ext_name' already loaded. " .
'Please unload it in your php.ini file ' .
'prior to install or upgrade');
}
$role = 'ext';
} else {
$role = 'src';
}
$dest = $ext['dest'];
$packagingroot = '';
if (isset($this->_options['packagingroot'])) {
$packagingroot = $this->_options['packagingroot'];
}
$copyto = $this->_prependPath($dest, $packagingroot);
if ($copyto != $dest) {
$this->log(1, "Installing '$dest' as '$copyto'");
} else {
$this->log(1, "Installing '$dest'");
}
$copydir = dirname($copyto);
// pretty much nothing happens if we are only registering the install
if (empty($this->_options['register-only'])) {
if (!file_exists($copydir) || !is_dir($copydir)) {
if (!$this->mkDirHier($copydir)) {
return $this->raiseError("failed to mkdir $copydir",
PEAR_INSTALLER_FAILED);
}
$this->log(3, "+ mkdir $copydir");
}
if (!@copy($ext['file'], $copyto)) {
return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED);
}
$this->log(3, "+ cp $ext[file] $copyto");
$this->addFileOperation('rename', array($ext['file'], $copyto));
if (!OS_WINDOWS) {
$mode = 0666 & ~(int)octdec($this->config->get('umask'));
$this->addFileOperation('chmod', array($mode, $copyto));
if (!@chmod($copyto, $mode)) {
$this->log(0, "failed to change mode of $copyto ($php_errormsg)");
}
}
}
 
if ($filelist->getPackageXmlVersion() == '1.0') {
$filelist->installedFile($bn, array(
'role' => $role,
'name' => $bn,
'installed_as' => $dest,
'php_api' => $ext['php_api'],
'zend_mod_api' => $ext['zend_mod_api'],
'zend_ext_api' => $ext['zend_ext_api'],
));
} else {
$filelist->installedFile($bn, array('attribs' => array(
'role' => $role,
'name' => $bn,
'installed_as' => $dest,
'php_api' => $ext['php_api'],
'zend_mod_api' => $ext['zend_mod_api'],
'zend_ext_api' => $ext['zend_ext_api'],
)));
}
}
}
 
// }}}
function &getUninstallPackages()
{
return $this->_downloadedPackages;
}
// {{{ uninstall()
 
/**
* Uninstall a package
*
* This method removes all files installed by the application, and then
* removes any empty directories.
* @param string package name
* @param array Command-line options. Possibilities include:
*
* - installroot: base installation dir, if not the default
* - register-only : update registry but don't remove files
* - nodeps: do not process dependencies of other packages to ensure
* uninstallation does not break things
*/
function uninstall($package, $options = array())
{
if (isset($options['installroot'])) {
$this->config->setInstallRoot($options['installroot']);
$this->installroot = '';
} else {
$this->config->setInstallRoot('');
$this->installroot = '';
}
$this->_registry = &$this->config->getRegistry();
if (is_object($package)) {
$channel = $package->getChannel();
$pkg = $package;
$package = $pkg->getPackage();
} else {
$pkg = false;
$info = $this->_registry->parsePackageName($package,
$this->config->get('default_channel'));
$channel = $info['channel'];
$package = $info['package'];
}
$savechannel = $this->config->get('default_channel');
$this->configSet('default_channel', $channel);
if (!is_object($pkg)) {
$pkg = $this->_registry->getPackage($package, $channel);
}
if (!$pkg) {
$this->configSet('default_channel', $savechannel);
return $this->raiseError($this->_registry->parsedPackageNameToString(
array(
'channel' => $channel,
'package' => $package
), true) . ' not installed');
}
if ($pkg->getInstalledBinary()) {
// this is just an alias for a binary package
return $this->_registry->deletePackage($package, $channel);
}
$filelist = $pkg->getFilelist();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
$depchecker = &new PEAR_Dependency2($this->config, $options,
array('channel' => $channel, 'package' => $package),
PEAR_VALIDATE_UNINSTALLING);
$e = $depchecker->validatePackageUninstall($this);
PEAR::staticPopErrorHandling();
if (PEAR::isError($e)) {
if (!isset($options['ignore-errors'])) {
return $this->raiseError($e);
} else {
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $e->getMessage());
}
}
} elseif (is_array($e)) {
if (!isset($options['soft'])) {
$this->log(0, $e[0]);
}
}
$this->pkginfo = &$pkg;
// pretty much nothing happens if we are only registering the uninstall
if (empty($options['register-only'])) {
// {{{ Delete the files
$this->startFileTransaction();
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
if (PEAR::isError($err = $this->_deletePackageFiles($package, $channel))) {
PEAR::popErrorHandling();
$this->rollbackFileTransaction();
$this->configSet('default_channel', $savechannel);
if (!isset($options['ignore-errors'])) {
return $this->raiseError($err);
} else {
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $err->getMessage());
}
}
} else {
PEAR::popErrorHandling();
}
if (!$this->commitFileTransaction()) {
$this->rollbackFileTransaction();
if (!isset($options['ignore-errors'])) {
return $this->raiseError("uninstall failed");
} elseif (!isset($options['soft'])) {
$this->log(0, 'WARNING: uninstall failed');
}
} else {
$this->startFileTransaction();
if ($dirtree = $pkg->getDirTree()) {
// attempt to delete empty directories
uksort($dirtree, array($this, '_sortDirs'));
foreach($dirtree as $dir => $notused) {
$this->addFileOperation('rmdir', array($dir));
}
} else {
$this->configSet('default_channel', $savechannel);
return $this->_registry->deletePackage($package, $channel);
}
if (!$this->commitFileTransaction()) {
$this->rollbackFileTransaction();
if (!isset($options['ignore-errors'])) {
return $this->raiseError("uninstall failed");
} elseif (!isset($options['soft'])) {
$this->log(0, 'WARNING: uninstall failed');
}
}
}
// }}}
}
 
$this->configSet('default_channel', $savechannel);
// Register that the package is no longer installed
return $this->_registry->deletePackage($package, $channel);
}
 
/**
* Sort a list of arrays of array(downloaded packagefilename) by dependency.
*
* It also removes duplicate dependencies
* @param array an array of PEAR_PackageFile_v[1/2] objects
* @return array|PEAR_Error array of array(packagefilename, package.xml contents)
*/
function sortPackagesForUninstall(&$packages)
{
$this->_dependencyDB = &PEAR_DependencyDB::singleton($this->config);
if (PEAR::isError($this->_dependencyDB)) {
return $this->_dependencyDB;
}
usort($packages, array(&$this, '_sortUninstall'));
}
 
function _sortUninstall($a, $b)
{
if (!$a->getDeps() && !$b->getDeps()) {
return 0; // neither package has dependencies, order is insignificant
}
if ($a->getDeps() && !$b->getDeps()) {
return -1; // $a must be installed after $b because $a has dependencies
}
if (!$a->getDeps() && $b->getDeps()) {
return 1; // $b must be installed after $a because $b has dependencies
}
// both packages have dependencies
if ($this->_dependencyDB->dependsOn($a, $b)) {
return -1;
}
if ($this->_dependencyDB->dependsOn($b, $a)) {
return 1;
}
return 0;
}
 
// }}}
// {{{ _sortDirs()
function _sortDirs($a, $b)
{
if (strnatcmp($a, $b) == -1) return 1;
if (strnatcmp($a, $b) == 1) return -1;
return 0;
}
 
// }}}
 
// {{{ _buildCallback()
 
function _buildCallback($what, $data)
{
if (($what == 'cmdoutput' && $this->debug > 1) ||
($what == 'output' && $this->debug > 0)) {
$this->ui->outputData(rtrim($data), 'build');
}
}
 
// }}}
}
 
// {{{ md5_file() utility function
if (!function_exists("md5_file")) {
function md5_file($filename) {
if (!$fd = @fopen($file, 'r')) {
return false;
}
fclose($fd);
return md5(file_get_contents($filename));
}
}
// }}}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Downloader.php
New file
0,0 → 1,1702
<?php
/**
* PEAR_Downloader, the PEAR Installer's download utility class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Martin Jansen <mj@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Downloader.php,v 1.123 2007/02/20 00:16:12 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.3.0
*/
 
/**
* Needed for constants, extending
*/
require_once 'PEAR/Common.php';
 
define('PEAR_INSTALLER_OK', 1);
define('PEAR_INSTALLER_FAILED', 0);
define('PEAR_INSTALLER_SKIPPED', -1);
define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2);
 
/**
* Administration class used to download anything from the internet (PEAR Packages,
* static URLs, xml files)
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Martin Jansen <mj@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.3.0
*/
class PEAR_Downloader extends PEAR_Common
{
/**
* @var PEAR_Registry
* @access private
*/
var $_registry;
 
/**
* @var PEAR_Remote
* @access private
*/
var $_remote;
 
/**
* Preferred Installation State (snapshot, devel, alpha, beta, stable)
* @var string|null
* @access private
*/
var $_preferredState;
 
/**
* Options from command-line passed to Install.
*
* Recognized options:<br />
* - onlyreqdeps : install all required dependencies as well
* - alldeps : install all dependencies, including optional
* - installroot : base relative path to install files in
* - force : force a download even if warnings would prevent it
* - nocompress : download uncompressed tarballs
* @see PEAR_Command_Install
* @access private
* @var array
*/
var $_options;
 
/**
* Downloaded Packages after a call to download().
*
* Format of each entry:
*
* <code>
* array('pkg' => 'package_name', 'file' => '/path/to/local/file',
* 'info' => array() // parsed package.xml
* );
* </code>
* @access private
* @var array
*/
var $_downloadedPackages = array();
 
/**
* Packages slated for download.
*
* This is used to prevent downloading a package more than once should it be a dependency
* for two packages to be installed.
* Format of each entry:
*
* <pre>
* array('package_name1' => parsed package.xml, 'package_name2' => parsed package.xml,
* );
* </pre>
* @access private
* @var array
*/
var $_toDownload = array();
 
/**
* Array of every package installed, with names lower-cased.
*
* Format:
* <code>
* array('package1' => 0, 'package2' => 1, );
* </code>
* @var array
*/
var $_installed = array();
 
/**
* @var array
* @access private
*/
var $_errorStack = array();
/**
* @var boolean
* @access private
*/
var $_internalDownload = false;
 
/**
* Temporary variable used in sorting packages by dependency in {@link sortPkgDeps()}
* @var array
* @access private
*/
var $_packageSortTree;
 
/**
* Temporary directory, or configuration value where downloads will occur
* @var string
*/
var $_downloadDir;
// {{{ PEAR_Downloader()
 
/**
* @param PEAR_Frontend_*
* @param array
* @param PEAR_Config
*/
function PEAR_Downloader(&$ui, $options, &$config)
{
parent::PEAR_Common();
$this->_options = $options;
$this->config = &$config;
$this->_preferredState = $this->config->get('preferred_state');
$this->ui = &$ui;
if (!$this->_preferredState) {
// don't inadvertantly use a non-set preferred_state
$this->_preferredState = null;
}
 
if (isset($this->_options['installroot'])) {
$this->config->setInstallRoot($this->_options['installroot']);
}
$this->_registry = &$config->getRegistry();
$this->_remote = &$config->getRemote();
 
if (isset($this->_options['alldeps']) || isset($this->_options['onlyreqdeps'])) {
$this->_installed = $this->_registry->listAllPackages();
foreach ($this->_installed as $key => $unused) {
if (!count($unused)) {
continue;
}
$strtolower = create_function('$a','return strtolower($a);');
array_walk($this->_installed[$key], $strtolower);
}
}
}
 
/**
* Attempt to discover a channel's remote capabilities from
* its server name
* @param string
* @return boolean
*/
function discover($channel)
{
$this->log(1, 'Attempting to discover channel "' . $channel . '"...');
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$callback = $this->ui ? array(&$this, '_downloadCallback') : null;
if (!class_exists('System')) {
require_once 'System.php';
}
$a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui,
System::mktemp(array('-d')), $callback, false);
PEAR::popErrorHandling();
if (PEAR::isError($a)) {
return false;
}
list($a, $lastmodified) = $a;
if (!class_exists('PEAR/ChannelFile.php')) {
require_once 'PEAR/ChannelFile.php';
}
$b = new PEAR_ChannelFile;
if ($b->fromXmlFile($a)) {
unlink($a);
if ($this->config->get('auto_discover')) {
$this->_registry->addChannel($b, $lastmodified);
$alias = $b->getName();
if ($b->getName() == $this->_registry->channelName($b->getAlias())) {
$alias = $b->getAlias();
}
$this->log(1, 'Auto-discovered channel "' . $channel .
'", alias "' . $alias . '", adding to registry');
}
return true;
}
unlink($a);
return false;
}
 
/**
* For simpler unit-testing
* @param PEAR_Downloader
* @return PEAR_Downloader_Package
*/
function &newDownloaderPackage(&$t)
{
if (!class_exists('PEAR_Downloader_Package')) {
require_once 'PEAR/Downloader/Package.php';
}
$a = &new PEAR_Downloader_Package($t);
return $a;
}
 
/**
* For simpler unit-testing
* @param PEAR_Config
* @param array
* @param array
* @param int
*/
function &getDependency2Object(&$c, $i, $p, $s)
{
if (!class_exists('PEAR/Dependency2.php')) {
require_once 'PEAR/Dependency2.php';
}
$z = &new PEAR_Dependency2($c, $i, $p, $s);
return $z;
}
 
function &download($params)
{
if (!count($params)) {
$a = array();
return $a;
}
if (!isset($this->_registry)) {
$this->_registry = &$this->config->getRegistry();
}
if (!isset($this->_remote)) {
$this->_remote = &$this->config->getRemote();
}
$channelschecked = array();
// convert all parameters into PEAR_Downloader_Package objects
foreach ($params as $i => $param) {
$params[$i] = &$this->newDownloaderPackage($this);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $params[$i]->initialize($param);
PEAR::staticPopErrorHandling();
if (!$err) {
// skip parameters that were missed by preferred_state
continue;
}
if (PEAR::isError($err)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $err->getMessage());
}
$params[$i] = false;
if (is_object($param)) {
$param = $param->getChannel() . '/' . $param->getPackage();
}
$this->pushError('Package "' . $param . '" is not valid',
PEAR_INSTALLER_SKIPPED);
} else {
do {
if ($params[$i] && $params[$i]->getType() == 'local') {
// bug #7090
// skip channel.xml check for local packages
break;
}
if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) &&
!isset($this->_options['offline'])) {
$channelschecked[$params[$i]->getChannel()] = true;
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (!class_exists('System')) {
require_once 'System.php';
}
$curchannel = &$this->_registry->getChannel($params[$i]->getChannel());
if (PEAR::isError($curchannel)) {
PEAR::staticPopErrorHandling();
return $this->raiseError($curchannel);
}
if (PEAR::isError($dir = $this->getDownloadDir())) {
PEAR::staticPopErrorHandling();
break;
}
$a = $this->downloadHttp('http://' . $params[$i]->getChannel() .
'/channel.xml', $this->ui, $dir, null, $curchannel->lastModified());
 
PEAR::staticPopErrorHandling();
if (PEAR::isError($a) || !$a) {
break;
}
$this->log(0, 'WARNING: channel "' . $params[$i]->getChannel() . '" has ' .
'updated its protocols, use "channel-update ' . $params[$i]->getChannel() .
'" to update');
}
} while (false);
if ($params[$i] && !isset($this->_options['downloadonly'])) {
if (isset($this->_options['packagingroot'])) {
$checkdir = $this->_prependPath(
$this->config->get('php_dir', null, $params[$i]->getChannel()),
$this->_options['packagingroot']);
} else {
$checkdir = $this->config->get('php_dir',
null, $params[$i]->getChannel());
}
while ($checkdir && $checkdir != '/' && !file_exists($checkdir)) {
$checkdir = dirname($checkdir);
}
if ($checkdir == '.') {
$checkdir = '/';
}
if (!is_writeable($checkdir)) {
return PEAR::raiseError('Cannot install, php_dir for channel "' .
$params[$i]->getChannel() . '" is not writeable by the current user');
}
}
}
}
unset($channelschecked);
PEAR_Downloader_Package::removeDuplicates($params);
if (!count($params)) {
$a = array();
return $a;
}
if (!isset($this->_options['nodeps']) && !isset($this->_options['offline'])) {
$reverify = true;
while ($reverify) {
$reverify = false;
foreach ($params as $i => $param) {
$ret = $params[$i]->detectDependencies($params);
if (PEAR::isError($ret)) {
$reverify = true;
$params[$i] = false;
PEAR_Downloader_Package::removeDuplicates($params);
if (!isset($this->_options['soft'])) {
$this->log(0, $ret->getMessage());
}
continue 2;
}
}
}
}
if (isset($this->_options['offline'])) {
$this->log(3, 'Skipping dependency download check, --offline specified');
}
if (!count($params)) {
$a = array();
return $a;
}
while (PEAR_Downloader_Package::mergeDependencies($params));
PEAR_Downloader_Package::removeDuplicates($params, true);
PEAR_Downloader_Package::removeInstalled($params);
if (!count($params)) {
$this->pushError('No valid packages found', PEAR_INSTALLER_FAILED);
$a = array();
return $a;
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->analyzeDependencies($params);
PEAR::popErrorHandling();
if (!count($params)) {
$this->pushError('No valid packages found', PEAR_INSTALLER_FAILED);
$a = array();
return $a;
}
$ret = array();
$newparams = array();
if (isset($this->_options['pretend'])) {
return $params;
}
foreach ($params as $i => $package) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pf = &$params[$i]->download();
PEAR::staticPopErrorHandling();
if (PEAR::isError($pf)) {
if (!isset($this->_options['soft'])) {
$this->log(1, $pf->getMessage());
$this->log(0, 'Error: cannot download "' .
$this->_registry->parsedPackageNameToString($package->getParsedPackage(),
true) .
'"');
}
continue;
}
$newparams[] = &$params[$i];
$ret[] = array('file' => $pf->getArchiveFile(),
'info' => &$pf,
'pkg' => $pf->getPackage());
}
$this->_downloadedPackages = $ret;
return $newparams;
}
 
/**
* @param array all packages to be installed
*/
function analyzeDependencies(&$params)
{
$hasfailed = $failed = false;
if (isset($this->_options['downloadonly'])) {
return;
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$redo = true;
$reset = false;
while ($redo) {
$redo = false;
foreach ($params as $i => $param) {
$deps = $param->getDeps();
if (!$deps) {
$depchecker = &$this->getDependency2Object($this->config, $this->getOptions(),
$param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING);
if ($param->getType() == 'xmlrpc') {
$send = $param->getDownloadURL();
} else {
$send = $param->getPackageFile();
}
$installcheck = $depchecker->validatePackage($send, $this, $params);
if (PEAR::isError($installcheck)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $installcheck->getMessage());
}
$hasfailed = true;
$params[$i] = false;
$reset = true;
$redo = true;
$failed = false;
PEAR_Downloader_Package::removeDuplicates($params);
continue 2;
}
continue;
}
if (!$reset && $param->alreadyValidated()) {
continue;
}
if (count($deps)) {
$depchecker = &$this->getDependency2Object($this->config, $this->getOptions(),
$param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING);
if ($param->getType() == 'xmlrpc') {
$send = $param->getDownloadURL();
} else {
$send = $param->getPackageFile();
}
$installcheck = $depchecker->validatePackage($send, $this, $params);
if (PEAR::isError($installcheck)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $installcheck->getMessage());
}
$hasfailed = true;
$params[$i] = false;
$reset = true;
$redo = true;
$failed = false;
PEAR_Downloader_Package::removeDuplicates($params);
continue 2;
}
$failed = false;
if (isset($deps['required'])) {
foreach ($deps['required'] as $type => $dep) {
// note: Dependency2 will never return a PEAR_Error if ignore-errors
// is specified, so soft is needed to turn off logging
if (!isset($dep[0])) {
if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep,
true, $params))) {
$failed = true;
if (!isset($this->_options['soft'])) {
$this->log(0, $e->getMessage());
}
} elseif (is_array($e) && !$param->alreadyValidated()) {
if (!isset($this->_options['soft'])) {
$this->log(0, $e[0]);
}
}
} else {
foreach ($dep as $d) {
if (PEAR::isError($e =
$depchecker->{"validate{$type}Dependency"}($d,
true, $params))) {
$failed = true;
if (!isset($this->_options['soft'])) {
$this->log(0, $e->getMessage());
}
} elseif (is_array($e) && !$param->alreadyValidated()) {
if (!isset($this->_options['soft'])) {
$this->log(0, $e[0]);
}
}
}
}
}
if (isset($deps['optional'])) {
foreach ($deps['optional'] as $type => $dep) {
if (!isset($dep[0])) {
if (PEAR::isError($e =
$depchecker->{"validate{$type}Dependency"}($dep,
false, $params))) {
$failed = true;
if (!isset($this->_options['soft'])) {
$this->log(0, $e->getMessage());
}
} elseif (is_array($e) && !$param->alreadyValidated()) {
if (!isset($this->_options['soft'])) {
$this->log(0, $e[0]);
}
}
} else {
foreach ($dep as $d) {
if (PEAR::isError($e =
$depchecker->{"validate{$type}Dependency"}($d,
false, $params))) {
$failed = true;
if (!isset($this->_options['soft'])) {
$this->log(0, $e->getMessage());
}
} elseif (is_array($e) && !$param->alreadyValidated()) {
if (!isset($this->_options['soft'])) {
$this->log(0, $e[0]);
}
}
}
}
}
}
$groupname = $param->getGroup();
if (isset($deps['group']) && $groupname) {
if (!isset($deps['group'][0])) {
$deps['group'] = array($deps['group']);
}
$found = false;
foreach ($deps['group'] as $group) {
if ($group['attribs']['name'] == $groupname) {
$found = true;
break;
}
}
if ($found) {
unset($group['attribs']);
foreach ($group as $type => $dep) {
if (!isset($dep[0])) {
if (PEAR::isError($e =
$depchecker->{"validate{$type}Dependency"}($dep,
false, $params))) {
$failed = true;
if (!isset($this->_options['soft'])) {
$this->log(0, $e->getMessage());
}
} elseif (is_array($e) && !$param->alreadyValidated()) {
if (!isset($this->_options['soft'])) {
$this->log(0, $e[0]);
}
}
} else {
foreach ($dep as $d) {
if (PEAR::isError($e =
$depchecker->{"validate{$type}Dependency"}($d,
false, $params))) {
$failed = true;
if (!isset($this->_options['soft'])) {
$this->log(0, $e->getMessage());
}
} elseif (is_array($e) && !$param->alreadyValidated()) {
if (!isset($this->_options['soft'])) {
$this->log(0, $e[0]);
}
}
}
}
}
}
}
} else {
foreach ($deps as $dep) {
if (PEAR::isError($e = $depchecker->validateDependency1($dep, $params))) {
$failed = true;
if (!isset($this->_options['soft'])) {
$this->log(0, $e->getMessage());
}
} elseif (is_array($e) && !$param->alreadyValidated()) {
if (!isset($this->_options['soft'])) {
$this->log(0, $e[0]);
}
}
}
}
$params[$i]->setValidated();
}
if ($failed) {
$hasfailed = true;
$params[$i] = false;
$reset = true;
$redo = true;
$failed = false;
PEAR_Downloader_Package::removeDuplicates($params);
continue 2;
}
}
}
PEAR::staticPopErrorHandling();
if ($hasfailed && (isset($this->_options['ignore-errors']) ||
isset($this->_options['nodeps']))) {
// this is probably not needed, but just in case
if (!isset($this->_options['soft'])) {
$this->log(0, 'WARNING: dependencies failed');
}
}
}
 
/**
* Retrieve the directory that downloads will happen in
* @access private
* @return string
*/
function getDownloadDir()
{
if (isset($this->_downloadDir)) {
return $this->_downloadDir;
}
$downloaddir = $this->config->get('download_dir');
if (empty($downloaddir)) {
if (!class_exists('System')) {
require_once 'System.php';
}
if (PEAR::isError($downloaddir = System::mktemp('-d'))) {
return $downloaddir;
}
$this->log(3, '+ tmp dir created at ' . $downloaddir);
}
if (!is_writable($downloaddir)) {
if (PEAR::isError(System::mkdir(array('-p', $downloaddir)))) {
return PEAR::raiseError('download directory "' . $downloaddir .
'" is not writeable. Change download_dir config variable to ' .
'a writeable dir');
}
}
return $this->_downloadDir = $downloaddir;
}
 
function setDownloadDir($dir)
{
$this->_downloadDir = $dir;
}
 
// }}}
// {{{ configSet()
function configSet($key, $value, $layer = 'user', $channel = false)
{
$this->config->set($key, $value, $layer, $channel);
$this->_preferredState = $this->config->get('preferred_state', null, $channel);
if (!$this->_preferredState) {
// don't inadvertantly use a non-set preferred_state
$this->_preferredState = null;
}
}
 
// }}}
// {{{ setOptions()
function setOptions($options)
{
$this->_options = $options;
}
 
// }}}
// {{{ setOptions()
function getOptions()
{
return $this->_options;
}
 
// }}}
 
/**
* For simpler unit-testing
* @param PEAR_Config
* @param int
* @param string
*/
function &getPackagefileObject(&$c, $d, $t = false)
{
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
$a = &new PEAR_PackageFile($c, $d, $t);
return $a;
}
 
// {{{ _getPackageDownloadUrl()
 
/**
* @param array output of {@link parsePackageName()}
* @access private
*/
function _getPackageDownloadUrl($parr)
{
$curchannel = $this->config->get('default_channel');
$this->configSet('default_channel', $parr['channel']);
// getDownloadURL returns an array. On error, it only contains information
// on the latest release as array(version, info). On success it contains
// array(version, info, download url string)
$state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state');
if (!$this->_registry->channelExists($parr['channel'])) {
do {
if ($this->config->get('auto_discover')) {
if ($this->discover($parr['channel'])) {
break;
}
}
$this->configSet('default_channel', $curchannel);
return PEAR::raiseError('Unknown remote channel: ' . $remotechannel);
} while (false);
}
$chan = &$this->_registry->getChannel($parr['channel']);
if (PEAR::isError($chan)) {
return $chan;
}
$version = $this->_registry->packageInfo($parr['package'], 'version',
$parr['channel']);
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', $this->_options);
if (!isset($parr['version']) && !isset($parr['state']) && $version
&& !isset($this->_options['downloadonly'])) {
$url = $rest->getDownloadURL($base, $parr, $state, $version);
} else {
$url = $rest->getDownloadURL($base, $parr, $state, false);
}
if (PEAR::isError($url)) {
$this->configSet('default_channel', $curchannel);
return $url;
}
if ($parr['channel'] != $curchannel) {
$this->configSet('default_channel', $curchannel);
}
if (!is_array($url)) {
return $url;
}
$url['raw'] = false; // no checking is necessary for REST
if (!is_array($url['info'])) {
return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' .
'this should never happen');
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$testversion = $this->_registry->packageInfo($url['package'], 'version',
$parr['channel']);
PEAR::staticPopErrorHandling();
if (!isset($this->_options['force']) &&
!isset($this->_options['downloadonly']) &&
!PEAR::isError($testversion) &&
!isset($parr['group'])) {
if (version_compare($testversion, $url['version'], '>=')) {
return PEAR::raiseError($this->_registry->parsedPackageNameToString(
$parr, true) . ' is already installed and is newer than detected ' .
'release version ' . $url['version'], -976);
}
}
if (isset($url['info']['required']) || $url['compatible']) {
require_once 'PEAR/PackageFile/v2.php';
$pf = new PEAR_PackageFile_v2;
$pf->setRawChannel($parr['channel']);
if ($url['compatible']) {
$pf->setRawCompatible($url['compatible']);
}
} else {
require_once 'PEAR/PackageFile/v1.php';
$pf = new PEAR_PackageFile_v1;
}
$pf->setRawPackage($url['package']);
$pf->setDeps($url['info']);
if ($url['compatible']) {
$pf->setCompatible($url['compatible']);
}
$pf->setRawState($url['stability']);
$url['info'] = &$pf;
if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
$ext = '.tar';
} else {
$ext = '.tgz';
}
if (is_array($url)) {
if (isset($url['url'])) {
$url['url'] .= $ext;
}
}
return $url;
} elseif ($chan->supports('xmlrpc', 'package.getDownloadURL', false, '1.1')) {
// don't install with the old version information unless we're doing a plain
// vanilla simple installation. If the user says to install a particular
// version or state, ignore the current installed version
if (!isset($parr['version']) && !isset($parr['state']) && $version
&& !isset($this->_options['downloadonly'])) {
$url = $this->_remote->call('package.getDownloadURL', $parr, $state, $version);
} else {
$url = $this->_remote->call('package.getDownloadURL', $parr, $state);
}
} else {
$url = $this->_remote->call('package.getDownloadURL', $parr, $state);
}
if (PEAR::isError($url)) {
return $url;
}
if ($parr['channel'] != $curchannel) {
$this->configSet('default_channel', $curchannel);
}
if (isset($url['__PEAR_ERROR_CLASS__'])) {
return PEAR::raiseError($url['message']);
}
if (!is_array($url)) {
return $url;
}
$url['raw'] = $url['info'];
if (isset($this->_options['downloadonly'])) {
$pkg = &$this->getPackagefileObject($this->config, $this->debug);
} else {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (PEAR::isError($dir = $this->getDownloadDir())) {
PEAR::staticPopErrorHandling();
return $dir;
}
PEAR::staticPopErrorHandling();
$pkg = &$this->getPackagefileObject($this->config, $this->debug, $dir);
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pinfo = &$pkg->fromXmlString($url['info'], PEAR_VALIDATE_DOWNLOADING, 'remote');
PEAR::staticPopErrorHandling();
if (PEAR::isError($pinfo)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $pinfo->getMessage());
}
return PEAR::raiseError('Remote package.xml is not valid - this should never happen');
}
$url['info'] = &$pinfo;
if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
$ext = '.tar';
} else {
$ext = '.tgz';
}
if (is_array($url)) {
if (isset($url['url'])) {
$url['url'] .= $ext;
}
}
return $url;
}
// }}}
// {{{ getDepPackageDownloadUrl()
 
/**
* @param array dependency array
* @access private
*/
function _getDepPackageDownloadUrl($dep, $parr)
{
$xsdversion = isset($dep['rel']) ? '1.0' : '2.0';
$curchannel = $this->config->get('default_channel');
if (isset($dep['uri'])) {
$xsdversion = '2.0';
$chan = &$this->_registry->getChannel('__uri');
if (PEAR::isError($chan)) {
return $chan;
}
$version = $this->_registry->packageInfo($dep['name'], 'version', '__uri');
$this->configSet('default_channel', '__uri');
} else {
if (isset($dep['channel'])) {
$remotechannel = $dep['channel'];
} else {
$remotechannel = 'pear.php.net';
}
if (!$this->_registry->channelExists($remotechannel)) {
do {
if ($this->config->get('auto_discover')) {
if ($this->discover($remotechannel)) {
break;
}
}
return PEAR::raiseError('Unknown remote channel: ' . $remotechannel);
} while (false);
}
$chan = &$this->_registry->getChannel($remotechannel);
if (PEAR::isError($chan)) {
return $chan;
}
$version = $this->_registry->packageInfo($dep['name'], 'version',
$remotechannel);
$this->configSet('default_channel', $remotechannel);
}
$state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state');
if (isset($parr['state']) && isset($parr['version'])) {
unset($parr['state']);
}
if (isset($dep['uri'])) {
$info = &$this->newDownloaderPackage($this);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $info->initialize($dep);
PEAR::staticPopErrorHandling();
if (!$err) {
// skip parameters that were missed by preferred_state
return PEAR::raiseError('Cannot initialize dependency');
}
if (PEAR::isError($err)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $err->getMessage());
}
if (is_object($info)) {
$param = $info->getChannel() . '/' . $info->getPackage();
}
return PEAR::raiseError('Package "' . $param . '" is not valid');
}
return $info;
} elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', $this->_options);
$url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr,
$state, $version);
if (PEAR::isError($url)) {
return $url;
}
if ($parr['channel'] != $curchannel) {
$this->configSet('default_channel', $curchannel);
}
if (!is_array($url)) {
return $url;
}
$url['raw'] = false; // no checking is necessary for REST
if (!is_array($url['info'])) {
return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' .
'this should never happen');
}
if (isset($url['info']['required'])) {
if (!class_exists('PEAR_PackageFile_v2')) {
require_once 'PEAR/PackageFile/v2.php';
}
$pf = new PEAR_PackageFile_v2;
$pf->setRawChannel($remotechannel);
} else {
if (!class_exists('PEAR_PackageFile_v1')) {
require_once 'PEAR/PackageFile/v1.php';
}
$pf = new PEAR_PackageFile_v1;
}
$pf->setRawPackage($url['package']);
$pf->setDeps($url['info']);
if ($url['compatible']) {
$pf->setCompatible($url['compatible']);
}
$pf->setRawState($url['stability']);
$url['info'] = &$pf;
if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
$ext = '.tar';
} else {
$ext = '.tgz';
}
if (is_array($url)) {
if (isset($url['url'])) {
$url['url'] .= $ext;
}
}
return $url;
} elseif ($chan->supports('xmlrpc', 'package.getDepDownloadURL', false, '1.1')) {
if ($version) {
$url = $this->_remote->call('package.getDepDownloadURL', $xsdversion, $dep, $parr,
$state, $version);
} else {
$url = $this->_remote->call('package.getDepDownloadURL', $xsdversion, $dep, $parr,
$state);
}
} else {
$url = $this->_remote->call('package.getDepDownloadURL', $xsdversion, $dep, $parr, $state);
}
if ($this->config->get('default_channel') != $curchannel) {
$this->configSet('default_channel', $curchannel);
}
if (!is_array($url)) {
return $url;
}
if (isset($url['__PEAR_ERROR_CLASS__'])) {
return PEAR::raiseError($url['message']);
}
$url['raw'] = $url['info'];
$pkg = &$this->getPackagefileObject($this->config, $this->debug);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pinfo = &$pkg->fromXmlString($url['info'], PEAR_VALIDATE_DOWNLOADING, 'remote');
PEAR::staticPopErrorHandling();
if (PEAR::isError($pinfo)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $pinfo->getMessage());
}
return PEAR::raiseError('Remote package.xml is not valid - this should never happen');
}
$url['info'] = &$pinfo;
if (is_array($url)) {
if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
$ext = '.tar';
} else {
$ext = '.tgz';
}
if (isset($url['url'])) {
$url['url'] .= $ext;
}
}
return $url;
}
// }}}
// {{{ getPackageDownloadUrl()
 
/**
* @deprecated in favor of _getPackageDownloadUrl
*/
function getPackageDownloadUrl($package, $version = null, $channel = false)
{
if ($version) {
$package .= "-$version";
}
if ($this === null || $this->_registry === null) {
$package = "http://pear.php.net/get/$package";
} else {
$chan = $this->_registry->getChannel($channel);
if (PEAR::isError($chan)) {
return '';
}
$package = "http://" . $chan->getServer() . "/get/$package";
}
if (!extension_loaded("zlib")) {
$package .= '?uncompress=yes';
}
return $package;
}
 
// }}}
// {{{ getDownloadedPackages()
 
/**
* Retrieve a list of downloaded packages after a call to {@link download()}.
*
* Also resets the list of downloaded packages.
* @return array
*/
function getDownloadedPackages()
{
$ret = $this->_downloadedPackages;
$this->_downloadedPackages = array();
$this->_toDownload = array();
return $ret;
}
 
// }}}
// {{{ _downloadCallback()
 
function _downloadCallback($msg, $params = null)
{
switch ($msg) {
case 'saveas':
$this->log(1, "downloading $params ...");
break;
case 'done':
$this->log(1, '...done: ' . number_format($params, 0, '', ',') . ' bytes');
break;
case 'bytesread':
static $bytes;
if (empty($bytes)) {
$bytes = 0;
}
if (!($bytes % 10240)) {
$this->log(1, '.', false);
}
$bytes += $params;
break;
case 'start':
if($params[1] == -1) {
$length = "Unknown size";
} else {
$length = number_format($params[1], 0, '', ',')." bytes";
}
$this->log(1, "Starting to download {$params[0]} ($length)");
break;
}
if (method_exists($this->ui, '_downloadCallback'))
$this->ui->_downloadCallback($msg, $params);
}
 
// }}}
// {{{ _prependPath($path, $prepend)
 
function _prependPath($path, $prepend)
{
if (strlen($prepend) > 0) {
if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) {
if (preg_match('/^[a-z]:/i', $prepend)) {
$prepend = substr($prepend, 2);
} elseif ($prepend{0} != '\\') {
$prepend = "\\$prepend";
}
$path = substr($path, 0, 2) . $prepend . substr($path, 2);
} else {
$path = $prepend . $path;
}
}
return $path;
}
// }}}
// {{{ pushError($errmsg, $code)
 
/**
* @param string
* @param integer
*/
function pushError($errmsg, $code = -1)
{
array_push($this->_errorStack, array($errmsg, $code));
}
 
// }}}
// {{{ getErrorMsgs()
 
function getErrorMsgs()
{
$msgs = array();
$errs = $this->_errorStack;
foreach ($errs as $err) {
$msgs[] = $err[0];
}
$this->_errorStack = array();
return $msgs;
}
 
// }}}
 
/**
* for BC
*/
function sortPkgDeps(&$packages, $uninstall = false)
{
$uninstall ?
$this->sortPackagesForUninstall($packages) :
$this->sortPackagesForInstall($packages);
}
 
/**
* Sort a list of arrays of array(downloaded packagefilename) by dependency.
*
* This uses the topological sort method from graph theory, and the
* Structures_Graph package to properly sort dependencies for installation.
* @param array an array of downloaded PEAR_Downloader_Packages
* @return array array of array(packagefilename, package.xml contents)
*/
function sortPackagesForInstall(&$packages)
{
require_once 'Structures/Graph.php';
require_once 'Structures/Graph/Node.php';
require_once 'Structures/Graph/Manipulator/TopologicalSorter.php';
$depgraph = new Structures_Graph(true);
$nodes = array();
$reg = &$this->config->getRegistry();
foreach ($packages as $i => $package) {
$pname = $reg->parsedPackageNameToString(
array(
'channel' => $package->getChannel(),
'package' => strtolower($package->getPackage()),
));
$nodes[$pname] = new Structures_Graph_Node;
$nodes[$pname]->setData($packages[$i]);
$depgraph->addNode($nodes[$pname]);
}
$deplinks = array();
foreach ($nodes as $package => $node) {
$pf = &$node->getData();
$pdeps = $pf->getDeps(true);
if (!$pdeps) {
continue;
}
if ($pf->getPackagexmlVersion() == '1.0') {
foreach ($pdeps as $dep) {
if ($dep['type'] != 'pkg' ||
(isset($dep['optional']) && $dep['optional'] == 'yes')) {
continue;
}
$dname = $reg->parsedPackageNameToString(
array(
'channel' => 'pear.php.net',
'package' => strtolower($dep['name']),
));
if (isset($nodes[$dname]))
{
if (!isset($deplinks[$dname])) {
$deplinks[$dname] = array();
}
$deplinks[$dname][$package] = 1;
// dependency is in installed packages
continue;
}
$dname = $reg->parsedPackageNameToString(
array(
'channel' => 'pecl.php.net',
'package' => strtolower($dep['name']),
));
if (isset($nodes[$dname]))
{
if (!isset($deplinks[$dname])) {
$deplinks[$dname] = array();
}
$deplinks[$dname][$package] = 1;
// dependency is in installed packages
continue;
}
}
} else {
// the only ordering we care about is:
// 1) subpackages must be installed before packages that depend on them
// 2) required deps must be installed before packages that depend on them
if (isset($pdeps['required']['subpackage'])) {
$t = $pdeps['required']['subpackage'];
if (!isset($t[0])) {
$t = array($t);
}
$this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
}
if (isset($pdeps['group'])) {
if (!isset($pdeps['group'][0])) {
$pdeps['group'] = array($pdeps['group']);
}
foreach ($pdeps['group'] as $group) {
if (isset($group['subpackage'])) {
$t = $group['subpackage'];
if (!isset($t[0])) {
$t = array($t);
}
$this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
}
}
}
if (isset($pdeps['optional']['subpackage'])) {
$t = $pdeps['optional']['subpackage'];
if (!isset($t[0])) {
$t = array($t);
}
$this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
}
if (isset($pdeps['required']['package'])) {
$t = $pdeps['required']['package'];
if (!isset($t[0])) {
$t = array($t);
}
$this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
}
if (isset($pdeps['group'])) {
if (!isset($pdeps['group'][0])) {
$pdeps['group'] = array($pdeps['group']);
}
foreach ($pdeps['group'] as $group) {
if (isset($group['package'])) {
$t = $group['package'];
if (!isset($t[0])) {
$t = array($t);
}
$this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
}
}
}
}
}
$this->_detectDepCycle($deplinks);
foreach ($deplinks as $dependent => $parents) {
foreach ($parents as $parent => $unused) {
$nodes[$dependent]->connectTo($nodes[$parent]);
}
}
$installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph);
$ret = array();
for ($i = 0; $i < count($installOrder); $i++) {
foreach ($installOrder[$i] as $index => $sortedpackage) {
$data = &$installOrder[$i][$index]->getData();
$ret[] = &$nodes[$reg->parsedPackageNameToString(
array(
'channel' => $data->getChannel(),
'package' => strtolower($data->getPackage()),
))]->getData();
}
}
$packages = $ret;
return;
}
 
/**
* Detect recursive links between dependencies and break the cycles
*
* @param array
* @access private
*/
function _detectDepCycle(&$deplinks)
{
do {
$keepgoing = false;
foreach ($deplinks as $dep => $parents) {
foreach ($parents as $parent => $unused) {
// reset the parent cycle detector
$this->_testCycle(null, null, null);
if ($this->_testCycle($dep, $deplinks, $parent)) {
$keepgoing = true;
unset($deplinks[$dep][$parent]);
if (count($deplinks[$dep]) == 0) {
unset($deplinks[$dep]);
}
continue 3;
}
}
}
} while ($keepgoing);
}
 
function _testCycle($test, $deplinks, $dep)
{
static $visited = array();
if ($test === null) {
$visited = array();
return;
}
// this happens when a parent has a dep cycle on another dependency
// but the child is not part of the cycle
if (isset($visited[$dep])) {
return false;
}
$visited[$dep] = 1;
if ($test == $dep) {
return true;
}
if (isset($deplinks[$dep])) {
if (in_array($test, array_keys($deplinks[$dep]), true)) {
return true;
}
foreach ($deplinks[$dep] as $parent => $unused) {
if ($this->_testCycle($test, $deplinks, $parent)) {
return true;
}
}
}
return false;
}
 
/**
* Set up the dependency for installation parsing
*
* @param array $t dependency information
* @param PEAR_Registry $reg
* @param array $deplinks list of dependency links already established
* @param array $nodes all existing package nodes
* @param string $package parent package name
* @access private
*/
function _setupGraph($t, $reg, &$deplinks, &$nodes, $package)
{
foreach ($t as $dep) {
$depchannel = !isset($dep['channel']) ?
'__uri': $dep['channel'];
$dname = $reg->parsedPackageNameToString(
array(
'channel' => $depchannel,
'package' => strtolower($dep['name']),
));
if (isset($nodes[$dname]))
{
if (!isset($deplinks[$dname])) {
$deplinks[$dname] = array();
}
$deplinks[$dname][$package] = 1;
}
}
}
 
function _dependsOn($a, $b)
{
return $this->_checkDepTree(strtolower($a->getChannel()), strtolower($a->getPackage()),
$b);
}
 
function _checkDepTree($channel, $package, $b, $checked = array())
{
$checked[$channel][$package] = true;
if (!isset($this->_depTree[$channel][$package])) {
return false;
}
if (isset($this->_depTree[$channel][$package][strtolower($b->getChannel())]
[strtolower($b->getPackage())])) {
return true;
}
foreach ($this->_depTree[$channel][$package] as $ch => $packages) {
foreach ($packages as $pa => $true) {
if ($this->_checkDepTree($ch, $pa, $b, $checked)) {
return true;
}
}
}
return false;
}
 
function _sortInstall($a, $b)
{
if (!$a->getDeps() && !$b->getDeps()) {
return 0; // neither package has dependencies, order is insignificant
}
if ($a->getDeps() && !$b->getDeps()) {
return 1; // $a must be installed after $b because $a has dependencies
}
if (!$a->getDeps() && $b->getDeps()) {
return -1; // $b must be installed after $a because $b has dependencies
}
// both packages have dependencies
if ($this->_dependsOn($a, $b)) {
return 1;
}
if ($this->_dependsOn($b, $a)) {
return -1;
}
return 0;
}
 
/**
* Download a file through HTTP. Considers suggested file name in
* Content-disposition: header and can run a callback function for
* different events. The callback will be called with two
* parameters: the callback type, and parameters. The implemented
* callback types are:
*
* 'setup' called at the very beginning, parameter is a UI object
* that should be used for all output
* 'message' the parameter is a string with an informational message
* 'saveas' may be used to save with a different file name, the
* parameter is the filename that is about to be used.
* If a 'saveas' callback returns a non-empty string,
* that file name will be used as the filename instead.
* Note that $save_dir will not be affected by this, only
* the basename of the file.
* 'start' download is starting, parameter is number of bytes
* that are expected, or -1 if unknown
* 'bytesread' parameter is the number of bytes read so far
* 'done' download is complete, parameter is the total number
* of bytes read
* 'connfailed' if the TCP/SSL connection fails, this callback is called
* with array(host,port,errno,errmsg)
* 'writefailed' if writing to disk fails, this callback is called
* with array(destfile,errmsg)
*
* If an HTTP proxy has been configured (http_proxy PEAR_Config
* setting), the proxy will be used.
*
* @param string $url the URL to download
* @param object $ui PEAR_Frontend_* instance
* @param object $config PEAR_Config instance
* @param string $save_dir directory to save file in
* @param mixed $callback function/method to call for status
* updates
* @param false|string|array $lastmodified header values to check against for caching
* use false to return the header values from this download
* @param false|array $accept Accept headers to send
* @return string|array Returns the full path of the downloaded file or a PEAR
* error on failure. If the error is caused by
* socket-related errors, the error object will
* have the fsockopen error code available through
* getCode(). If caching is requested, then return the header
* values.
*
* @access public
*/
function downloadHttp($url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null,
$accept = false)
{
static $redirect = 0;
// allways reset , so we are clean case of error
$wasredirect = $redirect;
$redirect = 0;
if ($callback) {
call_user_func($callback, 'setup', array(&$ui));
}
$info = parse_url($url);
if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) {
return PEAR::raiseError('Cannot download non-http URL "' . $url . '"');
}
if (!isset($info['host'])) {
return PEAR::raiseError('Cannot download from non-URL "' . $url . '"');
} else {
$host = isset($info['host']) ? $info['host'] : null;
$port = isset($info['port']) ? $info['port'] : null;
$path = isset($info['path']) ? $info['path'] : null;
}
if (isset($this)) {
$config = &$this->config;
} else {
$config = &PEAR_Config::singleton();
}
$proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
if ($config->get('http_proxy') &&
$proxy = parse_url($config->get('http_proxy'))) {
$proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') {
$proxy_host = 'ssl://' . $proxy_host;
}
$proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080;
$proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
$proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
 
if ($callback) {
call_user_func($callback, 'message', "Using HTTP proxy $host:$port");
}
}
if (empty($port)) {
if (isset($info['scheme']) && $info['scheme'] == 'https') {
$port = 443;
} else {
$port = 80;
}
}
if ($proxy_host != '') {
$fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr);
if (!$fp) {
if ($callback) {
call_user_func($callback, 'connfailed', array($proxy_host, $proxy_port,
$errno, $errstr));
}
return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno);
}
if ($lastmodified === false || $lastmodified) {
$request = "GET $url HTTP/1.1\r\n";
} else {
$request = "GET $url HTTP/1.0\r\n";
}
} else {
if (isset($info['scheme']) && $info['scheme'] == 'https') {
$host = 'ssl://' . $host;
}
$fp = @fsockopen($host, $port, $errno, $errstr);
if (!$fp) {
if ($callback) {
call_user_func($callback, 'connfailed', array($host, $port,
$errno, $errstr));
}
return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
}
if ($lastmodified === false || $lastmodified) {
$request = "GET $path HTTP/1.1\r\n";
$request .= "Host: $host:$port\r\n";
} else {
$request = "GET $path HTTP/1.0\r\n";
$request .= "Host: $host\r\n";
}
}
$ifmodifiedsince = '';
if (is_array($lastmodified)) {
if (isset($lastmodified['Last-Modified'])) {
$ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n";
}
if (isset($lastmodified['ETag'])) {
$ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n";
}
} else {
$ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : '');
}
$request .= $ifmodifiedsince . "User-Agent: PEAR/1.5.1/PHP/" .
PHP_VERSION . "\r\n";
if (isset($this)) { // only pass in authentication for non-static calls
$username = $config->get('username');
$password = $config->get('password');
if ($username && $password) {
$tmp = base64_encode("$username:$password");
$request .= "Authorization: Basic $tmp\r\n";
}
}
if ($proxy_host != '' && $proxy_user != '') {
$request .= 'Proxy-Authorization: Basic ' .
base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n";
}
if ($accept) {
$request .= 'Accept: ' . implode(', ', $accept) . "\r\n";
}
$request .= "Connection: close\r\n";
$request .= "\r\n";
fwrite($fp, $request);
$headers = array();
$reply = 0;
while (trim($line = fgets($fp, 1024))) {
if (preg_match('/^([^:]+):\s+(.*)\s*$/', $line, $matches)) {
$headers[strtolower($matches[1])] = trim($matches[2]);
} elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
$reply = (int) $matches[1];
if ($reply == 304 && ($lastmodified || ($lastmodified === false))) {
return false;
}
if (! in_array($reply, array(200, 301, 302, 303, 305, 307))) {
return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)");
}
}
}
if ($reply != 200) {
if (isset($headers['location'])) {
if ($wasredirect < 5) {
$redirect = $wasredirect + 1;
return $this->downloadHttp($headers['location'],
$ui, $save_dir, $callback, $lastmodified, $accept);
} else {
return PEAR::raiseError("File http://$host:$port$path not valid (redirection looped more than 5 times)");
}
} else {
return PEAR::raiseError("File http://$host:$port$path not valid (redirected but no location)");
}
}
if (isset($headers['content-disposition']) &&
preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|$)/', $headers['content-disposition'], $matches)) {
$save_as = basename($matches[1]);
} else {
$save_as = basename($url);
}
if ($callback) {
$tmp = call_user_func($callback, 'saveas', $save_as);
if ($tmp) {
$save_as = $tmp;
}
}
$dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as;
if (!$wp = @fopen($dest_file, 'wb')) {
fclose($fp);
if ($callback) {
call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg));
}
return PEAR::raiseError("could not open $dest_file for writing");
}
if (isset($headers['content-length'])) {
$length = $headers['content-length'];
} else {
$length = -1;
}
$bytes = 0;
if ($callback) {
call_user_func($callback, 'start', array(basename($dest_file), $length));
}
while ($data = fread($fp, 1024)) {
$bytes += strlen($data);
if ($callback) {
call_user_func($callback, 'bytesread', $bytes);
}
if (!@fwrite($wp, $data)) {
fclose($fp);
if ($callback) {
call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg));
}
return PEAR::raiseError("$dest_file: write failed ($php_errormsg)");
}
}
fclose($fp);
fclose($wp);
if ($callback) {
call_user_func($callback, 'done', $bytes);
}
if ($lastmodified === false || $lastmodified) {
if (isset($headers['etag'])) {
$lastmodified = array('ETag' => $headers['etag']);
}
if (isset($headers['last-modified'])) {
if (is_array($lastmodified)) {
$lastmodified['Last-Modified'] = $headers['last-modified'];
} else {
$lastmodified = $headers['last-modified'];
}
}
return array($dest_file, $lastmodified, $headers);
}
return $dest_file;
}
}
// }}}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Autoloader.php
New file
0,0 → 1,223
<?php
/**
* Class auto-loader
*
* PHP versions 4
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Autoloader.php,v 1.13 2006/01/06 04:47:36 cellog Exp $
* @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
* @since File available since Release 0.1
* @deprecated File deprecated in Release 1.4.0a1
*/
 
// /* vim: set expandtab tabstop=4 shiftwidth=4: */
 
if (!extension_loaded("overload")) {
// die hard without ext/overload
die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader");
}
 
/**
* Include for PEAR_Error and PEAR classes
*/
require_once "PEAR.php";
 
/**
* This class is for objects where you want to separate the code for
* some methods into separate classes. This is useful if you have a
* class with not-frequently-used methods that contain lots of code
* that you would like to avoid always parsing.
*
* The PEAR_Autoloader class provides autoloading and aggregation.
* The autoloading lets you set up in which classes the separated
* methods are found. Aggregation is the technique used to import new
* methods, an instance of each class providing separated methods is
* stored and called every time the aggregated method is called.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
* @since File available since Release 0.1
* @deprecated File deprecated in Release 1.4.0a1
*/
class PEAR_Autoloader extends PEAR
{
// {{{ properties
 
/**
* Map of methods and classes where they are defined
*
* @var array
*
* @access private
*/
var $_autoload_map = array();
 
/**
* Map of methods and aggregate objects
*
* @var array
*
* @access private
*/
var $_method_map = array();
 
// }}}
// {{{ addAutoload()
 
/**
* Add one or more autoload entries.
*
* @param string $method which method to autoload
*
* @param string $classname (optional) which class to find the method in.
* If the $method parameter is an array, this
* parameter may be omitted (and will be ignored
* if not), and the $method parameter will be
* treated as an associative array with method
* names as keys and class names as values.
*
* @return void
*
* @access public
*/
function addAutoload($method, $classname = null)
{
if (is_array($method)) {
array_walk($method, create_function('$a,&$b', '$b = strtolower($b);'));
$this->_autoload_map = array_merge($this->_autoload_map, $method);
} else {
$this->_autoload_map[strtolower($method)] = $classname;
}
}
 
// }}}
// {{{ removeAutoload()
 
/**
* Remove an autoload entry.
*
* @param string $method which method to remove the autoload entry for
*
* @return bool TRUE if an entry was removed, FALSE if not
*
* @access public
*/
function removeAutoload($method)
{
$method = strtolower($method);
$ok = isset($this->_autoload_map[$method]);
unset($this->_autoload_map[$method]);
return $ok;
}
 
// }}}
// {{{ addAggregateObject()
 
/**
* Add an aggregate object to this object. If the specified class
* is not defined, loading it will be attempted following PEAR's
* file naming scheme. All the methods in the class will be
* aggregated, except private ones (name starting with an
* underscore) and constructors.
*
* @param string $classname what class to instantiate for the object.
*
* @return void
*
* @access public
*/
function addAggregateObject($classname)
{
$classname = strtolower($classname);
if (!class_exists($classname)) {
$include_file = preg_replace('/[^a-z0-9]/i', '_', $classname);
include_once $include_file;
}
$obj =& new $classname;
$methods = get_class_methods($classname);
foreach ($methods as $method) {
// don't import priviate methods and constructors
if ($method{0} != '_' && $method != $classname) {
$this->_method_map[$method] = $obj;
}
}
}
 
// }}}
// {{{ removeAggregateObject()
 
/**
* Remove an aggregate object.
*
* @param string $classname the class of the object to remove
*
* @return bool TRUE if an object was removed, FALSE if not
*
* @access public
*/
function removeAggregateObject($classname)
{
$ok = false;
$classname = strtolower($classname);
reset($this->_method_map);
while (list($method, $obj) = each($this->_method_map)) {
if (is_a($obj, $classname)) {
unset($this->_method_map[$method]);
$ok = true;
}
}
return $ok;
}
 
// }}}
// {{{ __call()
 
/**
* Overloaded object call handler, called each time an
* undefined/aggregated method is invoked. This method repeats
* the call in the right aggregate object and passes on the return
* value.
*
* @param string $method which method that was called
*
* @param string $args An array of the parameters passed in the
* original call
*
* @return mixed The return value from the aggregated method, or a PEAR
* error if the called method was unknown.
*/
function __call($method, $args, &$retval)
{
$method = strtolower($method);
if (empty($this->_method_map[$method]) && isset($this->_autoload_map[$method])) {
$this->addAggregateObject($this->_autoload_map[$method]);
}
if (isset($this->_method_map[$method])) {
$retval = call_user_func_array(array($this->_method_map[$method], $method), $args);
return true;
}
return false;
}
 
// }}}
}
 
overload("PEAR_Autoloader");
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Dependency2.php
New file
0,0 → 1,1291
<?php
/**
* PEAR_Dependency2, advanced dependency validation
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Dependency2.php,v 1.54 2007/02/13 04:16:25 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* Required for the PEAR_VALIDATE_* constants
*/
require_once 'PEAR/Validate.php';
 
/**
* Dependency check for PEAR packages
*
* This class handles both version 1.0 and 2.0 dependencies
* WARNING: *any* changes to this class must be duplicated in the
* test_PEAR_Dependency2 class found in tests/PEAR_Dependency2/setup.php.inc,
* or unit tests will not actually validate the changes
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Dependency2
{
/**
* One of the PEAR_VALIDATE_* states
* @see PEAR_VALIDATE_NORMAL
* @var integer
*/
var $_state;
/**
* Command-line options to install/upgrade/uninstall commands
* @param array
*/
var $_options;
/**
* @var OS_Guess
*/
var $_os;
/**
* @var PEAR_Registry
*/
var $_registry;
/**
* @var PEAR_Config
*/
var $_config;
/**
* @var PEAR_DependencyDB
*/
var $_dependencydb;
/**
* Output of PEAR_Registry::parsedPackageName()
* @var array
*/
var $_currentPackage;
/**
* @param PEAR_Config
* @param array installation options
* @param array format of PEAR_Registry::parsedPackageName()
* @param int installation state (one of PEAR_VALIDATE_*)
*/
function PEAR_Dependency2(&$config, $installoptions, $package,
$state = PEAR_VALIDATE_INSTALLING)
{
$this->_config = &$config;
if (!class_exists('PEAR_DependencyDB')) {
require_once 'PEAR/DependencyDB.php';
}
if (isset($installoptions['packagingroot'])) {
// make sure depdb is in the right location
$config->setInstallRoot($installoptions['packagingroot']);
}
$this->_registry = &$config->getRegistry();
$this->_dependencydb = &PEAR_DependencyDB::singleton($config);
if (isset($installoptions['packagingroot'])) {
$config->setInstallRoot(false);
}
$this->_options = $installoptions;
$this->_state = $state;
if (!class_exists('OS_Guess')) {
require_once 'OS/Guess.php';
}
$this->_os = new OS_Guess;
$this->_currentPackage = $package;
}
 
function _getExtraString($dep)
{
$extra = ' (';
if (isset($dep['uri'])) {
return '';
}
if (isset($dep['recommended'])) {
$extra .= 'recommended version ' . $dep['recommended'];
} else {
if (isset($dep['min'])) {
$extra .= 'version >= ' . $dep['min'];
}
if (isset($dep['max'])) {
if ($extra != ' (') {
$extra .= ', ';
}
$extra .= 'version <= ' . $dep['max'];
}
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
if ($extra != ' (') {
$extra .= ', ';
}
$extra .= 'excluded versions: ';
foreach ($dep['exclude'] as $i => $exclude) {
if ($i) {
$extra .= ', ';
}
$extra .= $exclude;
}
}
}
$extra .= ')';
if ($extra == ' ()') {
$extra = '';
}
return $extra;
}
 
/**
* This makes unit-testing a heck of a lot easier
*/
function getPHP_OS()
{
return PHP_OS;
}
 
/**
* This makes unit-testing a heck of a lot easier
*/
function getsysname()
{
return $this->_os->getSysname();
}
 
/**
* Specify a dependency on an OS. Use arch for detailed os/processor information
*
* There are two generic OS dependencies that will be the most common, unix and windows.
* Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix
*/
function validateOsDependency($dep)
{
if ($this->_state != PEAR_VALIDATE_INSTALLING &&
$this->_state != PEAR_VALIDATE_DOWNLOADING) {
return true;
}
if (isset($dep['conflicts'])) {
$not = true;
} else {
$not = false;
}
if ($dep['name'] == '*') {
return true;
}
switch (strtolower($dep['name'])) {
case 'windows' :
if ($not) {
if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError("Cannot install %s on Windows");
} else {
return $this->warning("warning: Cannot install %s on Windows");
}
}
} else {
if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError("Can only install %s on Windows");
} else {
return $this->warning("warning: Can only install %s on Windows");
}
}
}
break;
case 'unix' :
$unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix');
if ($not) {
if (in_array($this->getSysname(), $unices)) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError("Cannot install %s on any Unix system");
} else {
return $this->warning(
"warning: Cannot install %s on any Unix system");
}
}
} else {
if (!in_array($this->getSysname(), $unices)) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError("Can only install %s on a Unix system");
} else {
return $this->warning(
"warning: Can only install %s on a Unix system");
}
}
}
break;
default :
if ($not) {
if (strtolower($dep['name']) == strtolower($this->getSysname())) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError('Cannot install %s on ' . $dep['name'] .
' operating system');
} else {
return $this->warning('warning: Cannot install %s on ' .
$dep['name'] . ' operating system');
}
}
} else {
if (strtolower($dep['name']) != strtolower($this->getSysname())) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError('Cannot install %s on ' .
$this->getSysname() .
' operating system, can only install on ' . $dep['name']);
} else {
return $this->warning('warning: Cannot install %s on ' .
$this->getSysname() .
' operating system, can only install on ' . $dep['name']);
}
}
}
}
return true;
}
 
/**
* This makes unit-testing a heck of a lot easier
*/
function matchSignature($pattern)
{
return $this->_os->matchSignature($pattern);
}
 
/**
* Specify a complex dependency on an OS/processor/kernel version,
* Use OS for simple operating system dependency.
*
* This is the only dependency that accepts an eregable pattern. The pattern
* will be matched against the php_uname() output parsed by OS_Guess
*/
function validateArchDependency($dep)
{
if ($this->_state != PEAR_VALIDATE_INSTALLING) {
return true;
}
if (isset($dep['conflicts'])) {
$not = true;
} else {
$not = false;
}
if (!$this->matchSignature($dep['pattern'])) {
if (!$not) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s Architecture dependency failed, does not ' .
'match "' . $dep['pattern'] . '"');
} else {
return $this->warning('warning: %s Architecture dependency failed, does ' .
'not match "' . $dep['pattern'] . '"');
}
}
return true;
} else {
if ($not) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s Architecture dependency failed, required "' .
$dep['pattern'] . '"');
} else {
return $this->warning('warning: %s Architecture dependency failed, ' .
'required "' . $dep['pattern'] . '"');
}
}
return true;
}
}
 
/**
* This makes unit-testing a heck of a lot easier
*/
function extension_loaded($name)
{
return extension_loaded($name);
}
 
/**
* This makes unit-testing a heck of a lot easier
*/
function phpversion($name = null)
{
if ($name !== null) {
return phpversion($name);
} else {
return phpversion();
}
}
 
function validateExtensionDependency($dep, $required = true)
{
if ($this->_state != PEAR_VALIDATE_INSTALLING &&
$this->_state != PEAR_VALIDATE_DOWNLOADING) {
return true;
}
$loaded = $this->extension_loaded($dep['name']);
$extra = $this->_getExtraString($dep);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
}
if (!isset($dep['min']) && !isset($dep['max']) &&
!isset($dep['recommended']) && !isset($dep['exclude'])) {
if ($loaded) {
if (isset($dep['conflicts'])) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra);
} else {
return $this->warning('warning: %s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra);
}
}
return true;
} else {
if (isset($dep['conflicts'])) {
return true;
}
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP extension "' .
$dep['name'] . '"' . $extra);
} else {
return $this->warning('warning: %s requires PHP extension "' .
$dep['name'] . '"' . $extra);
}
} else {
return $this->warning('%s can optionally use PHP extension "' .
$dep['name'] . '"' . $extra);
}
}
}
if (!$loaded) {
if (isset($dep['conflicts'])) {
return true;
}
if (!$required) {
return $this->warning('%s can optionally use PHP extension "' .
$dep['name'] . '"' . $extra);
} else {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP extension "' . $dep['name'] .
'"' . $extra);
}
return $this->warning('warning: %s requires PHP extension "' . $dep['name'] .
'"' . $extra);
}
}
$version = (string) $this->phpversion($dep['name']);
if (empty($version)) {
$version = '0';
}
$fail = false;
if (isset($dep['min'])) {
if (!version_compare($version, $dep['min'], '>=')) {
$fail = true;
}
}
if (isset($dep['max'])) {
if (!version_compare($version, $dep['max'], '<=')) {
$fail = true;
}
}
if ($fail && !isset($dep['conflicts'])) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP extension "' . $dep['name'] .
'"' . $extra . ', installed version is ' . $version);
} else {
return $this->warning('warning: %s requires PHP extension "' . $dep['name'] .
'"' . $extra . ', installed version is ' . $version);
}
} elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra . ', installed version is ' . $version);
} else {
return $this->warning('warning: %s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra . ', installed version is ' . $version);
}
}
if (isset($dep['exclude'])) {
foreach ($dep['exclude'] as $exclude) {
if (version_compare($version, $exclude, '==')) {
if (isset($dep['conflicts'])) {
continue;
}
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError('%s is not compatible with PHP extension "' .
$dep['name'] . '" version ' .
$exclude);
} else {
return $this->warning('warning: %s is not compatible with PHP extension "' .
$dep['name'] . '" version ' .
$exclude);
}
} elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra . ', installed version is ' . $version);
} else {
return $this->warning('warning: %s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra . ', installed version is ' . $version);
}
}
}
}
if (isset($dep['recommended'])) {
if (version_compare($version, $dep['recommended'], '==')) {
return true;
} else {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] .
' version "' . $version . '"' .
' is not the recommended version "' . $dep['recommended'] .
'", but may be compatible, use --force to install');
} else {
return $this->warning('warning: %s dependency: PHP extension ' .
$dep['name'] . ' version "' . $version . '"' .
' is not the recommended version "' . $dep['recommended'].'"');
}
}
}
return true;
}
 
function validatePhpDependency($dep)
{
if ($this->_state != PEAR_VALIDATE_INSTALLING &&
$this->_state != PEAR_VALIDATE_DOWNLOADING) {
return true;
}
$version = $this->phpversion();
$extra = $this->_getExtraString($dep);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
}
if (isset($dep['min'])) {
if (!version_compare($version, $dep['min'], '>=')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP' .
$extra . ', installed version is ' . $version);
} else {
return $this->warning('warning: %s requires PHP' .
$extra . ', installed version is ' . $version);
}
}
}
if (isset($dep['max'])) {
if (!version_compare($version, $dep['max'], '<=')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP' .
$extra . ', installed version is ' . $version);
} else {
return $this->warning('warning: %s requires PHP' .
$extra . ', installed version is ' . $version);
}
}
}
if (isset($dep['exclude'])) {
foreach ($dep['exclude'] as $exclude) {
if (version_compare($version, $exclude, '==')) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError('%s is not compatible with PHP version ' .
$exclude);
} else {
return $this->warning(
'warning: %s is not compatible with PHP version ' .
$exclude);
}
}
}
}
return true;
}
 
/**
* This makes unit-testing a heck of a lot easier
*/
function getPEARVersion()
{
return '1.5.1';
}
 
function validatePearinstallerDependency($dep)
{
$pearversion = $this->getPEARVersion();
$extra = $this->_getExtraString($dep);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
}
if (version_compare($pearversion, $dep['min'], '<')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PEAR Installer' . $extra .
', installed version is ' . $pearversion);
} else {
return $this->warning('warning: %s requires PEAR Installer' . $extra .
', installed version is ' . $pearversion);
}
}
if (isset($dep['max'])) {
if (version_compare($pearversion, $dep['max'], '>')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PEAR Installer' . $extra .
', installed version is ' . $pearversion);
} else {
return $this->warning('warning: %s requires PEAR Installer' . $extra .
', installed version is ' . $pearversion);
}
}
}
if (isset($dep['exclude'])) {
if (!isset($dep['exclude'][0])) {
$dep['exclude'] = array($dep['exclude']);
}
foreach ($dep['exclude'] as $exclude) {
if (version_compare($exclude, $pearversion, '==')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s is not compatible with PEAR Installer ' .
'version ' . $exclude);
} else {
return $this->warning('warning: %s is not compatible with PEAR ' .
'Installer version ' . $exclude);
}
}
}
}
return true;
}
 
function validateSubpackageDependency($dep, $required, $params)
{
return $this->validatePackageDependency($dep, $required, $params);
}
 
/**
* @param array dependency information (2.0 format)
* @param boolean whether this is a required dependency
* @param array a list of downloaded packages to be installed, if any
* @param boolean if true, then deps on pear.php.net that fail will also check
* against pecl.php.net packages to accomodate extensions that have
* moved to pecl.php.net from pear.php.net
*/
function validatePackageDependency($dep, $required, $params, $depv1 = false)
{
if ($this->_state != PEAR_VALIDATE_INSTALLING &&
$this->_state != PEAR_VALIDATE_DOWNLOADING) {
return true;
}
if (isset($dep['providesextension'])) {
if ($this->extension_loaded($dep['providesextension'])) {
$save = $dep;
$subdep = $dep;
$subdep['name'] = $subdep['providesextension'];
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$ret = $this->validateExtensionDependency($subdep, $required);
PEAR::popErrorHandling();
if (!PEAR::isError($ret)) {
return true;
}
}
}
if ($this->_state == PEAR_VALIDATE_INSTALLING) {
return $this->_validatePackageInstall($dep, $required, $depv1);
}
if ($this->_state == PEAR_VALIDATE_DOWNLOADING) {
return $this->_validatePackageDownload($dep, $required, $params, $depv1);
}
}
 
function _validatePackageDownload($dep, $required, $params, $depv1 = false)
{
$dep['package'] = $dep['name'];
if (isset($dep['uri'])) {
$dep['channel'] = '__uri';
}
$depname = $this->_registry->parsedPackageNameToString($dep, true);
$found = false;
foreach ($params as $param) {
if ($param->isEqual(
array('package' => $dep['name'],
'channel' => $dep['channel']))) {
$found = true;
break;
}
if ($depv1 && $dep['channel'] == 'pear.php.net') {
if ($param->isEqual(
array('package' => $dep['name'],
'channel' => 'pecl.php.net'))) {
$found = true;
break;
}
}
}
if (!$found && isset($dep['providesextension'])) {
foreach ($params as $param) {
if ($param->isExtension($dep['providesextension'])) {
$found = true;
break;
}
}
}
if ($found) {
$version = $param->getVersion();
$installed = false;
$downloaded = true;
} else {
if ($this->_registry->packageExists($dep['name'], $dep['channel'])) {
$installed = true;
$downloaded = false;
$version = $this->_registry->packageinfo($dep['name'], 'version',
$dep['channel']);
} else {
if ($dep['channel'] == 'pecl.php.net' && $this->_registry->packageExists($dep['name'],
'pear.php.net')) {
$installed = true;
$downloaded = false;
$version = $this->_registry->packageinfo($dep['name'], 'version',
'pear.php.net');
} else {
$version = 'not installed or downloaded';
$installed = false;
$downloaded = false;
}
}
}
$extra = $this->_getExtraString($dep);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
}
if (!isset($dep['min']) && !isset($dep['max']) &&
!isset($dep['recommended']) && !isset($dep['exclude'])) {
if ($installed || $downloaded) {
$installed = $installed ? 'installed' : 'downloaded';
if (isset($dep['conflicts'])) {
if ($version) {
$rest = ", $installed version is " . $version;
} else {
$rest = '';
}
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with package "' . $depname . '"' .
$extra . $rest);
} else {
return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
$extra . $rest);
}
}
return true;
} else {
if (isset($dep['conflicts'])) {
return true;
}
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires package "' . $depname . '"' .
$extra);
} else {
return $this->warning('warning: %s requires package "' . $depname . '"' .
$extra);
}
} else {
return $this->warning('%s can optionally use package "' . $depname . '"' .
$extra);
}
}
}
if (!$installed && !$downloaded) {
if (isset($dep['conflicts'])) {
return true;
}
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires package "' . $depname . '"' .
$extra);
} else {
return $this->warning('warning: %s requires package "' . $depname . '"' .
$extra);
}
} else {
return $this->warning('%s can optionally use package "' . $depname . '"' .
$extra);
}
}
$fail = false;
if (isset($dep['min'])) {
if (version_compare($version, $dep['min'], '<')) {
$fail = true;
}
}
if (isset($dep['max'])) {
if (version_compare($version, $dep['max'], '>')) {
$fail = true;
}
}
if ($fail && !isset($dep['conflicts'])) {
$installed = $installed ? 'installed' : 'downloaded';
$dep['package'] = $dep['name'];
$dep = $this->_registry->parsedPackageNameToString($dep, true);
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
} else {
return $this->warning('warning: %s requires package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
}
} elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail &&
isset($dep['conflicts']) && !isset($dep['exclude'])) {
$installed = $installed ? 'installed' : 'downloaded';
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra .
", $installed version is " . $version);
} else {
return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
}
}
if (isset($dep['exclude'])) {
$installed = $installed ? 'installed' : 'downloaded';
foreach ($dep['exclude'] as $exclude) {
if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError('%s is not compatible with ' .
$installed . ' package "' .
$depname . '" version ' .
$exclude);
} else {
return $this->warning('warning: %s is not compatible with ' .
$installed . ' package "' .
$depname . '" version ' .
$exclude);
}
} elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) {
$installed = $installed ? 'installed' : 'downloaded';
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
} else {
return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
}
}
}
}
if (isset($dep['recommended'])) {
$installed = $installed ? 'installed' : 'downloaded';
if (version_compare($version, $dep['recommended'], '==')) {
return true;
} else {
if (!$found && $installed) {
$param = $this->_registry->getPackage($dep['name'], $dep['channel']);
}
if ($param) {
$found = false;
foreach ($params as $parent) {
if ($parent->isEqual($this->_currentPackage)) {
$found = true;
break;
}
}
if ($found) {
if ($param->isCompatible($parent)) {
return true;
}
} else { // this is for validPackage() calls
$parent = $this->_registry->getPackage($this->_currentPackage['package'],
$this->_currentPackage['channel']);
if ($parent !== null) {
if ($param->isCompatible($parent)) {
return true;
}
}
}
}
if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) &&
!isset($this->_options['loose'])) {
return $this->raiseError('%s dependency package "' . $depname .
'" ' . $installed . ' version ' . $version .
' is not the recommended version ' . $dep['recommended'] .
', but may be compatible, use --force to install');
} else {
return $this->warning('warning: %s dependency package "' . $depname .
'" ' . $installed . ' version ' . $version .
' is not the recommended version ' . $dep['recommended']);
}
}
}
return true;
}
 
function _validatePackageInstall($dep, $required, $depv1 = false)
{
return $this->_validatePackageDownload($dep, $required, array(), $depv1);
}
 
/**
* Verify that uninstalling packages passed in to command line is OK.
*
* @param PEAR_Installer $dl
* @return PEAR_Error|true
*/
function validatePackageUninstall(&$dl)
{
if (PEAR::isError($this->_dependencydb)) {
return $this->_dependencydb;
}
$params = array();
// construct an array of "downloaded" packages to fool the package dependency checker
// into using these to validate uninstalls of circular dependencies
$downloaded = &$dl->getUninstallPackages();
foreach ($downloaded as $i => $pf) {
if (!class_exists('PEAR_Downloader_Package')) {
require_once 'PEAR/Downloader/Package.php';
}
$dp = &new PEAR_Downloader_Package($dl);
$dp->setPackageFile($downloaded[$i]);
$params[$i] = &$dp;
}
// check cache
$memyselfandI = strtolower($this->_currentPackage['channel']) . '/' .
strtolower($this->_currentPackage['package']);
if (isset($dl->___uninstall_package_cache)) {
$badpackages = $dl->___uninstall_package_cache;
if (isset($badpackages[$memyselfandI]['warnings'])) {
foreach ($badpackages[$memyselfandI]['warnings'] as $warning) {
$dl->log(0, $warning[0]);
}
}
if (isset($badpackages[$memyselfandI]['errors'])) {
foreach ($badpackages[$memyselfandI]['errors'] as $error) {
$dl->log(0, $error->getMessage());
}
if (isset($this->_options['nodeps']) || isset($this->_options['force'])) {
return $this->warning(
'warning: %s should not be uninstalled, other installed packages depend ' .
'on this package');
} else {
return $this->raiseError(
'%s cannot be uninstalled, other installed packages depend on this package');
}
}
return true;
}
// first, list the immediate parents of each package to be uninstalled
$perpackagelist = array();
$allparents = array();
foreach ($params as $i => $param) {
$a = array('channel' => strtolower($param->getChannel()),
'package' => strtolower($param->getPackage()));
$deps = $this->_dependencydb->getDependentPackages($a);
if ($deps) {
foreach ($deps as $d) {
$pardeps = $this->_dependencydb->getDependencies($d);
foreach ($pardeps as $dep) {
if (strtolower($dep['dep']['channel']) == $a['channel'] &&
strtolower($dep['dep']['name']) == $a['package']) {
if (!isset($perpackagelist[$a['channel'] . '/' . $a['package']])) {
$perpackagelist[$a['channel'] . '/' . $a['package']] = array();
}
$perpackagelist[$a['channel'] . '/' . $a['package']][]
= array($d['channel'] . '/' . $d['package'], $dep);
if (!isset($allparents[$d['channel'] . '/' . $d['package']])) {
$allparents[$d['channel'] . '/' . $d['package']] = array();
}
if (!isset($allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']])) {
$allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']] = array();
}
$allparents[$d['channel'] . '/' . $d['package']]
[$a['channel'] . '/' . $a['package']][]
= array($d, $dep);
}
}
}
}
}
// next, remove any packages from the parents list that are not installed
$remove = array();
foreach ($allparents as $parent => $d1) {
foreach ($d1 as $d) {
if ($this->_registry->packageExists($d[0][0]['package'], $d[0][0]['channel'])) {
continue;
}
$remove[$parent] = true;
}
}
// next remove any packages from the parents list that are not passed in for
// uninstallation
foreach ($allparents as $parent => $d1) {
foreach ($d1 as $d) {
foreach ($params as $param) {
if (strtolower($param->getChannel()) == $d[0][0]['channel'] &&
strtolower($param->getPackage()) == $d[0][0]['package']) {
// found it
continue 3;
}
}
$remove[$parent] = true;
}
}
// remove all packages whose dependencies fail
// save which ones failed for error reporting
$badchildren = array();
do {
$fail = false;
foreach ($remove as $package => $unused) {
if (!isset($allparents[$package])) {
continue;
}
foreach ($allparents[$package] as $kid => $d1) {
foreach ($d1 as $depinfo) {
if ($depinfo[1]['type'] != 'optional') {
if (isset($badchildren[$kid])) {
continue;
}
$badchildren[$kid] = true;
$remove[$kid] = true;
$fail = true;
continue 2;
}
}
}
if ($fail) {
// start over, we removed some children
continue 2;
}
}
} while ($fail);
// next, construct the list of packages that can't be uninstalled
$badpackages = array();
$save = $this->_currentPackage;
foreach ($perpackagelist as $package => $packagedeps) {
foreach ($packagedeps as $parent) {
if (!isset($remove[$parent[0]])) {
continue;
}
$packagename = $this->_registry->parsePackageName($parent[0]);
$packagename['channel'] = $this->_registry->channelAlias($packagename['channel']);
$pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']);
$packagename['package'] = $pa->getPackage();
$this->_currentPackage = $packagename;
// parent is not present in uninstall list, make sure we can actually
// uninstall it (parent dep is optional)
$parentname['channel'] = $this->_registry->channelAlias($parent[1]['dep']['channel']);
$pa = $this->_registry->getPackage($parent[1]['dep']['name'], $parent[1]['dep']['channel']);
$parentname['package'] = $pa->getPackage();
$parent[1]['dep']['package'] = $parentname['package'];
$parent[1]['dep']['channel'] = $parentname['channel'];
if ($parent[1]['type'] == 'optional') {
$test = $this->_validatePackageUninstall($parent[1]['dep'], false, $dl);
if ($test !== true) {
$badpackages[$package]['warnings'][] = $test;
}
} else {
$test = $this->_validatePackageUninstall($parent[1]['dep'], true, $dl);
if ($test !== true) {
$badpackages[$package]['errors'][] = $test;
}
}
}
}
$this->_currentPackage = $save;
$dl->___uninstall_package_cache = $badpackages;
if (isset($badpackages[$memyselfandI])) {
if (isset($badpackages[$memyselfandI]['warnings'])) {
foreach ($badpackages[$memyselfandI]['warnings'] as $warning) {
$dl->log(0, $warning[0]);
}
}
if (isset($badpackages[$memyselfandI]['errors'])) {
foreach ($badpackages[$memyselfandI]['errors'] as $error) {
$dl->log(0, $error->getMessage());
}
if (isset($this->_options['nodeps']) || isset($this->_options['force'])) {
return $this->warning(
'warning: %s should not be uninstalled, other installed packages depend ' .
'on this package');
} else {
return $this->raiseError(
'%s cannot be uninstalled, other installed packages depend on this package');
}
}
}
return true;
}
 
function _validatePackageUninstall($dep, $required, $dl)
{
$depname = $this->_registry->parsedPackageNameToString($dep, true);
$version = $this->_registry->packageinfo($dep['package'], 'version',
$dep['channel']);
if (!$version) {
return true;
}
$extra = $this->_getExtraString($dep);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
}
if (isset($dep['conflicts'])) {
return true; // uninstall OK - these packages conflict (probably installed with --force)
}
if (!isset($dep['min']) && !isset($dep['max'])) {
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('"' . $depname . '" is required by ' .
'installed package %s' . $extra);
} else {
return $this->warning('warning: "' . $depname . '" is required by ' .
'installed package %s' . $extra);
}
} else {
return $this->warning('"' . $depname . '" can be optionally used by ' .
'installed package %s' . $extra);
}
}
$fail = false;
if (isset($dep['min'])) {
if (version_compare($version, $dep['min'], '>=')) {
$fail = true;
}
}
if (isset($dep['max'])) {
if (version_compare($version, $dep['max'], '<=')) {
$fail = true;
}
}
// we re-use this variable, preserve the original value
$saverequired = $required;
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError($depname . $extra . ' is required by installed package' .
' "%s"');
} else {
return $this->raiseError('warning: ' . $depname . $extra .
' is required by installed package "%s"');
}
} else {
return $this->warning($depname . $extra . ' can be optionally used by installed package' .
' "%s"');
}
return true;
}
 
/**
* validate a downloaded package against installed packages
*
* As of PEAR 1.4.3, this will only validate
*
* @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2
* $pkg package identifier (either
* array('package' => blah, 'channel' => blah) or an array with
* index 'info' referencing an object)
* @param PEAR_Downloader $dl
* @param array $params full list of packages to install
* @return true|PEAR_Error
*/
function validatePackage($pkg, &$dl, $params = array())
{
if (is_array($pkg) && isset($pkg['info'])) {
$deps = $this->_dependencydb->getDependentPackageDependencies($pkg['info']);
} else {
$deps = $this->_dependencydb->getDependentPackageDependencies($pkg);
}
$fail = false;
if ($deps) {
if (!class_exists('PEAR_Downloader_Package')) {
require_once 'PEAR/Downloader/Package.php';
}
$dp = &new PEAR_Downloader_Package($dl);
if (is_object($pkg)) {
$dp->setPackageFile($pkg);
} else {
$dp->setDownloadURL($pkg);
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
foreach ($deps as $channel => $info) {
foreach ($info as $package => $ds) {
foreach ($params as $packd) {
if (strtolower($packd->getPackage()) == strtolower($package) &&
$packd->getChannel() == $channel) {
$dl->log(3, 'skipping installed package check of "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $channel, 'package' => $package),
true) .
'", version "' . $packd->getVersion() . '" will be ' .
'downloaded and installed');
continue 2; // jump to next package
}
}
foreach ($ds as $d) {
$checker = &new PEAR_Dependency2($this->_config, $this->_options,
array('channel' => $channel, 'package' => $package), $this->_state);
$dep = $d['dep'];
$required = $d['type'] == 'required';
$ret = $checker->_validatePackageDownload($dep, $required, array(&$dp));
if (is_array($ret)) {
$dl->log(0, $ret[0]);
} elseif (PEAR::isError($ret)) {
$dl->log(0, $ret->getMessage());
$fail = true;
}
}
}
}
PEAR::popErrorHandling();
}
if ($fail) {
return $this->raiseError(
'%s cannot be installed, conflicts with installed packages');
}
return true;
}
 
/**
* validate a package.xml 1.0 dependency
*/
function validateDependency1($dep, $params = array())
{
if (!isset($dep['optional'])) {
$dep['optional'] = 'no';
}
list($newdep, $type) = $this->normalizeDep($dep);
if (!$newdep) {
return $this->raiseError("Invalid Dependency");
}
if (method_exists($this, "validate{$type}Dependency")) {
return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no',
$params, true);
}
}
 
/**
* Convert a 1.0 dep into a 2.0 dep
*/
function normalizeDep($dep)
{
$types = array(
'pkg' => 'Package',
'ext' => 'Extension',
'os' => 'Os',
'php' => 'Php'
);
if (isset($types[$dep['type']])) {
$type = $types[$dep['type']];
} else {
return array(false, false);
}
$newdep = array();
switch ($type) {
case 'Package' :
$newdep['channel'] = 'pear.php.net';
case 'Extension' :
case 'Os' :
$newdep['name'] = $dep['name'];
break;
}
$dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']);
switch ($dep['rel']) {
case 'has' :
return array($newdep, $type);
break;
case 'not' :
$newdep['conflicts'] = true;
break;
case '>=' :
case '>' :
$newdep['min'] = $dep['version'];
if ($dep['rel'] == '>') {
$newdep['exclude'] = $dep['version'];
}
break;
case '<=' :
case '<' :
$newdep['max'] = $dep['version'];
if ($dep['rel'] == '<') {
$newdep['exclude'] = $dep['version'];
}
break;
case 'ne' :
case '!=' :
$newdep['min'] = '0';
$newdep['max'] = '100000';
$newdep['exclude'] = $dep['version'];
break;
case '==' :
$newdep['min'] = $dep['version'];
$newdep['max'] = $dep['version'];
break;
}
if ($type == 'Php') {
if (!isset($newdep['min'])) {
$newdep['min'] = '4.2.0';
}
if (!isset($newdep['max'])) {
$newdep['max'] = '6.0.0';
}
}
return array($newdep, $type);
}
 
/**
* Converts text comparing operators to them sign equivalents
*
* Example: 'ge' to '>='
*
* @access public
* @param string Operator
* @return string Sign equivalent
*/
function signOperator($operator)
{
switch($operator) {
case 'lt': return '<';
case 'le': return '<=';
case 'gt': return '>';
case 'ge': return '>=';
case 'eq': return '==';
case 'ne': return '!=';
default:
return $operator;
}
}
 
function raiseError($msg)
{
if (isset($this->_options['ignore-errors'])) {
return $this->warning($msg);
}
return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString(
$this->_currentPackage, true)));
}
 
function warning($msg)
{
return array(sprintf($msg, $this->_registry->parsedPackageNameToString(
$this->_currentPackage, true)));
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFileManager/Cvs.php
New file
0,0 → 1,175
<?php
//
// +------------------------------------------------------------------------+
// | PEAR :: Package File Manager |
// +------------------------------------------------------------------------+
// | Copyright (c) 2003-2004 Gregory Beaver |
// | Email cellog@phpdoc.org |
// +------------------------------------------------------------------------+
// | This source file is subject to version 3.00 of the PHP License, |
// | that is available at http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +------------------------------------------------------------------------+
// | Portions of this code based on phpDocumentor |
// | Web http://www.phpdoc.org |
// | Mirror http://phpdocu.sourceforge.net/ |
// +------------------------------------------------------------------------+
// $Id: Cvs.php,v 1.9 2005/03/25 22:37:15 cellog Exp $
//
/**
* @package PEAR_PackageFileManager
*/
/**
* The PEAR_PackageFileManager_File class
*/
require_once 'PEAR/PackageFileManager/File.php';
 
/**
* Generate a file list from a CVS checkout
*
* Note that this will <b>NOT</b> work on a
* repository, only on a checked out CVS module
* @package PEAR_PackageFileManager
*/
class PEAR_PackageFileManager_CVS extends PEAR_PackageFileManager_File {
/**
* List of CVS-specific files that may exist in CVS but should be
* ignored when building the package's file list.
* @var array
* @access private
*/
var $_cvsIgnore = array('.cvsignore');
 
/**
* Return a list of all files in the CVS repository
*
* This function is like {@link parent::dirList()} except
* that instead of retrieving a regular filelist, it first
* retrieves a listing of all the CVS/Entries files in
* $directory and all of the subdirectories. Then, it
* reads the Entries file, and creates a listing of files
* that are a part of the CVS repository. No check is
* made to see if they have been modified, but newly
* added or removed files are ignored.
* @return array list of files in a directory
* @param string $directory full path to the directory you want the list of
* @uses _recurDirList()
* @uses _readCVSEntries()
*/
function dirList($directory)
{
static $in_recursion = false;
if (!$in_recursion) {
// include only CVS/Entries files
$this->_setupIgnore(array('*/CVS/Entries'), 0);
$this->_setupIgnore(array(), 1);
$in_recursion = true;
$entries = parent::dirList($directory);
$in_recursion = false;
} else {
return parent::dirList($directory);
}
if (!$entries || !is_array($entries)) {
return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_NOCVSENTRIES, $directory);
}
return $this->_readCVSEntries($entries);
}
/**
* Iterate over the CVS Entries files, and retrieve every
* file in the repository
* @uses _getCVSEntries()
* @uses _isCVSFile()
* @param array array of full paths to CVS/Entries files
* @access private
*/
function _readCVSEntries($entries)
{
$ret = array();
$ignore = array_merge((array) $this->_options['ignore'], $this->_cvsIgnore);
// implicitly ignore packagefile
$ignore[] = $this->_options['packagefile'];
$include = $this->_options['include'];
$this->ignore = array(false, false);
$this->_setupIgnore($ignore, 1);
$this->_setupIgnore($include, 0);
foreach($entries as $cvsentry) {
$directory = @dirname(@dirname($cvsentry));
if (!$directory) {
continue;
}
$d = $this->_getCVSEntries($cvsentry);
if (!is_array($d)) {
continue;
}
foreach($d as $entry) {
if ($ignore) {
if ($this->_checkIgnore($this->_getCVSFileName($entry),
$directory . '/' . $this->_getCVSFileName($entry), 1)) {
// print 'Ignoring '.$file."<br>\n";
continue;
}
}
if ($include) {
if ($this->_checkIgnore($this->_getCVSFileName($entry),
$directory . '/' . $this->_getCVSFileName($entry), 0)) {
// print 'Including '.$file."<br\n";
continue;
}
}
if ($this->_isCVSFile($entry)) {
$ret[] = $directory . '/' . $this->_getCVSFileName($entry);
}
}
}
return $ret;
}
/**
* Retrieve the filename from an entry
*
* This method assumes that the entry is a file,
* use _isCVSFile() to verify before calling
* @param string a line in a CVS/Entries file
* @return string the filename (no path information)
* @access private
*/
function _getCVSFileName($cvsentry)
{
$stuff = explode('/', $cvsentry);
array_shift($stuff);
return array_shift($stuff);
}
/**
* Retrieve the entries in a CVS/Entries file
* @return array each line of the entries file, output of file()
* @uses function file()
* @param string full path to a CVS/Entries file
* @access private
*/
function _getCVSEntries($cvsentryfilename)
{
$cvsfile = @file($cvsentryfilename);
if (is_array($cvsfile)) {
return $cvsfile;
} else {
return false;
}
}
/**
* Check whether an entry is a file or a directory
* @return boolean
* @param string a line in a CVS/Entries file
* @access private
*/
function _isCVSFile($cvsentry)
{
// make sure we ignore entries that have either been removed or added, but not committed yet
return $cvsentry{0} == '/' && !strpos($cvsentry, 'dummy timestamp');
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFileManager/File.php
New file
0,0 → 1,421
<?php
//
// +------------------------------------------------------------------------+
// | PEAR :: Package File Manager |
// +------------------------------------------------------------------------+
// | Copyright (c) 2003-2004 Gregory Beaver |
// | Email cellog@phpdoc.org |
// +------------------------------------------------------------------------+
// | This source file is subject to version 3.00 of the PHP License, |
// | that is available at http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +------------------------------------------------------------------------+
// | Portions of this code based on phpDocumentor |
// | Web http://www.phpdoc.org |
// | Mirror http://phpdocu.sourceforge.net/ |
// +------------------------------------------------------------------------+
// $Id: File.php,v 1.21 2005/03/28 06:37:35 cellog Exp $
//
/**
* Retrieve the files from a directory listing
* @package PEAR_PackageFileManager
*/
/**
* Retrieve the files from a directory listing
*
* This class is used to retrieve a raw directory
* listing. Use the {@link PEAR_PackageFileManager_CVS}
* class to only retrieve the contents of a cvs
* repository when generating the package.xml
* @package PEAR_PackageFileManager
*/
class PEAR_PackageFileManager_File {
/**
* @var array
* @access private
*/
var $_options =
array(
);
 
/**
* @access private
* @var PEAR_PackageFileManager
*/
var $_parent;
 
/**
* @access private
* @var array|false
*/
var $_ignore = false;
 
/**
* Set up the File filelist generator
*
* 'ignore' and 'include' are the only options that this class uses. See
* {@link PEAR_PackageFileManager::setOptions()} for
* more information and formatting of this option
* @param PEAR_PackageFileManager
* @param array
*/
function PEAR_PackageFileManager_File(&$parent, $options)
{
$this->_parent = &$parent;
$this->_options = array_merge($this->_options, $options);
}
/**
* Generate the <filelist></filelist> section
* of the package file.
*
* This function performs the backend generation of the array
* containing all files in this package
* @return array
*/
function getFileList()
{
$package_directory = $this->_options['packagedirectory'];
$ignore = $this->_options['ignore'];
// implicitly ignore packagefile
$ignore[] = $this->_options['packagefile'];
if ($this->_options['packagefile'] == 'package.xml') {
// ignore auto-generated package2.xml from PEAR 1.4.0
$ignore[] = 'package2.xml';
}
$include = $this->_options['include'];
$this->ignore = array(false, false);
$this->_setupIgnore($ignore, 1);
$this->_setupIgnore($include, 0);
$allfiles = $this->dirList(substr($package_directory, 0, strlen($package_directory) - 1));
if (PEAR::isError($allfiles)) {
return $allfiles;
}
if (!count($allfiles)) {
return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_NO_FILES,
substr($package_directory, 0, strlen($package_directory) - 1));
}
$struc = array();
foreach($allfiles as $file) {
$path = substr(dirname($file), strlen(str_replace(DIRECTORY_SEPARATOR,
'/',
realpath($package_directory))) + 1);
if (!$path) {
$path = '/';
}
$ext = array_pop(explode('.', $file));
if (strlen($ext) == strlen($file)) {
$ext = '';
}
$struc[$path][] = array('file' => basename($file),
'ext' => $ext,
'path' => (($path == '/') ? basename($file) : $path . '/' . basename($file)),
'fullpath' => $file);
}
if (!count($struc)) {
$newig = implode($this->_options['ignore'], ', ');
return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_IGNORED_EVERYTHING,
substr($package_directory, 0, strlen($package_directory) - 1), $newig);
}
uksort($struc,'strnatcasecmp');
foreach($struc as $key => $ind) {
usort($ind, array($this, 'sortfiles'));
$struc[$key] = $ind;
}
 
$tempstruc = $struc;
if (!isset($tempstruc['/'])) {
$tempstruc['/'] = array();
}
$struc = array('/' => $tempstruc['/']);
$bv = 0;
foreach($tempstruc as $key => $ind) {
$save = $key;
if ($key != '/')
{
$struc['/'] = $this->_setupDirs($struc['/'], explode('/',$key), $tempstruc[$key]);
}
}
uksort($struc['/'], array($this, 'mystrucsort'));
 
return $struc;
}
/**
* Retrieve a listing of every file in $directory and
* all subdirectories.
*
* The return format is an array of full paths to files
* @access protected
* @return array list of files in a directory
* @param string $directory full path to the directory you want the list of
* @throws PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST
*/
function dirList($directory)
{
$ret = false;
if (@is_dir($directory)) {
$ret = array();
$d = @dir($directory); // thanks to Jason E Sweat (jsweat@users.sourceforge.net) for fix
while($d && false !== ($entry=$d->read())) {
if ($this->_testFile($directory, $entry)) {
if (is_file($directory . '/' . $entry)) {
// if include option was set, then only pass included files
if ($this->ignore[0]) {
if ($this->_checkIgnore($entry, $directory . '/' . $entry, 0)) {
continue;
}
}
// if ignore option was set, then only pass included files
if ($this->ignore[1]) {
if ($this->_checkIgnore($entry, $directory . '/' . $entry, 1)) {
continue;
}
}
$ret[] = $directory . '/' . $entry;
}
if (is_dir($directory . '/' . $entry)) {
$tmp = $this->dirList($directory . '/' . $entry);
if (is_array($tmp)) {
foreach($tmp as $ent) {
$ret[] = $ent;
}
}
}
}
}
if ($d) {
$d->close();
}
} else {
return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST, $directory);
}
return $ret;
}
/**
* Test whether an entry should be processed.
*
* Normally, it ignores all files and directories that begin with "." addhiddenfiles option
* instead only ignores "." and ".." entries
* @access private
* @param string directory name of entry
* @param string name
*/
function _testFile($directory, $entry)
{
if ($this->_options['addhiddenfiles']) {
return is_file($directory . '/' . $entry) || (is_dir($directory . '/' . $entry) && !in_array($entry, array('.', '..')));
} else {
return $entry{0} != '.';
}
}
 
/**
* Tell whether to ignore a file or a directory
* allows * and ? wildcards
*
* @param string $file just the file name of the file or directory,
* in the case of directories this is the last dir
* @param string $path the full path
* @param 1|0 $return value to return if regexp matches. Set this to
* false to include only matches, true to exclude
* all matches
* @return bool true if $path should be ignored, false if it should not
* @access private
*/
function _checkIgnore($file, $path, $return = 1)
{
if (file_exists($path)) {
$path = realpath($path);
}
if (is_array($this->ignore[$return])) {
foreach($this->ignore[$return] as $match) {
// match is an array if the ignore parameter was a /path/to/pattern
if (is_array($match)) {
// check to see if the path matches with a path delimiter appended
preg_match('/^' . strtoupper($match[0]).'$/', strtoupper($path) . '/',$find);
if (!count($find)) {
// check to see if it matches without an appended path delimiter
preg_match('/^' . strtoupper($match[0]).'$/', strtoupper($path), $find);
}
if (count($find)) {
// check to see if the file matches the file portion of the regex string
preg_match('/^' . strtoupper($match[1]).'$/', strtoupper($file), $find);
if (count($find)) {
return $return;
}
}
// check to see if the full path matches the regex
preg_match('/^' . strtoupper($match[0]).'$/',
strtoupper($path . DIRECTORY_SEPARATOR . $file), $find);
if (count($find)) {
return $return;
}
} else {
// ignore parameter was just a pattern with no path delimiters
// check it against the path
preg_match('/^' . strtoupper($match).'$/', strtoupper($path), $find);
if (count($find)) {
return $return;
}
// check it against the file only
preg_match('/^' . strtoupper($match).'$/', strtoupper($file), $find);
if (count($find)) {
return $return;
}
}
}
}
return !$return;
}
/**
* Construct the {@link $ignore} array
* @param array strings of files/paths/wildcards to ignore
* @param 0|1 0 = files to include, 1 = files to ignore
* @access private
*/
function _setupIgnore($ignore, $index)
{
$ig = array();
if (is_array($ignore)) {
for($i=0; $i<count($ignore);$i++) {
$ignore[$i] = strtr($ignore[$i], "\\", "/");
$ignore[$i] = str_replace('//','/',$ignore[$i]);
 
if (!empty($ignore[$i])) {
if (!is_numeric(strpos($ignore[$i], '/'))) {
$ig[] = $this->_getRegExpableSearchString($ignore[$i]);
} else {
if (basename($ignore[$i]) . '/' == $ignore[$i]) {
$ig[] = $this->_getRegExpableSearchString($ignore[$i]);
} else {
$ig[] = array($this->_getRegExpableSearchString($ignore[$i]),
$this->_getRegExpableSearchString(basename($ignore[$i])));
}
}
}
}
if (count($ig)) {
$this->ignore[$index] = $ig;
} else {
$this->ignore[$index] = false;
}
} else $this->ignore[$index] = false;
}
/**
* Converts $s into a string that can be used with preg_match
* @param string $s string with wildcards ? and *
* @return string converts * to .*, ? to ., etc.
* @access private
*/
function _getRegExpableSearchString($s)
{
$y = '\/';
if (DIRECTORY_SEPARATOR == '\\') {
$y = '\\\\';
}
$s = str_replace('/', DIRECTORY_SEPARATOR, $s);
$x = strtr($s, array('?' => '.','*' => '.*','.' => '\\.','\\' => '\\\\','/' => '\\/',
'[' => '\\[',']' => '\\]','-' => '\\-'));
if (strpos($s, DIRECTORY_SEPARATOR) !== false &&
strrpos($s, DIRECTORY_SEPARATOR) === strlen($s) - 1) {
$x = "(?:.*$y$x?.*|$x.*)";
}
return $x;
}
/**
* Recursively move contents of $struc into associative array
*
* The contents of $struc have many indexes like 'dir/subdir/subdir2'.
* This function converts them to
* array('dir' => array('subdir' => array('subdir2')))
* @param array struc is array('dir' => array of files in dir,
* 'dir/subdir' => array of files in dir/subdir,...)
* @param array array form of 'dir/subdir/subdir2' array('dir','subdir','subdir2')
* @return array same as struc but with array('dir' =>
* array(file1,file2,'subdir' => array(file1,...)))
* @access private
*/
function _setupDirs($struc, $dir, $contents)
{
if (!count($dir)) {
foreach($contents as $dir => $files) {
if (is_string($dir)) {
if (strpos($dir, '/')) {
$test = true;
$a = $contents[$dir];
unset($contents[$dir]);
$b = explode('/', $dir);
$c = array_shift($b);
if (isset($contents[$c])) {
$contents[$c] = $this->_setDir($contents[$c], $this->_setupDirs(array(), $b, $a));
} else {
$contents[$c] = $this->_setupDirs(array(), $b, $a);
}
}
}
}
return $contents;
}
$me = array_shift($dir);
if (!isset($struc[$me])) {
$struc[$me] = array();
}
$struc[$me] = $this->_setupDirs($struc[$me], $dir, $contents);
return $struc;
}
 
/**
* Recursively add all the subdirectories of $contents to $dir without erasing anything in
* $dir
* @param array
* @param array
* @return array processed $dir
* @access private
*/
function _setDir($dir, $contents)
{
while(list($one,$two) = each($contents)) {
if (isset($dir[$one])) {
$dir[$one] = $this->_setDir($dir[$one], $contents[$one]);
} else {
$dir[$one] = $two;
}
}
return $dir;
}
 
/**#@+
* Sorting functions for the file list
* @param string
* @param string
* @access private
*/
function sortfiles($a, $b)
{
return strnatcasecmp($a['file'],$b['file']);
}
function mystrucsort($a, $b)
{
if (is_numeric($a) && is_string($b)) return 1;
if (is_numeric($b) && is_string($a)) return -1;
if (is_numeric($a) && is_numeric($b))
{
if ($a > $b) return 1;
if ($a < $b) return -1;
if ($a == $b) return 0;
}
return strnatcasecmp($a,$b);
}
/**#@-*/
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFileManager/SimpleGenerator.php
New file
0,0 → 1,323
<?php
//
// +------------------------------------------------------------------------+
// | PEAR :: Package File Manager |
// +------------------------------------------------------------------------+
// | Copyright (c) 2004 Gregory Beaver |
// | Email cellog@phpdoc.org |
// +------------------------------------------------------------------------+
// | This source file is subject to version 3.00 of the PHP License, |
// | that is available at http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +------------------------------------------------------------------------+
// | Portions of this code based on phpDocumentor |
// | Web http://www.phpdoc.org |
// | Mirror http://phpdocu.sourceforge.net/ |
// +------------------------------------------------------------------------+
// $Id: SimpleGenerator.php,v 1.4 2005/05/20 22:42:59 cellog Exp $
//
 
require_once 'PEAR/PackageFile/Generator/v1.php';
/**
* Class for XML output
*
* @author Greg Beaver <cellog@php.net>
* @since 1.2.0
* @copyright 2003
* @package PEAR_PackageFileManager
*/
class PEAR_PackageFileManager_SimpleGenerator extends PEAR_PackageFile_Generator_v1
{
var $_options;
 
/**
* remove a warning about missing parameters - don't delete this
*/
function PEAR_PackageFileManager_SimpleGenerator()
{
}
 
/**
* @param array
*/
function setPackageFileManagerOptions($opts)
{
$this->_options = $opts;
}
 
/**
* Return an XML document based on the package info (as returned
* by the PEAR_Common::infoFrom* methods).
*
* @param array $pkginfo package info
*
* @return string XML data
*
* @access public
* @deprecated use a PEAR_PackageFile_v* object's generator instead
*/
function xmlFromInfo($pkginfo)
{
include_once 'PEAR/PackageFile.php';
include_once 'PEAR/Config.php';
$config = &PEAR_Config::singleton();
$packagefile = &new PEAR_PackageFile($config);
$pf = &$packagefile->fromArray($pkginfo);
parent::PEAR_PackageFile_Generator_v1($pf);
return $this->toXml();
}
 
function getFileRoles()
{
return PEAR_Common::getFileRoles();
}
 
function getReplacementTypes()
{
return PEAR_Common::getReplacementTypes();
}
 
/**
* Validate XML package definition file.
*
* @param string $info Filename of the package archive or of the
* package definition file
* @param array $errors Array that will contain the errors
* @param array $warnings Array that will contain the warnings
* @param string $dir_prefix (optional) directory where source files
* may be found, or empty if they are not available
* @access public
* @return boolean
* @deprecated use the validation of PEAR_PackageFile objects
*/
function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '')
{
include_once 'PEAR/PackageFile.php';
include_once 'PEAR/Config.php';
$config = &PEAR_Config::singleton();
$packagefile = &new PEAR_PackageFile($config);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (is_array($info)) {
$pf = &$packagefile->fromArray($info);
if (!$pf->validate(PEAR_VALIDATE_NORMAL)) {
foreach ($pf->getValidationWarnings() as $err) {
if ($error['level'] == 'error') {
$errors[] = $error['message'];
} else {
$warnings[] = $error['message'];
}
}
return false;
}
} else {
$pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL);
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
if ($error['level'] == 'error') {
$errors[] = $error['message'];
} else {
$warnings[] = $error['message'];
}
}
}
return false;
}
return true;
}
 
/**
* @param array
* @access protected
*/
function recursiveXmlFilelist($list)
{
$this->_dirs = array();
foreach ($list as $file => $attributes) {
$this->_addDir($this->_dirs, explode('/', dirname($file)), $file, $attributes);
}
if (!isset($this->_dirs['dirs'])) {
$this->_dirs['dirs'] = array();
}
if (count($this->_dirs['dirs']) != 1 || isset($this->_dirs['files'])) {
$this->_dirs = array('dirs' => array('/' => $this->_dirs));
}
return $this->_formatDir($this->_dirs, '', '', true);
}
 
/**
* @param array
* @param array
* @param string|null
* @param array|null
* @access private
*/
function _addDir(&$dirs, $dir, $file = null, $attributes = null)
{
if ($dir == array() || $dir == array('.')) {
$dirs['files'][basename($file)] = $attributes;
return;
}
$curdir = array_shift($dir);
if (!isset($dirs['dirs'][$curdir])) {
$dirs['dirs'][$curdir] = array();
}
$this->_addDir($dirs['dirs'][$curdir], $dir, $file, $attributes);
}
 
/**
* @param array
* @param string
* @param string
* @access private
*/
function _formatDir($dirs, $indent = '', $curdir = '', $toplevel = false)
{
$ret = '';
if (!count($dirs)) {
return '';
}
if (isset($dirs['dirs'])) {
uksort($dirs['dirs'], 'strnatcasecmp');
foreach ($dirs['dirs'] as $dir => $contents) {
if ($dir == '/') {
$usedir = '/';
} else {
if ($curdir == '/') {
$curdir = '';
}
$usedir = "$curdir/$dir";
}
$ret .= "$indent <dir name=\"$dir\"";
if ($toplevel) {
$ret .= ' baseinstalldir="' . $this->_options['baseinstalldir'] . '"';
} else {
if (isset($this->_options['installexceptions'][$dir])) {
$ret .= ' baseinstalldir="' . $this->_options['installexceptions'][$dir] . '"';
}
}
$ret .= ">\n";
$ret .= $this->_formatDir($contents, "$indent ", $usedir);
$ret .= "$indent </dir> <!-- $usedir -->\n";
}
}
if (isset($dirs['files'])) {
uksort($dirs['files'], 'strnatcasecmp');
foreach ($dirs['files'] as $file => $attribs) {
$ret .= $this->_formatFile($file, $attribs, $indent);
}
}
return $ret;
}
 
/**
* @param string
* @param array
* @param string
* @access private
*/
function _formatFile($file, $attributes, $indent)
{
$ret = "$indent <file role=\"$attributes[role]\"";
if (isset($this->_options['installexceptions'][$file])) {
$ret .= ' baseinstalldir="' . $this->_options['installexceptions'][$file] . '"';
}
if (isset($attributes['md5sum'])) {
$ret .= " md5sum=\"$attributes[md5sum]\"";
}
if (isset($attributes['platform'])) {
$ret .= " platform=\"$attributes[platform]\"";
}
if (!empty($attributes['install-as'])) {
$ret .= ' install-as="' .
htmlspecialchars($attributes['install-as']) . '"';
}
$ret .= ' name="' . htmlspecialchars($file) . '"';
if (empty($attributes['replacements'])) {
$ret .= "/>\n";
} else {
$ret .= ">\n";
foreach ($attributes['replacements'] as $r) {
$ret .= "$indent <replace";
foreach ($r as $k => $v) {
$ret .= " $k=\"" . htmlspecialchars($v) .'"';
}
$ret .= "/>\n";
}
$ret .= "$indent </file>\n";
}
return $ret;
}
 
/**
* Generate the <filelist> tag
* @access private
* @return string
*/
function _doFileList($indent, $filelist, $curdir)
{
$ret = '';
foreach ($filelist as $file => $fa) {
if (isset($fa['##files'])) {
$ret .= "$indent <dir";
} else {
$ret .= "$indent <file";
}
 
if (isset($fa['role'])) {
$ret .= " role=\"$fa[role]\"";
}
if (isset($fa['baseinstalldir'])) {
$ret .= ' baseinstalldir="' .
htmlspecialchars($fa['baseinstalldir']) . '"';
}
if (isset($fa['md5sum'])) {
$ret .= " md5sum=\"$fa[md5sum]\"";
}
if (isset($fa['platform'])) {
$ret .= " platform=\"$fa[platform]\"";
}
if (!empty($fa['install-as'])) {
$ret .= ' install-as="' .
htmlspecialchars($fa['install-as']) . '"';
}
$ret .= ' name="' . htmlspecialchars($file) . '"';
if (isset($fa['##files'])) {
$ret .= ">\n";
$recurdir = $curdir;
if ($recurdir == '///') {
$recurdir = '';
}
$ret .= $this->_doFileList("$indent ", $fa['##files'], $recurdir . $file . '/');
$displaydir = $curdir;
if ($displaydir == '///' || $displaydir == '/') {
$displaydir = '';
}
$ret .= "$indent </dir> <!-- $displaydir$file -->\n";
} else {
if (empty($fa['replacements'])) {
$ret .= "/>\n";
} else {
$ret .= ">\n";
foreach ($fa['replacements'] as $r) {
$ret .= "$indent <replace";
foreach ($r as $k => $v) {
$ret .= " $k=\"" . htmlspecialchars($v) .'"';
}
$ret .= "/>\n";
}
$ret .= "$indent </file>\n";
}
}
}
return $ret;
}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFileManager/XMLOutput.php
New file
0,0 → 1,180
<?php
//
// +------------------------------------------------------------------------+
// | PEAR :: Package File Manager |
// +------------------------------------------------------------------------+
// | Copyright (c) 2004 Gregory Beaver |
// | Email cellog@phpdoc.org |
// +------------------------------------------------------------------------+
// | This source file is subject to version 3.00 of the PHP License, |
// | that is available at http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +------------------------------------------------------------------------+
// | Portions of this code based on phpDocumentor |
// | Web http://www.phpdoc.org |
// | Mirror http://phpdocu.sourceforge.net/ |
// +------------------------------------------------------------------------+
// $Id: XMLOutput.php,v 1.4 2004/02/07 18:04:00 cellog Exp $
//
 
/**
* Class for XML output
*
* @author Greg Beaver <cellog@php.net>
* @since 1.2.0
* @copyright 2003
* @package PEAR_PackageFileManager
*/
class PEAR_PackageFileManager_XMLOutput extends PEAR_Common {
 
/**
* Generate part of an XML description with release information.
*
* @param array $pkginfo array with release information
* @param bool $changelog whether the result will be in a changelog element
*
* @return string XML data
*
* @access private
*/
function _makeReleaseXml($pkginfo, $changelog = false)
{
$indent = $changelog ? " " : "";
$ret = "$indent <release>\n";
if (!empty($pkginfo['version'])) {
$ret .= "$indent <version>$pkginfo[version]</version>\n";
}
if (!empty($pkginfo['release_date'])) {
$ret .= "$indent <date>$pkginfo[release_date]</date>\n";
}
if (!empty($pkginfo['release_license'])) {
$ret .= "$indent <license>$pkginfo[release_license]</license>\n";
}
if (!empty($pkginfo['release_state'])) {
$ret .= "$indent <state>$pkginfo[release_state]</state>\n";
}
if (!empty($pkginfo['release_notes'])) {
$ret .= "$indent <notes>".htmlspecialchars($pkginfo['release_notes'])."</notes>\n";
}
if (!empty($pkginfo['release_warnings'])) {
$ret .= "$indent <warnings>".htmlspecialchars($pkginfo['release_warnings'])."</warnings>\n";
}
if (isset($pkginfo['release_deps']) && sizeof($pkginfo['release_deps']) > 0) {
$ret .= "$indent <deps>\n";
foreach ($pkginfo['release_deps'] as $dep) {
$ret .= "$indent <dep type=\"$dep[type]\" rel=\"$dep[rel]\"";
if (isset($dep['version'])) {
$ret .= " version=\"$dep[version]\"";
}
if (isset($dep['optional'])) {
$ret .= " optional=\"$dep[optional]\"";
}
if (isset($dep['name'])) {
$ret .= ">$dep[name]</dep>\n";
} else {
$ret .= "/>\n";
}
}
$ret .= "$indent </deps>\n";
}
if (isset($pkginfo['configure_options'])) {
$ret .= "$indent <configureoptions>\n";
foreach ($pkginfo['configure_options'] as $c) {
$ret .= "$indent <configureoption name=\"".
htmlspecialchars($c['name']) . "\"";
if (isset($c['default'])) {
$ret .= " default=\"" . htmlspecialchars($c['default']) . "\"";
}
$ret .= " prompt=\"" . htmlspecialchars($c['prompt']) . "\"";
$ret .= "/>\n";
}
$ret .= "$indent </configureoptions>\n";
}
if (isset($pkginfo['provides'])) {
foreach ($pkginfo['provides'] as $key => $what) {
$ret .= "$indent <provides type=\"$what[type]\" ";
$ret .= "name=\"$what[name]\" ";
if (isset($what['extends'])) {
$ret .= "extends=\"$what[extends]\" ";
}
$ret .= "/>\n";
}
}
if (isset($pkginfo['filelist'])) {
$ret .= "$indent <filelist>\n";
$ret .= $this->_doFileList($indent, $pkginfo['filelist'], '/');
$ret .= "$indent </filelist>\n";
}
$ret .= "$indent </release>\n";
return $ret;
}
 
/**
* Generate the <filelist> tag
* @access private
* @return string
*/
function _doFileList($indent, $filelist, $curdir)
{
$ret = '';
foreach ($filelist as $file => $fa) {
if (isset($fa['##files'])) {
$ret .= "$indent <dir";
} else {
$ret .= "$indent <file";
}
 
if (isset($fa['role'])) {
$ret .= " role=\"$fa[role]\"";
}
if (isset($fa['baseinstalldir'])) {
$ret .= ' baseinstalldir="' .
htmlspecialchars($fa['baseinstalldir']) . '"';
}
if (isset($fa['md5sum'])) {
$ret .= " md5sum=\"$fa[md5sum]\"";
}
if (isset($fa['platform'])) {
$ret .= " platform=\"$fa[platform]\"";
}
if (!empty($fa['install-as'])) {
$ret .= ' install-as="' .
htmlspecialchars($fa['install-as']) . '"';
}
$ret .= ' name="' . htmlspecialchars($file) . '"';
if (isset($fa['##files'])) {
$ret .= ">\n";
$recurdir = $curdir;
if ($recurdir == '///') {
$recurdir = '';
}
$ret .= $this->_doFileList("$indent ", $fa['##files'], $recurdir . $file . '/');
$displaydir = $curdir;
if ($displaydir == '///' || $displaydir == '/') {
$displaydir = '';
}
$ret .= "$indent </dir> <!-- $displaydir$file -->\n";
} else {
if (empty($fa['replacements'])) {
$ret .= "/>\n";
} else {
$ret .= ">\n";
foreach ($fa['replacements'] as $r) {
$ret .= "$indent <replace";
foreach ($r as $k => $v) {
$ret .= " $k=\"" . htmlspecialchars($v) .'"';
}
$ret .= "/>\n";
}
$ret .= "$indent </file>\n";
}
}
}
return $ret;
}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFileManager/Perforce.php
New file
0,0 → 1,102
<?php
/*
* +------------------------------------------------------------------------+
* | PEAR :: Package File Manager :: Perforce |
* +------------------------------------------------------------------------+
* | Copyright (c) 2004 Jon Parise |
* | Email jon@php.net |
* +------------------------------------------------------------------------+
* | This source file is subject to version 3.00 of the PHP License, |
* | that is available at http://www.php.net/license/3_0.txt. |
* | If you did not receive a copy of the PHP license and are unable to |
* | obtain it through the world-wide-web, please send a note to |
* | license@php.net so we can mail you a copy immediately. |
* +------------------------------------------------------------------------+
* $Id: Perforce.php,v 1.2 2004/08/25 06:02:30 jon Exp $
*/
 
/**
* @package PEAR_PackageFileManager
*/
 
/**
* The PEAR_PackageFileManager_File class
*/
require_once 'PEAR/PackageFileManager/File.php';
 
/**
* Generate a file list from a Perforce checkout. This requires the 'p4'
* command line client, a properly-configured Perforce environment, and a
* connection to the Perforce server. Specifically, the 'p4 have' command
* is used to determine which local files are under Perforce's control.
*
* @author Jon Parise <jon@php.net>
* @package PEAR_PackageFileManager
*/
class PEAR_PackageFileManager_Perforce extends PEAR_PackageFileManager_File
{
/**
* Build a list of files based on the output of the 'p4 have' command.
*
* @param string $directory The directory in which to list the files.
*
* @return mixed An array of full filenames or a PEAR_Error value if
* $directory does not exist.
*/
function dirList($directory)
{
/* Return an error if the directory does not exist. */
if (@is_dir($directory) === false) {
return PEAR_PackageFileManager::raiseError(
PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST,
$directory);
}
 
/* List the files below $directory that are under Perforce control. */
exec("p4 have $directory/...", $output);
 
/* Strip off everything except the filename from each line of output. */
$files = preg_replace('/^.* \- /', '', $output);
 
/* If we have a list of files to include, remove all other entries. */
if ($this->ignore[0]) {
$files = array_filter($files, array($this, '_includeFilter'));
}
 
/* If we have a list of files to ignore, remove them from the array. */
if ($this->ignore[1]) {
$files = array_filter($files, array($this, '_ignoreFilter'));
}
 
return $files;
}
 
/**
* Determine whether a given file should be excluded from the file list.
*
* @param string $file The full pathname of file to check.
*
* @return bool True if the specified file should be included.
*
* @access private
*/
function _includeFilter($file)
{
return ($this->_checkIgnore(basename($file), $file, 0) === 0);
}
 
/**
* Determine whether a given file should be included (i.e., not ignored)
* from the file list.
*
* @param string $file The full pathname of file to check.
*
* @return bool True if the specified file should be included.
*
* @access private
*/
function _ignoreFilter($file)
{
return ($this->_checkIgnore(basename($file), $file, 1) !== 1);
}
}
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFileManager/Svn.php
New file
0,0 → 1,169
<?php
//
// +------------------------------------------------------------------------+
// | PEAR :: Package File Manager |
// +------------------------------------------------------------------------+
// | Copyright (c) 2003-2004 Gregory Beaver |
// | Email cellog@phpdoc.org |
// +------------------------------------------------------------------------+
// | This source file is subject to version 3.00 of the PHP License, |
// | that is available at http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +------------------------------------------------------------------------+
// | Portions of this code based on phpDocumentor |
// | Web http://www.phpdoc.org |
// | Mirror http://phpdocu.sourceforge.net/ |
// +------------------------------------------------------------------------+
// $Id: Svn.php,v 1.1 2004/05/31 12:02:31 arnaud Exp $
//
/**
* @package PEAR_PackageFileManager
*/
/**
* The PEAR_PackageFileManager_File class
*/
require_once 'PEAR/PackageFileManager/File.php';
 
/**
* Generate a file list from a Subversion checkout
*
* Largely based on the CVS class, modified to suit
* subversion organization.
*
* Note that this will <b>NOT</b> work on a
* repository, only on a checked out Subversion module
* @package PEAR_PackageFileManager
* @author Arnaud Limbour <arnaud@limbourg.com>
*/
class PEAR_PackageFileManager_Svn extends PEAR_PackageFileManager_File
{
/**
* Return a list of all files in the CVS repository
*
* This function is like {@link parent::dirList()} except
* that instead of retrieving a regular filelist, it first
* retrieves a listing of all the .svn/entries files in
* $directory and all of the subdirectories. Then, it
* reads the entries file, and creates a listing of files
* that are a part of the Subversion checkout. No check is
* made to see if they have been modified, but removed files
* are ignored.
*
* @access protected
* @return array list of files in a directory
* @param string $directory full path to the directory you want the list of
* @uses _recurDirList()
* @uses _readSVNEntries()
*/
function dirList($directory)
{
static $in_recursion = false;
if (!$in_recursion) {
// include only .svn/entries files
// since subversion keeps its data in a hidden
// directory we must force PackageFileManager to
// consider hidden directories.
$this->_options['addhiddenfiles'] = true;
$this->_setupIgnore(array('*/.svn/entries'), 0);
$this->_setupIgnore(array(), 1);
$in_recursion = true;
$entries = parent::dirList($directory);
$in_recursion = false;
} else {
return parent::dirList($directory);
}
if (!$entries || !is_array($entries)) {
return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_NOSVNENTRIES, $directory);
}
return $this->_readSVNEntries($entries);
}
/**
* Iterate over the SVN Entries files, and retrieve every
* file in the repository
*
* @uses _getSVNEntries()
* @param array array of full paths to .svn/entries files
* @access private
*/
function _readSVNEntries($entries)
{
$ret = array();
$ignore = $this->_options['ignore'];
// implicitly ignore packagefile
$ignore[] = $this->_options['packagefile'];
$include = $this->_options['include'];
$this->ignore = array(false, false);
$this->_setupIgnore($ignore, 1);
$this->_setupIgnore($include, 0);
foreach($entries as $cvsentry) {
$directory = @dirname(@dirname($cvsentry));
if (!$directory) {
continue;
}
$d = $this->_getSVNEntries($cvsentry);
if (!is_array($d)) {
continue;
}
foreach($d as $entry) {
if ($ignore) {
if ($this->_checkIgnore($entry,
$directory . '/' . $entry, 1)) {
continue;
}
}
if ($include) {
if ($this->_checkIgnore($entry,
$directory . '/' . $entry, 0)) {
continue;
}
}
$ret[] = $directory . '/' . $entry;
}
}
return $ret;
}
/**
* Retrieve the entries in a .svn/entries file
*
* Uses XML_Tree to parse the XML subversion file
*
* It keeps only files, excluding directories. It also
* makes sure no deleted file in included.
*
* @return array an array with full paths to files
* @uses PEAR::XML_Tree
* @param string full path to a .svn/entries file
* @access private
*/
function _getSVNEntries($svnentriesfilename)
{
require_once 'XML/Tree.php';
$parser = &new XML_Tree($svnentriesfilename);
$tree = &$parser->getTreeFromFile();
 
// loop through the xml tree and keep only valid entries being files
$entries = array();
foreach ($tree->children as $entry) {
if ($entry->name == 'entry'
&& $entry->attributes['kind'] == 'file') {
if (isset($entry->attributes['deleted'])) {
continue;
}
array_push($entries, $entry->attributes['name']);
}
}
 
unset($parser, $tree);
 
if (is_array($entries)) {
return $entries;
} else {
return false;
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/RunTest.php
New file
0,0 → 1,775
<?php
/**
* PEAR_RunTest
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: RunTest.php,v 1.34 2007/02/17 19:57:56 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.3.3
*/
 
/**
* for error handling
*/
require_once 'PEAR.php';
require_once 'PEAR/Config.php';
 
define('DETAILED', 1);
putenv("PHP_PEAR_RUNTESTS=1");
 
/**
* Simplified version of PHP's test suite
*
* Try it with:
*
* $ php -r 'include "../PEAR/RunTest.php"; $t=new PEAR_RunTest; $o=$t->run("./pear_system.phpt");print_r($o);'
*
*
* @category pear
* @package PEAR
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.3.3
*/
class PEAR_RunTest
{
var $_logger;
var $_options;
var $ini_overwrites = array(
'output_handler=',
'open_basedir=',
'safe_mode=0',
'disable_functions=',
'output_buffering=Off',
'error_reporting=E_ALL',
'display_errors=1',
'log_errors=0',
'html_errors=0',
'track_errors=1',
'report_memleaks=1',
'report_zend_debug=0',
'docref_root=',
'docref_ext=.html',
'error_prepend_string=',
'error_append_string=',
'auto_prepend_file=',
'auto_append_file=',
'magic_quotes_runtime=0',
);
 
 
/**
* An object that supports the PEAR_Common->log() signature, or null
* @param PEAR_Common|null
*/
function PEAR_RunTest($logger = null, $options = array())
{
if (is_null($logger)) {
require_once 'PEAR/Common.php';
$logger = new PEAR_Common;
}
$this->_logger = $logger;
$this->_options = $options;
}
 
/**
* Taken from php-src/run-tests.php
*
* @param string $commandline command name
* @param array $env
* @param string $stdin standard input to pass to the command
* @return unknown
*/
function system_with_timeout($commandline, $env = null, $stdin = null)
{
$data = '';
 
if (version_compare(phpversion(), '5.0.0', '<')) {
$proc = proc_open($commandline, array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
), $pipes);
} else {
$proc = proc_open($commandline, array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
), $pipes, null, $env, array("suppress_errors" => true));
}
if (!$proc) {
return false;
}
if (is_string($stdin)) {
fwrite($pipes[0], $stdin);
}
fclose($pipes[0]);
while (true) {
/* hide errors from interrupted syscalls */
$r = $pipes;
$w = null;
$e = null;
$n = @stream_select($r, $w, $e, 60);
if ($n === 0) {
/* timed out */
$data .= "\n ** ERROR: process timed out **\n";
proc_terminate($proc);
return array(1234567890, $data);
} else if ($n > 0) {
$line = fread($pipes[1], 8192);
if (strlen($line) == 0) {
/* EOF */
break;
}
$data .= $line;
}
}
if (function_exists('proc_get_status')) {
$stat = proc_get_status($proc);
if ($stat['signaled']) {
$data .= "\nTermsig=".$stat['stopsig'];
}
}
$code = proc_close($proc);
if (function_exists('proc_get_status')) {
$code = $stat['exitcode'];
}
return array($code, $data);
}
 
function settings2array($settings, $ini_settings)
{
foreach ($settings as $setting) {
if (strpos($setting, '=')!==false) {
$setting = explode("=", $setting, 2);
$name = trim(strtolower($setting[0]));
$value = trim($setting[1]);
$ini_settings[$name] = $value;
}
}
return $ini_settings;
}
function settings2params($ini_settings)
{
$settings = '';
foreach ($ini_settings as $name => $value) {
$value = addslashes($value);
$settings .= " -d \"$name=$value\"";
}
return $settings;
}
 
//
// Run an individual test case.
//
 
function run($file, $ini_settings = '')
{
$cwd = getcwd();
$conf = &PEAR_Config::singleton();
$php = $conf->get('php_bin');
if (isset($this->_options['phpunit'])) {
$cmd = "$php$ini_settings -f $file";
if (isset($this->_logger)) {
$this->_logger->log(2, 'Running command "' . $cmd . '"');
}
$savedir = getcwd(); // in case the test moves us around
chdir(dirname($file));
echo `$cmd`;
chdir($savedir);
return 'PASSED'; // we have no way of knowing this information so assume passing
}
$pass_options = '';
if (!empty($this->_options['ini'])) {
$pass_options = $this->_options['ini'];
}
 
$info_params = '';
$log_format = 'LEOD';
 
// Load the sections of the test file.
$section_text = array(
'TEST' => '(unnamed test)',
'SKIPIF' => '',
'GET' => '',
'COOKIE' => '',
'POST' => '',
'ARGS' => '',
'INI' => '',
'CLEAN' => '',
);
 
$file = realpath($file);
if (!is_file($file) || !$fp = fopen($file, "r")) {
return PEAR::raiseError("Cannot open test file: $file");
}
 
$section = '';
while (!feof($fp)) {
$line = fgets($fp);
 
// Match the beginning of a section.
if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
$section = $r[1];
$section_text[$section] = '';
continue;
} elseif (empty($section)) {
fclose($fp);
return PEAR::raiseError("Invalid sections formats in test file: $file");
}
 
// Add to the section text.
$section_text[$section] .= $line;
}
fclose($fp);
 
if (isset($section_text['POST_RAW']) && isset($section_text['UPLOAD'])) {
return PEAR::raiseError("Cannot contain both POST_RAW and UPLOAD in test file: $file");
}
$ini_settings = array();
$ini_settings = $this->settings2array($this->ini_overwrites, $ini_settings);
if ($section_text['INI']) {
if (strpos($section_text['INI'], '{PWD}') !== false) {
$section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']);
}
$ini_settings = $this->settings2array(preg_split( "/[\n\r]+/",
$section_text['INI']), $ini_settings);
}
$ini_settings = $this->settings2params($ini_settings);
$shortname = str_replace($cwd . DIRECTORY_SEPARATOR, '', $file);
if (!isset($this->_options['simple'])) {
$tested = trim($section_text['TEST']) . "[$shortname]";
} else {
$tested = trim($section_text['TEST']) . ' ';
}
if (!empty($section_text['GET']) || !empty($section_text['POST']) ||
!empty($section_text['POST_RAW']) || !empty($section_text['COOKIE']) ||
!empty($section_text['UPLOAD'])) {
if (empty($this->_options['cgi'])) {
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, "SKIP $tested (reason: --cgi option needed for this test, type 'pear help run-tests')");
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' # skip --cgi option needed for this test, "pear help run-tests" for info');
}
return 'SKIPPED';
}
$php = $this->_options['cgi'];
}
 
$temp_dir = $test_dir = realpath(dirname($file));
$main_file_name = basename($file,'phpt');
$diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'diff';
$log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'log';
$exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'exp';
$output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'out';
$memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'mem';
$temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'php';
$test_file = $test_dir . DIRECTORY_SEPARATOR . $main_file_name.'php';
$temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php';
$test_skipif = $test_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php';
$temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php';
$test_clean = $test_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php';
$tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.');
 
// unlink old test results
@unlink($diff_filename);
@unlink($log_filename);
@unlink($exp_filename);
@unlink($output_filename);
@unlink($memcheck_filename);
@unlink($temp_file);
@unlink($test_file);
@unlink($temp_skipif);
@unlink($test_skipif);
@unlink($tmp_post);
@unlink($temp_clean);
@unlink($test_clean);
 
// Check if test should be skipped.
$info = '';
$warn = false;
if (array_key_exists('SKIPIF', $section_text)) {
if (trim($section_text['SKIPIF'])) {
$this->save_text($temp_skipif, $section_text['SKIPIF']);
$output = $this->system_with_timeout("$php $info_params -f $temp_skipif");
$output = $output[1];
unlink($temp_skipif);
if (!strncasecmp('skip', ltrim($output), 4)) {
$skipreason = "SKIP $tested";
if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) {
$skipreason .= '(reason: ' . $m[1] . ')';
}
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, $skipreason);
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' # skip ' . $reason);
}
return 'SKIPPED';
}
if (!strncasecmp('info', ltrim($output), 4)) {
if (preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) {
$info = " (info: $m[1])";
}
}
if (!strncasecmp('warn', ltrim($output), 4)) {
if (preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) {
$warn = true; /* only if there is a reason */
$info = " (warn: $m[1])";
}
}
}
}
 
// We've satisfied the preconditions - run the test!
$this->save_text($temp_file,$section_text['FILE']);
 
$args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : '';
 
$cmd = "$php$ini_settings -f $temp_file$args 2>&1";
if (isset($this->_logger)) {
$this->_logger->log(2, 'Running command "' . $cmd . '"');
}
 
$savedir = getcwd(); // in case the test moves us around
// Reset environment from any previous test.
$env = $_ENV;
$env['REDIRECT_STATUS']='';
$env['QUERY_STRING']='';
$env['PATH_TRANSLATED']='';
$env['SCRIPT_FILENAME']='';
$env['REQUEST_METHOD']='';
$env['CONTENT_TYPE']='';
$env['CONTENT_LENGTH']='';
if (!empty($section_text['ENV'])) {
foreach(explode("\n", trim($section_text['ENV'])) as $e) {
$e = explode('=',trim($e),2);
if (!empty($e[0]) && isset($e[1])) {
$env[$e[0]] = $e[1];
}
}
}
if (array_key_exists('GET', $section_text)) {
$query_string = trim($section_text['GET']);
} else {
$query_string = '';
}
if (array_key_exists('COOKIE', $section_text)) {
$env['HTTP_COOKIE'] = trim($section_text['COOKIE']);
} else {
$env['HTTP_COOKIE'] = '';
}
$env['REDIRECT_STATUS'] = '1';
$env['QUERY_STRING'] = $query_string;
$env['PATH_TRANSLATED'] = $test_file;
$env['SCRIPT_FILENAME'] = $test_file;
if (array_key_exists('UPLOAD', $section_text) && !empty($section_text['UPLOAD'])) {
$upload_files = trim($section_text['UPLOAD']);
$upload_files = explode("\n", $upload_files);
 
$request = "Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737\n" .
"-----------------------------20896060251896012921717172737\n";
foreach ($upload_files as $fileinfo) {
$fileinfo = explode('=', $fileinfo);
if (count($fileinfo) != 2) {
return PEAR::raiseError("Invalid UPLOAD section in test file: $file");
}
if (!realpath(dirname($file) . '/' . $fileinfo[1])) {
return PEAR::raiseError("File for upload does not exist: $fileinfo[1] " .
"in test file: $file");
}
$file_contents = file_get_contents(dirname($file) . '/' . $fileinfo[1]);
$fileinfo[1] = basename($fileinfo[1]);
$request .= "Content-Disposition: form-data; name=\"$fileinfo[0]\"; filename=\"$fileinfo[1]\"\n";
$request .= "Content-Type: text/plain\n\n";
$request .= $file_contents . "\n" .
"-----------------------------20896060251896012921717172737\n";
}
if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
// encode POST raw
$post = trim($section_text['POST']);
$post = explode('&', $post);
foreach ($post as $i => $post_info) {
$post_info = explode('=', $post_info);
if (count($post_info) != 2) {
return PEAR::raiseError("Invalid POST data in test file: $file");
}
$post_info[0] = rawurldecode($post_info[0]);
$post_info[1] = rawurldecode($post_info[1]);
$post[$i] = $post_info;
}
foreach ($post as $post_info) {
$request .= "Content-Disposition: form-data; name=\"$post_info[0]\"\n\n";
$request .= $post_info[1] . "\n" .
"-----------------------------20896060251896012921717172737\n";
}
unset($section_text['POST']);
}
$section_text['POST_RAW'] = $request;
}
if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) {
$post = trim($section_text['POST_RAW']);
$raw_lines = explode("\n", $post);
$request = '';
$started = false;
foreach ($raw_lines as $i => $line) {
if (empty($env['CONTENT_TYPE']) &&
preg_match('/^Content-Type:(.*)/i', $line, $res)) {
$env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
continue;
}
if ($started) {
$request .= "\n";
}
$started = true;
$request .= $line;
}
$env['CONTENT_LENGTH'] = strlen($request);
$env['REQUEST_METHOD'] = 'POST';
 
$this->save_text($tmp_post, $request);
$cmd = "$php$pass_options$ini_settings -f \"$test_file\" 2>&1 < $tmp_post";
} elseif (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
$post = trim($section_text['POST']);
$this->save_text($tmp_post, $post);
$content_length = strlen($post);
$env['REQUEST_METHOD'] = 'POST';
$env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
$env['CONTENT_LENGTH'] = $content_length;
$cmd = "$php$pass_options$ini_settings -f \"$test_file\" 2>&1 < $tmp_post";
} else {
$env['REQUEST_METHOD'] = 'GET';
$env['CONTENT_TYPE'] = '';
$env['CONTENT_LENGTH'] = '';
$cmd = "$php$pass_options$ini_settings -f \"$test_file\" $args 2>&1";
}
if (OS_WINDOWS && isset($section_text['RETURNS'])) {
ob_start();
system($cmd, $return_value);
$out = ob_get_contents();
ob_end_clean();
$section_text['RETURNS'] = (int) trim($section_text['RETURNS']);
$returnfail = ($return_value != $section_text['RETURNS']);
} else {
$returnfail = false;
$out = $this->system_with_timeout($cmd, $env,
isset($section_text['STDIN']) ? $section_text['STDIN'] : null);
$return_value = $out[0];
$out = $out[1];
}
if (isset($tmp_post) && realpath($tmp_post)) {
unlink(realpath($tmp_post));
}
chdir($savedir);
 
if ($section_text['CLEAN']) {
// perform test cleanup
$this->save_text($temp_clean, $section_text['CLEAN']);
$this->system_with_timeout("$php $temp_clean");
if (file_exists($temp_clean)) {
unlink($temp_clean);
}
}
// Does the output match what is expected?
$output = trim($out);
$output = preg_replace('/\r\n/', "\n", $output);
 
/* when using CGI, strip the headers from the output */
$headers = "";
if (!empty($this->_options['cgi']) &&
preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) {
$output = trim($match[2]);
$rh = preg_split("/[\n\r]+/",$match[1]);
$headers = array();
foreach ($rh as $line) {
if (strpos($line, ':')!==false) {
$line = explode(':', $line, 2);
$headers[trim($line[0])] = trim($line[1]);
}
}
}
 
do {
if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) {
if (isset($section_text['EXPECTF'])) {
$wanted = trim($section_text['EXPECTF']);
} else {
$wanted = trim($section_text['EXPECTREGEX']);
}
$wanted_re = preg_replace('/\r\n/',"\n",$wanted);
if (isset($section_text['EXPECTF'])) {
$wanted_re = preg_quote($wanted_re, '/');
// Stick to basics
$wanted_re = str_replace("%s", ".+?", $wanted_re); //not greedy
$wanted_re = str_replace("%i", "[+\-]?[0-9]+", $wanted_re);
$wanted_re = str_replace("%d", "[0-9]+", $wanted_re);
$wanted_re = str_replace("%x", "[0-9a-fA-F]+", $wanted_re);
$wanted_re = str_replace("%f", "[+\-]?\.?[0-9]+\.?[0-9]*(E-?[0-9]+)?", $wanted_re);
$wanted_re = str_replace("%c", ".", $wanted_re);
// %f allows two points "-.0.0" but that is the best *simple* expression
}
/* DEBUG YOUR REGEX HERE
var_dump($wanted_re);
print(str_repeat('=', 80) . "\n");
var_dump($output);
*/
if (!$returnfail && preg_match("/^$wanted_re\$/s", $output)) {
if (file_exists($temp_file)) {
unlink($temp_file);
}
 
if (array_key_exists('FAIL', $section_text)) {
break;
}
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, "PASS $tested$info");
}
if (isset($old_php)) {
$php = $old_php;
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' - ' . $tested);
}
return 'PASSED';
}
 
} else {
$wanted = trim($section_text['EXPECT']);
$wanted = preg_replace('/\r\n/',"\n",$wanted);
// compare and leave on success
$ok = (0 == strcmp($output,$wanted));
if (!$returnfail && $ok) {
if (file_exists($temp_file)) {
unlink($temp_file);
}
if (array_key_exists('FAIL', $section_text)) {
break;
}
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, "PASS $tested$info");
}
if (isset($old_php)) {
$php = $old_php;
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' - ' . $tested);
}
return 'PASSED';
}
}
} while (false);
 
if (array_key_exists('FAIL', $section_text)) {
// we expect a particular failure
// this is only used for testing PEAR_RunTest
$faildiff = $this->generate_diff(
$wanted,
$output,
null,
isset($section_text['EXPECTF']) ? $wanted_re : null);
$wanted = preg_replace('/\r/', '', trim($section_text['FAIL']));
$faildiff = preg_replace('/\r/', '', $faildiff);
if ($faildiff == $wanted) {
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, "PASS $tested$info");
}
if (isset($old_php)) {
$php = $old_php;
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' - ' . $tested);
}
return 'PASSED';
}
unset($section_text['EXPECTF']);
$output = $faildiff;
if (isset($section_text['RETURNS'])) {
return PEAR::raiseError('Cannot have both RETURNS and FAIL in the same test: ' .
$file);
}
}
 
// Test failed so we need to report details.
if ($warn) {
$this->_logger->log(0, "WARN $tested$info");
} else {
$this->_logger->log(0, "FAIL $tested$info");
}
 
if (isset($section_text['RETURNS'])) {
$GLOBALS['__PHP_FAILED_TESTS__'][] = array(
'name' => $file,
'test_name' => $tested,
'output' => $log_filename,
'diff' => $diff_filename,
'info' => $info,
'return' => $return_value
);
} else {
$GLOBALS['__PHP_FAILED_TESTS__'][] = array(
'name' => $file,
'test_name' => $tested,
'output' => $output_filename,
'diff' => $diff_filename,
'info' => $info,
);
}
 
// write .exp
if (strpos($log_format,'E') !== FALSE) {
$logname = $exp_filename;
if (!$log = fopen($logname,'w')) {
return PEAR::raiseError("Cannot create test log - $logname");
}
fwrite($log,$wanted);
fclose($log);
}
 
// write .out
if (strpos($log_format,'O') !== FALSE) {
$logname = $output_filename;
if (!$log = fopen($logname,'w')) {
return PEAR::raiseError("Cannot create test log - $logname");
}
fwrite($log,$output);
fclose($log);
}
 
// write .diff
if (strpos($log_format,'D') !== FALSE) {
$logname = $diff_filename;
if (!$log = fopen($logname,'w')) {
return PEAR::raiseError("Cannot create test log - $logname");
}
fwrite($log, $this->generate_diff(
$wanted,
$output,
isset($section_text['RETURNS']) ?
array(trim($section_text['RETURNS']), $return_value) : null,
isset($section_text['EXPECTF']) ? $wanted_re : null)
);
fclose($log);
}
 
// write .log
if (strpos($log_format,'L') !== FALSE) {
$logname = $log_filename;
if (!$log = fopen($logname,'w')) {
return PEAR::raiseError("Cannot create test log - $logname");
}
fwrite($log,"
---- EXPECTED OUTPUT
$wanted
---- ACTUAL OUTPUT
$output
---- FAILED
");
if ($returnfail) {
fwrite($log,"
---- EXPECTED RETURN
$section_text[RETURNS]
---- ACTUAL RETURN
$return_value
");
}
fclose($log);
//error_report($file,$logname,$tested);
}
 
if (isset($old_php)) {
$php = $old_php;
}
 
if (isset($this->_options['tapoutput'])) {
$wanted = explode("\n", $wanted);
$wanted = "# Expected output:\n#\n#" . implode("\n#", $wanted);
$output = explode("\n", $output);
$output = "#\n#\n# Actual output:\n#\n#" . implode("\n#", $output);
return array($wanted . $output . 'not ok', ' - ' . $tested);
}
return $warn ? 'WARNED' : 'FAILED';
}
 
function generate_diff($wanted, $output, $return_value, $wanted_re)
{
$w = explode("\n", $wanted);
$o = explode("\n", $output);
$wr = explode("\n", $wanted_re);
$w1 = array_diff_assoc($w,$o);
$o1 = array_diff_assoc($o,$w);
$w2 = array();
$o2 = array();
foreach($w1 as $idx => $val) {
if (!$wanted_re || !isset($wr[$idx]) || !isset($o1[$idx]) ||
!preg_match('/^' . $wr[$idx] . '$/', $o1[$idx])) {
$w2[sprintf("%03d<", $idx)] = sprintf("%03d- ", $idx + 1) . $val;
}
}
foreach($o1 as $idx => $val) {
if (!$wanted_re || !isset($wr[$idx]) ||
!preg_match('/^' . $wr[$idx] . '$/', $val)) {
$o2[sprintf("%03d>", $idx)] = sprintf("%03d+ ", $idx + 1) . $val;
}
}
$diff = array_merge($w2, $o2);
ksort($diff);
if ($return_value) {
$extra = "##EXPECTED: $return_value[0]\r\n##RETURNED: $return_value[1]";
} else {
$extra = '';
}
return implode("\r\n", $diff) . $extra;
}
 
//
// Write the given text to a temporary file, and return the filename.
//
 
function save_text($filename, $text)
{
if (!$fp = fopen($filename, 'w')) {
return PEAR::raiseError("Cannot open file '" . $filename . "' (save_text)");
}
fwrite($fp,$text);
fclose($fp);
if (1 < DETAILED) echo "
FILE $filename {{{
$text
}}}
";
}
 
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFile/Parser/v1.php
New file
0,0 → 1,461
<?php
/**
* package.xml parsing class, package.xml version 1.0
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v1.php,v 1.22 2006/03/27 05:25:48 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* package.xml abstraction class
*/
require_once 'PEAR/PackageFile/v1.php';
/**
* Parser for package.xml version 1.0
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @PEAR-VER@
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_PackageFile_Parser_v1
{
var $_registry;
var $_config;
var $_logger;
/**
* BC hack to allow PEAR_Common::infoFromString() to sort of
* work with the version 2.0 format - there's no filelist though
* @param PEAR_PackageFile_v2
*/
function fromV2($packagefile)
{
$info = $packagefile->getArray(true);
$ret = new PEAR_PackageFile_v1;
$ret->fromArray($info['old']);
}
 
function setConfig(&$c)
{
$this->_config = &$c;
$this->_registry = &$c->getRegistry();
}
 
function setLogger(&$l)
{
$this->_logger = &$l;
}
 
/**
* @param string contents of package.xml file, version 1.0
* @return bool success of parsing
*/
function parse($data, $file, $archive = false)
{
if (!extension_loaded('xml')) {
return PEAR::raiseError('Cannot create xml parser for parsing package.xml, no xml extension');
}
$xp = xml_parser_create();
if (!$xp) {
return PEAR::raiseError('Cannot create xml parser for parsing package.xml');
}
xml_set_object($xp, $this);
xml_set_element_handler($xp, '_element_start_1_0', '_element_end_1_0');
xml_set_character_data_handler($xp, '_pkginfo_cdata_1_0');
xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false);
 
$this->element_stack = array();
$this->_packageInfo = array('provides' => array());
$this->current_element = false;
unset($this->dir_install);
$this->_packageInfo['filelist'] = array();
$this->filelist =& $this->_packageInfo['filelist'];
$this->dir_names = array();
$this->in_changelog = false;
$this->d_i = 0;
$this->cdata = '';
$this->_isValid = true;
 
if (!xml_parse($xp, $data, 1)) {
$code = xml_get_error_code($xp);
$line = xml_get_current_line_number($xp);
xml_parser_free($xp);
return PEAR::raiseError(sprintf("XML error: %s at line %d",
$str = xml_error_string($code), $line), 2);
}
 
xml_parser_free($xp);
 
$pf = new PEAR_PackageFile_v1;
$pf->setConfig($this->_config);
if (isset($this->_logger)) {
$pf->setLogger($this->_logger);
}
$pf->setPackagefile($file, $archive);
$pf->fromArray($this->_packageInfo);
return $pf;
}
// {{{ _unIndent()
 
/**
* Unindent given string
*
* @param string $str The string that has to be unindented.
* @return string
* @access private
*/
function _unIndent($str)
{
// remove leading newlines
$str = preg_replace('/^[\r\n]+/', '', $str);
// find whitespace at the beginning of the first line
$indent_len = strspn($str, " \t");
$indent = substr($str, 0, $indent_len);
$data = '';
// remove the same amount of whitespace from following lines
foreach (explode("\n", $str) as $line) {
if (substr($line, 0, $indent_len) == $indent) {
$data .= substr($line, $indent_len) . "\n";
}
}
return $data;
}
 
// Support for package DTD v1.0:
// {{{ _element_start_1_0()
 
/**
* XML parser callback for ending elements. Used for version 1.0
* packages.
*
* @param resource $xp XML parser resource
* @param string $name name of ending element
*
* @return void
*
* @access private
*/
function _element_start_1_0($xp, $name, $attribs)
{
array_push($this->element_stack, $name);
$this->current_element = $name;
$spos = sizeof($this->element_stack) - 2;
$this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : '';
$this->current_attributes = $attribs;
$this->cdata = '';
switch ($name) {
case 'dir':
if ($this->in_changelog) {
break;
}
if (array_key_exists('name', $attribs) && $attribs['name'] != '/') {
$attribs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
$attribs['name']);
if (strrpos($attribs['name'], '/') == strlen($attribs['name']) - 1) {
$attribs['name'] = substr($attribs['name'], 0,
strlen($attribs['name']) - 1);
}
if (strpos($attribs['name'], '/') === 0) {
$attribs['name'] = substr($attribs['name'], 1);
}
$this->dir_names[] = $attribs['name'];
}
if (isset($attribs['baseinstalldir'])) {
$this->dir_install = $attribs['baseinstalldir'];
}
if (isset($attribs['role'])) {
$this->dir_role = $attribs['role'];
}
break;
case 'file':
if ($this->in_changelog) {
break;
}
if (isset($attribs['name'])) {
$path = '';
if (count($this->dir_names)) {
foreach ($this->dir_names as $dir) {
$path .= $dir . '/';
}
}
$path .= preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
$attribs['name']);
unset($attribs['name']);
$this->current_path = $path;
$this->filelist[$path] = $attribs;
// Set the baseinstalldir only if the file don't have this attrib
if (!isset($this->filelist[$path]['baseinstalldir']) &&
isset($this->dir_install))
{
$this->filelist[$path]['baseinstalldir'] = $this->dir_install;
}
// Set the Role
if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
$this->filelist[$path]['role'] = $this->dir_role;
}
}
break;
case 'replace':
if (!$this->in_changelog) {
$this->filelist[$this->current_path]['replacements'][] = $attribs;
}
break;
case 'maintainers':
$this->_packageInfo['maintainers'] = array();
$this->m_i = 0; // maintainers array index
break;
case 'maintainer':
// compatibility check
if (!isset($this->_packageInfo['maintainers'])) {
$this->_packageInfo['maintainers'] = array();
$this->m_i = 0;
}
$this->_packageInfo['maintainers'][$this->m_i] = array();
$this->current_maintainer =& $this->_packageInfo['maintainers'][$this->m_i];
break;
case 'changelog':
$this->_packageInfo['changelog'] = array();
$this->c_i = 0; // changelog array index
$this->in_changelog = true;
break;
case 'release':
if ($this->in_changelog) {
$this->_packageInfo['changelog'][$this->c_i] = array();
$this->current_release = &$this->_packageInfo['changelog'][$this->c_i];
} else {
$this->current_release = &$this->_packageInfo;
}
break;
case 'deps':
if (!$this->in_changelog) {
$this->_packageInfo['release_deps'] = array();
}
break;
case 'dep':
// dependencies array index
if (!$this->in_changelog) {
$this->d_i++;
isset($attribs['type']) ? ($attribs['type'] = strtolower($attribs['type'])) : false;
$this->_packageInfo['release_deps'][$this->d_i] = $attribs;
}
break;
case 'configureoptions':
if (!$this->in_changelog) {
$this->_packageInfo['configure_options'] = array();
}
break;
case 'configureoption':
if (!$this->in_changelog) {
$this->_packageInfo['configure_options'][] = $attribs;
}
break;
case 'provides':
if (empty($attribs['type']) || empty($attribs['name'])) {
break;
}
$attribs['explicit'] = true;
$this->_packageInfo['provides']["$attribs[type];$attribs[name]"] = $attribs;
break;
case 'package' :
if (isset($attribs['version'])) {
$this->_packageInfo['xsdversion'] = trim($attribs['version']);
} else {
$this->_packageInfo['xsdversion'] = '1.0';
}
if (isset($attribs['packagerversion'])) {
$this->_packageInfo['packagerversion'] = $attribs['packagerversion'];
}
break;
}
}
 
// }}}
// {{{ _element_end_1_0()
 
/**
* XML parser callback for ending elements. Used for version 1.0
* packages.
*
* @param resource $xp XML parser resource
* @param string $name name of ending element
*
* @return void
*
* @access private
*/
function _element_end_1_0($xp, $name)
{
$data = trim($this->cdata);
switch ($name) {
case 'name':
switch ($this->prev_element) {
case 'package':
$this->_packageInfo['package'] = $data;
break;
case 'maintainer':
$this->current_maintainer['name'] = $data;
break;
}
break;
case 'extends' :
$this->_packageInfo['extends'] = $data;
break;
case 'summary':
$this->_packageInfo['summary'] = $data;
break;
case 'description':
$data = $this->_unIndent($this->cdata);
$this->_packageInfo['description'] = $data;
break;
case 'user':
$this->current_maintainer['handle'] = $data;
break;
case 'email':
$this->current_maintainer['email'] = $data;
break;
case 'role':
$this->current_maintainer['role'] = $data;
break;
case 'version':
//$data = ereg_replace ('[^a-zA-Z0-9._\-]', '_', $data);
if ($this->in_changelog) {
$this->current_release['version'] = $data;
} else {
$this->_packageInfo['version'] = $data;
}
break;
case 'date':
if ($this->in_changelog) {
$this->current_release['release_date'] = $data;
} else {
$this->_packageInfo['release_date'] = $data;
}
break;
case 'notes':
// try to "de-indent" release notes in case someone
// has been over-indenting their xml ;-)
$data = $this->_unIndent($this->cdata);
if ($this->in_changelog) {
$this->current_release['release_notes'] = $data;
} else {
$this->_packageInfo['release_notes'] = $data;
}
break;
case 'warnings':
if ($this->in_changelog) {
$this->current_release['release_warnings'] = $data;
} else {
$this->_packageInfo['release_warnings'] = $data;
}
break;
case 'state':
if ($this->in_changelog) {
$this->current_release['release_state'] = $data;
} else {
$this->_packageInfo['release_state'] = $data;
}
break;
case 'license':
if ($this->in_changelog) {
$this->current_release['release_license'] = $data;
} else {
$this->_packageInfo['release_license'] = $data;
}
break;
case 'dep':
if ($data && !$this->in_changelog) {
$this->_packageInfo['release_deps'][$this->d_i]['name'] = $data;
}
break;
case 'dir':
if ($this->in_changelog) {
break;
}
array_pop($this->dir_names);
break;
case 'file':
if ($this->in_changelog) {
break;
}
if ($data) {
$path = '';
if (count($this->dir_names)) {
foreach ($this->dir_names as $dir) {
$path .= $dir . '/';
}
}
$path .= $data;
$this->filelist[$path] = $this->current_attributes;
// Set the baseinstalldir only if the file don't have this attrib
if (!isset($this->filelist[$path]['baseinstalldir']) &&
isset($this->dir_install))
{
$this->filelist[$path]['baseinstalldir'] = $this->dir_install;
}
// Set the Role
if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
$this->filelist[$path]['role'] = $this->dir_role;
}
}
break;
case 'maintainer':
if (empty($this->_packageInfo['maintainers'][$this->m_i]['role'])) {
$this->_packageInfo['maintainers'][$this->m_i]['role'] = 'lead';
}
$this->m_i++;
break;
case 'release':
if ($this->in_changelog) {
$this->c_i++;
}
break;
case 'changelog':
$this->in_changelog = false;
break;
}
array_pop($this->element_stack);
$spos = sizeof($this->element_stack) - 1;
$this->current_element = ($spos > 0) ? $this->element_stack[$spos] : '';
$this->cdata = '';
}
 
// }}}
// {{{ _pkginfo_cdata_1_0()
 
/**
* XML parser callback for character data. Used for version 1.0
* packages.
*
* @param resource $xp XML parser resource
* @param string $name character data
*
* @return void
*
* @access private
*/
function _pkginfo_cdata_1_0($xp, $data)
{
if (isset($this->cdata)) {
$this->cdata .= $data;
}
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFile/Parser/v2.php
New file
0,0 → 1,115
<?php
/**
* package.xml parsing class, package.xml version 2.0
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v2.php,v 1.19 2006/01/23 17:39:52 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* base xml parser class
*/
require_once 'PEAR/XMLParser.php';
require_once 'PEAR/PackageFile/v2.php';
/**
* Parser for package.xml version 2.0
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @PEAR-VER@
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser
{
var $_config;
var $_logger;
var $_registry;
 
function setConfig(&$c)
{
$this->_config = &$c;
$this->_registry = &$c->getRegistry();
}
 
function setLogger(&$l)
{
$this->_logger = &$l;
}
/**
* Unindent given string
*
* @param string $str The string that has to be unindented.
* @return string
* @access private
*/
function _unIndent($str)
{
// remove leading newlines
$str = preg_replace('/^[\r\n]+/', '', $str);
// find whitespace at the beginning of the first line
$indent_len = strspn($str, " \t");
$indent = substr($str, 0, $indent_len);
$data = '';
// remove the same amount of whitespace from following lines
foreach (explode("\n", $str) as $line) {
if (substr($line, 0, $indent_len) == $indent) {
$data .= substr($line, $indent_len) . "\n";
}
}
return $data;
}
 
/**
* post-process data
*
* @param string $data
* @param string $element element name
*/
function postProcess($data, $element)
{
if ($element == 'notes') {
return trim($this->_unIndent($data));
}
return trim($data);
}
 
/**
* @param string
* @param string file name of the package.xml
* @param string|false name of the archive this package.xml came from, if any
* @param string class name to instantiate and return. This must be PEAR_PackageFile_v2 or
* a subclass
* @return PEAR_PackageFile_v2
*/
function &parse($data, $file, $archive = false, $class = 'PEAR_PackageFile_v2')
{
if (PEAR::isError($err = parent::parse($data, $file))) {
return $err;
}
$ret = new $class;
$ret->setConfig($this->_config);
if (isset($this->_logger)) {
$ret->setLogger($this->_logger);
}
$ret->fromArray($this->_unserializedData);
$ret->setPackagefile($file, $archive);
return $ret;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFile/v1.php
New file
0,0 → 1,1603
<?php
/**
* PEAR_PackageFile_v1, package.xml version 1.0
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v1.php,v 1.72 2006/10/31 02:54:41 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* For error handling
*/
require_once 'PEAR/ErrorStack.php';
 
/**
* Error code if parsing is attempted with no xml extension
*/
define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3);
 
/**
* Error code if creating the xml parser resource fails
*/
define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4);
 
/**
* Error code used for all sax xml parsing errors
*/
define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5);
 
/**
* Error code used when there is no name
*/
define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6);
 
/**
* Error code when a package name is not valid
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7);
 
/**
* Error code used when no summary is parsed
*/
define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8);
 
/**
* Error code for summaries that are more than 1 line
*/
define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9);
 
/**
* Error code used when no description is present
*/
define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10);
 
/**
* Error code used when no license is present
*/
define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11);
 
/**
* Error code used when a <version> version number is not present
*/
define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12);
 
/**
* Error code used when a <version> version number is invalid
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13);
 
/**
* Error code when release state is missing
*/
define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14);
 
/**
* Error code when release state is invalid
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15);
 
/**
* Error code when release state is missing
*/
define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16);
 
/**
* Error code when release state is invalid
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17);
 
/**
* Error code when no release notes are found
*/
define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18);
 
/**
* Error code when no maintainers are found
*/
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19);
 
/**
* Error code when a maintainer has no handle
*/
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20);
 
/**
* Error code when a maintainer has no handle
*/
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21);
 
/**
* Error code when a maintainer has no name
*/
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22);
 
/**
* Error code when a maintainer has no email
*/
define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23);
 
/**
* Error code when a maintainer has no handle
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24);
 
/**
* Error code when a dependency is not a PHP dependency, but has no name
*/
define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25);
 
/**
* Error code when a dependency has no type (pkg, php, etc.)
*/
define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26);
 
/**
* Error code when a dependency has no relation (lt, ge, has, etc.)
*/
define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27);
 
/**
* Error code when a dependency is not a 'has' relation, but has no version
*/
define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28);
 
/**
* Error code when a dependency has an invalid relation
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29);
 
/**
* Error code when a dependency has an invalid type
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30);
 
/**
* Error code when a dependency has an invalid optional option
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31);
 
/**
* Error code when a dependency is a pkg dependency, and has an invalid package name
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32);
 
/**
* Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel
*/
define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33);
 
/**
* Error code when rel="has" and version attribute is present.
*/
define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34);
 
/**
* Error code when type="php" and dependency name is present
*/
define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35);
 
/**
* Error code when a configure option has no name
*/
define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36);
 
/**
* Error code when a configure option has no name
*/
define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37);
 
/**
* Error code when a file in the filelist has an invalid role
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38);
 
/**
* Error code when a file in the filelist has no role
*/
define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39);
 
/**
* Error code when analyzing a php source file that has parse errors
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40);
 
/**
* Error code when analyzing a php source file reveals a source element
* without a package name prefix
*/
define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41);
 
/**
* Error code when an unknown channel is specified
*/
define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42);
 
/**
* Error code when no files are found in the filelist
*/
define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43);
 
/**
* Error code when a file is not valid php according to _analyzeSourceCode()
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44);
 
/**
* Error code when the channel validator returns an error or warning
*/
define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45);
 
/**
* Error code when a php5 package is packaged in php4 (analysis doesn't work)
*/
define('PEAR_PACKAGEFILE_ERROR_PHP5', 46);
 
/**
* Error code when a file is listed in package.xml but does not exist
*/
define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47);
 
/**
* Error code when a <dep type="php" rel="not"... is encountered (use rel="ne")
*/
define('PEAR_PACKAGEFILE_PHP_NO_NOT', 48);
 
/**
* Error code when a package.xml contains non-ISO-8859-1 characters
*/
define('PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS', 49);
 
/**
* Error code when a dependency is not a 'has' relation, but has no version
*/
define('PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION', 50);
 
/**
* Error code when a package has no lead developer
*/
define('PEAR_PACKAGEFILE_ERROR_NO_LEAD', 51);
 
/**
* Error code when a filename begins with "."
*/
define('PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME', 52);
/**
* package.xml encapsulator
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_PackageFile_v1
{
/**
* @access private
* @var PEAR_ErrorStack
* @access private
*/
var $_stack;
 
/**
* A registry object, used to access the package name validation regex for non-standard channels
* @var PEAR_Registry
* @access private
*/
var $_registry;
 
/**
* An object that contains a log method that matches PEAR_Common::log's signature
* @var object
* @access private
*/
var $_logger;
 
/**
* Parsed package information
* @var array
* @access private
*/
var $_packageInfo;
 
/**
* path to package.xml
* @var string
* @access private
*/
var $_packageFile;
 
/**
* path to package .tgz or false if this is a local/extracted package.xml
* @var string
* @access private
*/
var $_archiveFile;
 
/**
* @var int
* @access private
*/
var $_isValid = 0;
 
/**
* Determines whether this packagefile was initialized only with partial package info
*
* If this package file was constructed via parsing REST, it will only contain
*
* - package name
* - channel name
* - dependencies
* @var boolean
* @access private
*/
var $_incomplete = true;
 
/**
* @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack
* @param string Name of Error Stack class to use.
*/
function PEAR_PackageFile_v1()
{
$this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1');
$this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
$this->_isValid = 0;
}
 
function installBinary($installer)
{
return false;
}
 
function isExtension($name)
{
return false;
}
 
function setConfig(&$config)
{
$this->_config = &$config;
$this->_registry = &$config->getRegistry();
}
 
function setRequestedGroup()
{
// placeholder
}
 
/**
* For saving in the registry.
*
* Set the last version that was installed
* @param string
*/
function setLastInstalledVersion($version)
{
$this->_packageInfo['_lastversion'] = $version;
}
 
/**
* @return string|false
*/
function getLastInstalledVersion()
{
if (isset($this->_packageInfo['_lastversion'])) {
return $this->_packageInfo['_lastversion'];
}
return false;
}
 
function getInstalledBinary()
{
return false;
}
 
function listPostinstallScripts()
{
return false;
}
 
function initPostinstallScripts()
{
return false;
}
 
function setLogger(&$logger)
{
if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) {
return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
}
$this->_logger = &$logger;
}
 
function setPackagefile($file, $archive = false)
{
$this->_packageFile = $file;
$this->_archiveFile = $archive ? $archive : $file;
}
 
function getPackageFile()
{
return isset($this->_packageFile) ? $this->_packageFile : false;
}
 
function getPackageType()
{
return 'php';
}
 
function getArchiveFile()
{
return $this->_archiveFile;
}
 
function packageInfo($field)
{
if (!is_string($field) || empty($field) ||
!isset($this->_packageInfo[$field])) {
return false;
}
return $this->_packageInfo[$field];
}
 
function setDirtree($path)
{
if (!isset($this->_packageInfo['dirtree'])) {
$this->_packageInfo['dirtree'] = array();
}
$this->_packageInfo['dirtree'][$path] = true;
}
 
function getDirtree()
{
if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
return $this->_packageInfo['dirtree'];
}
return false;
}
 
function resetDirtree()
{
unset($this->_packageInfo['dirtree']);
}
 
function fromArray($pinfo)
{
$this->_incomplete = false;
$this->_packageInfo = $pinfo;
}
 
function isIncomplete()
{
return $this->_incomplete;
}
 
function getChannel()
{
return 'pear.php.net';
}
 
function getUri()
{
return false;
}
 
function getTime()
{
return false;
}
 
function getExtends()
{
if (isset($this->_packageInfo['extends'])) {
return $this->_packageInfo['extends'];
}
return false;
}
 
/**
* @return array
*/
function toArray()
{
if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
return false;
}
return $this->getArray();
}
 
function getArray()
{
return $this->_packageInfo;
}
 
function getName()
{
return $this->getPackage();
}
 
function getPackage()
{
if (isset($this->_packageInfo['package'])) {
return $this->_packageInfo['package'];
}
return false;
}
 
/**
* WARNING - don't use this unless you know what you are doing
*/
function setRawPackage($package)
{
$this->_packageInfo['package'] = $package;
}
 
function setPackage($package)
{
$this->_packageInfo['package'] = $package;
$this->_isValid = false;
}
 
function getVersion()
{
if (isset($this->_packageInfo['version'])) {
return $this->_packageInfo['version'];
}
return false;
}
 
function setVersion($version)
{
$this->_packageInfo['version'] = $version;
$this->_isValid = false;
}
 
function clearMaintainers()
{
unset($this->_packageInfo['maintainers']);
}
 
function getMaintainers()
{
if (isset($this->_packageInfo['maintainers'])) {
return $this->_packageInfo['maintainers'];
}
return false;
}
 
/**
* Adds a new maintainer - no checking of duplicates is performed, use
* updatemaintainer for that purpose.
*/
function addMaintainer($role, $handle, $name, $email)
{
$this->_packageInfo['maintainers'][] =
array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name);
$this->_isValid = false;
}
 
function updateMaintainer($role, $handle, $name, $email)
{
$found = false;
if (!isset($this->_packageInfo['maintainers']) ||
!is_array($this->_packageInfo['maintainers'])) {
return $this->addMaintainer($role, $handle, $name, $email);
}
foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
if ($maintainer['handle'] == $handle) {
$found = $i;
break;
}
}
if ($found !== false) {
unset($this->_packageInfo['maintainers'][$found]);
$this->_packageInfo['maintainers'] =
array_values($this->_packageInfo['maintainers']);
}
$this->addMaintainer($role, $handle, $name, $email);
}
 
function deleteMaintainer($handle)
{
$found = false;
foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
if ($maintainer['handle'] == $handle) {
$found = $i;
break;
}
}
if ($found !== false) {
unset($this->_packageInfo['maintainers'][$found]);
$this->_packageInfo['maintainers'] =
array_values($this->_packageInfo['maintainers']);
return true;
}
return false;
}
 
function getState()
{
if (isset($this->_packageInfo['release_state'])) {
return $this->_packageInfo['release_state'];
}
return false;
}
 
function setRawState($state)
{
$this->_packageInfo['release_state'] = $state;
}
 
function setState($state)
{
$this->_packageInfo['release_state'] = $state;
$this->_isValid = false;
}
 
function getDate()
{
if (isset($this->_packageInfo['release_date'])) {
return $this->_packageInfo['release_date'];
}
return false;
}
 
function setDate($date)
{
$this->_packageInfo['release_date'] = $date;
$this->_isValid = false;
}
 
function getLicense()
{
if (isset($this->_packageInfo['release_license'])) {
return $this->_packageInfo['release_license'];
}
return false;
}
 
function setLicense($date)
{
$this->_packageInfo['release_license'] = $date;
$this->_isValid = false;
}
 
function getSummary()
{
if (isset($this->_packageInfo['summary'])) {
return $this->_packageInfo['summary'];
}
return false;
}
 
function setSummary($summary)
{
$this->_packageInfo['summary'] = $summary;
$this->_isValid = false;
}
 
function getDescription()
{
if (isset($this->_packageInfo['description'])) {
return $this->_packageInfo['description'];
}
return false;
}
 
function setDescription($desc)
{
$this->_packageInfo['description'] = $desc;
$this->_isValid = false;
}
 
function getNotes()
{
if (isset($this->_packageInfo['release_notes'])) {
return $this->_packageInfo['release_notes'];
}
return false;
}
 
function setNotes($notes)
{
$this->_packageInfo['release_notes'] = $notes;
$this->_isValid = false;
}
 
function getDeps()
{
if (isset($this->_packageInfo['release_deps'])) {
return $this->_packageInfo['release_deps'];
}
return false;
}
 
/**
* Reset dependencies prior to adding new ones
*/
function clearDeps()
{
unset($this->_packageInfo['release_deps']);
}
 
function addPhpDep($version, $rel)
{
$this->_isValid = false;
$this->_packageInfo['release_deps'][] =
array('type' => 'php',
'rel' => $rel,
'version' => $version);
}
 
function addPackageDep($name, $version, $rel, $optional = 'no')
{
$this->_isValid = false;
$dep =
array('type' => 'pkg',
'name' => $name,
'rel' => $rel,
'optional' => $optional);
if ($rel != 'has' && $rel != 'not') {
$dep['version'] = $version;
}
$this->_packageInfo['release_deps'][] = $dep;
}
 
function addExtensionDep($name, $version, $rel, $optional = 'no')
{
$this->_isValid = false;
$this->_packageInfo['release_deps'][] =
array('type' => 'ext',
'name' => $name,
'rel' => $rel,
'version' => $version,
'optional' => $optional);
}
 
/**
* WARNING - do not use this function directly unless you know what you're doing
*/
function setDeps($deps)
{
$this->_packageInfo['release_deps'] = $deps;
}
 
function hasDeps()
{
return isset($this->_packageInfo['release_deps']) &&
count($this->_packageInfo['release_deps']);
}
 
function getDependencyGroup($group)
{
return false;
}
 
function isCompatible($pf)
{
return false;
}
 
function isSubpackageOf($p)
{
return $p->isSubpackage($this);
}
 
function isSubpackage($p)
{
return false;
}
 
function dependsOn($package, $channel)
{
if (strtolower($channel) != 'pear.php.net') {
return false;
}
if (!($deps = $this->getDeps())) {
return false;
}
foreach ($deps as $dep) {
if ($dep['type'] != 'pkg') {
continue;
}
if (strtolower($dep['name']) == strtolower($package)) {
return true;
}
}
return false;
}
 
function getConfigureOptions()
{
if (isset($this->_packageInfo['configure_options'])) {
return $this->_packageInfo['configure_options'];
}
return false;
}
 
function hasConfigureOptions()
{
return isset($this->_packageInfo['configure_options']) &&
count($this->_packageInfo['configure_options']);
}
 
function addConfigureOption($name, $prompt, $default = false)
{
$o = array('name' => $name, 'prompt' => $prompt);
if ($default !== false) {
$o['default'] = $default;
}
if (!isset($this->_packageInfo['configure_options'])) {
$this->_packageInfo['configure_options'] = array();
}
$this->_packageInfo['configure_options'][] = $o;
}
 
function clearConfigureOptions()
{
unset($this->_packageInfo['configure_options']);
}
 
function getProvides()
{
if (isset($this->_packageInfo['provides'])) {
return $this->_packageInfo['provides'];
}
return false;
}
 
function getProvidesExtension()
{
return false;
}
 
function addFile($dir, $file, $attrs)
{
$dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
if ($dir == '/' || $dir == '') {
$dir = '';
} else {
$dir .= '/';
}
$file = $dir . $file;
$file = preg_replace('![\\/]+!', '/', $file);
$this->_packageInfo['filelist'][$file] = $attrs;
}
 
function getInstallationFilelist()
{
return $this->getFilelist();
}
 
function getFilelist()
{
if (isset($this->_packageInfo['filelist'])) {
return $this->_packageInfo['filelist'];
}
return false;
}
 
function setFileAttribute($file, $attr, $value)
{
$this->_packageInfo['filelist'][$file][$attr] = $value;
}
 
function resetFilelist()
{
$this->_packageInfo['filelist'] = array();
}
 
function setInstalledAs($file, $path)
{
if ($path) {
return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
}
unset($this->_packageInfo['filelist'][$file]['installed_as']);
}
 
function installedFile($file, $atts)
{
if (isset($this->_packageInfo['filelist'][$file])) {
$this->_packageInfo['filelist'][$file] =
array_merge($this->_packageInfo['filelist'][$file], $atts);
} else {
$this->_packageInfo['filelist'][$file] = $atts;
}
}
 
function getChangelog()
{
if (isset($this->_packageInfo['changelog'])) {
return $this->_packageInfo['changelog'];
}
return false;
}
 
function getPackagexmlVersion()
{
return '1.0';
}
 
/**
* Wrapper to {@link PEAR_ErrorStack::getErrors()}
* @param boolean determines whether to purge the error stack after retrieving
* @return array
*/
function getValidationWarnings($purge = true)
{
return $this->_stack->getErrors($purge);
}
 
// }}}
/**
* Validation error. Also marks the object contents as invalid
* @param error code
* @param array error information
* @access private
*/
function _validateError($code, $params = array())
{
$this->_stack->push($code, 'error', $params, false, false, debug_backtrace());
$this->_isValid = false;
}
 
/**
* Validation warning. Does not mark the object contents invalid.
* @param error code
* @param array error information
* @access private
*/
function _validateWarning($code, $params = array())
{
$this->_stack->push($code, 'warning', $params, false, false, debug_backtrace());
}
 
/**
* @param integer error code
* @access protected
*/
function _getErrorMessage()
{
return array(
PEAR_PACKAGEFILE_ERROR_NO_NAME =>
'Missing Package Name',
PEAR_PACKAGEFILE_ERROR_NO_SUMMARY =>
'No summary found',
PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY =>
'Summary should be on one line',
PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION =>
'Missing description',
PEAR_PACKAGEFILE_ERROR_NO_LICENSE =>
'Missing license',
PEAR_PACKAGEFILE_ERROR_NO_VERSION =>
'No release version found',
PEAR_PACKAGEFILE_ERROR_NO_STATE =>
'No release state found',
PEAR_PACKAGEFILE_ERROR_NO_DATE =>
'No release date found',
PEAR_PACKAGEFILE_ERROR_NO_NOTES =>
'No release notes found',
PEAR_PACKAGEFILE_ERROR_NO_LEAD =>
'Package must have at least one lead maintainer',
PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS =>
'No maintainers found, at least one must be defined',
PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE =>
'Maintainer %index% has no handle (user ID at channel server)',
PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE =>
'Maintainer %index% has no role',
PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME =>
'Maintainer %index% has no name',
PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL =>
'Maintainer %index% has no email',
PEAR_PACKAGEFILE_ERROR_NO_DEPNAME =>
'Dependency %index% is not a php dependency, and has no name',
PEAR_PACKAGEFILE_ERROR_NO_DEPREL =>
'Dependency %index% has no relation (rel)',
PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE =>
'Dependency %index% has no type',
PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED =>
'PHP Dependency %index% has a name attribute of "%name%" which will be' .
' ignored!',
PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION =>
'Dependency %index% is not a rel="has" or rel="not" dependency, ' .
'and has no version',
PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION =>
'Dependency %index% is a type="php" dependency, ' .
'and has no version',
PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED =>
'Dependency %index% is a rel="%rel%" dependency, versioning is ignored',
PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL =>
'Dependency %index% has invalid optional value "%opt%", should be yes or no',
PEAR_PACKAGEFILE_PHP_NO_NOT =>
'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' .
' to exclude specific versions',
PEAR_PACKAGEFILE_ERROR_NO_CONFNAME =>
'Configure Option %index% has no name',
PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT =>
'Configure Option %index% has no prompt',
PEAR_PACKAGEFILE_ERROR_NO_FILES =>
'No files in <filelist> section of package.xml',
PEAR_PACKAGEFILE_ERROR_NO_FILEROLE =>
'File "%file%" has no role, expecting one of "%roles%"',
PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE =>
'File "%file%" has invalid role "%role%", expecting one of "%roles%"',
PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME =>
'File "%file%" cannot start with ".", cannot package or install',
PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE =>
'Parser error: invalid PHP found in file "%file%"',
PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX =>
'in %file%: %type% "%name%" not prefixed with package name "%package%"',
PEAR_PACKAGEFILE_ERROR_INVALID_FILE =>
'Parser error: invalid PHP file "%file%"',
PEAR_PACKAGEFILE_ERROR_CHANNELVAL =>
'Channel validator error: field "%field%" - %reason%',
PEAR_PACKAGEFILE_ERROR_PHP5 =>
'Error, PHP5 token encountered in %file%, analysis should be in PHP5',
PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND =>
'File "%file%" in package.xml does not exist',
PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS =>
'Package.xml contains non-ISO-8859-1 characters, and may not validate',
);
}
 
/**
* Validate XML package definition file.
*
* @access public
* @return boolean
*/
function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false)
{
if (($this->_isValid & $state) == $state) {
return true;
}
$this->_isValid = true;
$info = $this->_packageInfo;
if (empty($info['package'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME);
$this->_packageName = $pn = 'unknown';
} else {
$this->_packageName = $pn = $info['package'];
}
 
if (empty($info['summary'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY);
} elseif (strpos(trim($info['summary']), "\n") !== false) {
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY,
array('summary' => $info['summary']));
}
if (empty($info['description'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION);
}
if (empty($info['release_license'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE);
}
if (empty($info['version'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION);
}
if (empty($info['release_state'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE);
}
if (empty($info['release_date'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE);
}
if (empty($info['release_notes'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES);
}
if (empty($info['maintainers'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS);
} else {
$haslead = false;
$i = 1;
foreach ($info['maintainers'] as $m) {
if (empty($m['handle'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE,
array('index' => $i));
}
if (empty($m['role'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE,
array('index' => $i, 'roles' => PEAR_Common::getUserRoles()));
} elseif ($m['role'] == 'lead') {
$haslead = true;
}
if (empty($m['name'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME,
array('index' => $i));
}
if (empty($m['email'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL,
array('index' => $i));
}
$i++;
}
if (!$haslead) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD);
}
}
if (!empty($info['release_deps'])) {
$i = 1;
foreach ($info['release_deps'] as $d) {
if (!isset($d['type']) || empty($d['type'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE,
array('index' => $i, 'types' => PEAR_Common::getDependencyTypes()));
continue;
}
if (!isset($d['rel']) || empty($d['rel'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL,
array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations()));
continue;
}
if (!empty($d['optional'])) {
if (!in_array($d['optional'], array('yes', 'no'))) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL,
array('index' => $i, 'opt' => $d['optional']));
}
}
if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION,
array('index' => $i));
} elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) {
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED,
array('index' => $i, 'rel' => $d['rel']));
}
if ($d['type'] == 'php' && !empty($d['name'])) {
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED,
array('index' => $i, 'name' => $d['name']));
} elseif ($d['type'] != 'php' && empty($d['name'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME,
array('index' => $i));
}
if ($d['type'] == 'php' && empty($d['version'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION,
array('index' => $i));
}
if (($d['rel'] == 'not') && ($d['type'] == 'php')) {
$this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT,
array('index' => $i));
}
$i++;
}
}
if (!empty($info['configure_options'])) {
$i = 1;
foreach ($info['configure_options'] as $c) {
if (empty($c['name'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME,
array('index' => $i));
}
if (empty($c['prompt'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT,
array('index' => $i));
}
$i++;
}
}
if (empty($info['filelist'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES);
$errors[] = 'no files';
} else {
foreach ($info['filelist'] as $file => $fa) {
if (empty($fa['role'])) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE,
array('file' => $file, 'roles' => PEAR_Common::getFileRoles()));
continue;
} elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE,
array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles()));
}
if ($file{0} == '.' && $file{1} == '/') {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
array('file' => $file));
}
}
}
if (isset($this->_registry) && $this->_isValid) {
$chan = $this->_registry->getChannel('pear.php.net');
if (PEAR::isError($chan)) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage());
return $this->_isValid = 0;
}
$validator = $chan->getValidationObject();
$validator->setPackageFile($this);
$validator->validate($state);
$failures = $validator->getFailures();
foreach ($failures['errors'] as $error) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error);
}
foreach ($failures['warnings'] as $warning) {
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning);
}
}
if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) {
if ($this->_analyzePhpFiles()) {
$this->_isValid = true;
}
}
if ($this->_isValid) {
return $this->_isValid = $state;
}
return $this->_isValid = 0;
}
 
function _analyzePhpFiles()
{
if (!$this->_isValid) {
return false;
}
if (!isset($this->_packageFile)) {
return false;
}
$dir_prefix = dirname($this->_packageFile);
$common = new PEAR_Common;
$log = isset($this->_logger) ? array(&$this->_logger, 'log') :
array($common, 'log');
$info = $this->getFilelist();
foreach ($info as $file => $fa) {
if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND,
array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file));
continue;
}
if ($fa['role'] == 'php' && $dir_prefix) {
call_user_func_array($log, array(1, "Analyzing $file"));
$srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file);
if ($srcinfo) {
$this->_buildProvidesArray($srcinfo);
}
}
}
$this->_packageName = $pn = $this->getPackage();
$pnl = strlen($pn);
if (isset($this->_packageInfo['provides'])) {
foreach ((array) $this->_packageInfo['provides'] as $key => $what) {
if (isset($what['explicit'])) {
// skip conformance checks if the provides entry is
// specified in the package.xml file
continue;
}
extract($what);
if ($type == 'class') {
if (!strncasecmp($name, $pn, $pnl)) {
continue;
}
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
} elseif ($type == 'function') {
if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) {
continue;
}
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
}
}
}
return $this->_isValid;
}
 
/**
* Get the default xml generator object
*
* @return PEAR_PackageFile_Generator_v1
*/
function &getDefaultGenerator()
{
if (!class_exists('PEAR_PackageFile_Generator_v1')) {
require_once 'PEAR/PackageFile/Generator/v1.php';
}
$a = &new PEAR_PackageFile_Generator_v1($this);
return $a;
}
 
/**
* Get the contents of a file listed within the package.xml
* @param string
* @return string
*/
function getFileContents($file)
{
if ($this->_archiveFile == $this->_packageFile) { // unpacked
$dir = dirname($this->_packageFile);
$file = $dir . DIRECTORY_SEPARATOR . $file;
$file = str_replace(array('/', '\\'),
array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
if (file_exists($file) && is_readable($file)) {
return implode('', file($file));
}
} else { // tgz
if (!class_exists('Archive_Tar')) {
require_once 'Archive/Tar.php';
}
$tar = &new Archive_Tar($this->_archiveFile);
$tar->pushErrorHandling(PEAR_ERROR_RETURN);
if ($file != 'package.xml' && $file != 'package2.xml') {
$file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
}
$file = $tar->extractInString($file);
$tar->popErrorHandling();
if (PEAR::isError($file)) {
return PEAR::raiseError("Cannot locate file '$file' in archive");
}
return $file;
}
}
 
// {{{ analyzeSourceCode()
/**
* Analyze the source code of the given PHP file
*
* @param string Filename of the PHP file
* @return mixed
* @access private
*/
function _analyzeSourceCode($file)
{
if (!function_exists("token_get_all")) {
return false;
}
if (!defined('T_DOC_COMMENT')) {
define('T_DOC_COMMENT', T_COMMENT);
}
if (!defined('T_INTERFACE')) {
define('T_INTERFACE', -1);
}
if (!defined('T_IMPLEMENTS')) {
define('T_IMPLEMENTS', -1);
}
if (!$fp = @fopen($file, "r")) {
return false;
}
fclose($fp);
$contents = file_get_contents($file);
$tokens = token_get_all($contents);
/*
for ($i = 0; $i < sizeof($tokens); $i++) {
@list($token, $data) = $tokens[$i];
if (is_string($token)) {
var_dump($token);
} else {
print token_name($token) . ' ';
var_dump(rtrim($data));
}
}
*/
$look_for = 0;
$paren_level = 0;
$bracket_level = 0;
$brace_level = 0;
$lastphpdoc = '';
$current_class = '';
$current_interface = '';
$current_class_level = -1;
$current_function = '';
$current_function_level = -1;
$declared_classes = array();
$declared_interfaces = array();
$declared_functions = array();
$declared_methods = array();
$used_classes = array();
$used_functions = array();
$extends = array();
$implements = array();
$nodeps = array();
$inquote = false;
$interface = false;
for ($i = 0; $i < sizeof($tokens); $i++) {
if (is_array($tokens[$i])) {
list($token, $data) = $tokens[$i];
} else {
$token = $tokens[$i];
$data = '';
}
if ($inquote) {
if ($token != '"' && $token != T_END_HEREDOC) {
continue;
} else {
$inquote = false;
continue;
}
}
switch ($token) {
case T_WHITESPACE :
continue;
case ';':
if ($interface) {
$current_function = '';
$current_function_level = -1;
}
break;
case '"':
case T_START_HEREDOC:
$inquote = true;
break;
case T_CURLY_OPEN:
case T_DOLLAR_OPEN_CURLY_BRACES:
case '{': $brace_level++; continue 2;
case '}':
$brace_level--;
if ($current_class_level == $brace_level) {
$current_class = '';
$current_class_level = -1;
}
if ($current_function_level == $brace_level) {
$current_function = '';
$current_function_level = -1;
}
continue 2;
case '[': $bracket_level++; continue 2;
case ']': $bracket_level--; continue 2;
case '(': $paren_level++; continue 2;
case ')': $paren_level--; continue 2;
case T_INTERFACE:
$interface = true;
case T_CLASS:
if (($current_class_level != -1) || ($current_function_level != -1)) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
array('file' => $file));
return false;
}
case T_FUNCTION:
case T_NEW:
case T_EXTENDS:
case T_IMPLEMENTS:
$look_for = $token;
continue 2;
case T_STRING:
if (version_compare(zend_version(), '2.0', '<')) {
if (in_array(strtolower($data),
array('public', 'private', 'protected', 'abstract',
'interface', 'implements', 'throw')
)) {
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5,
array($file));
}
}
if ($look_for == T_CLASS) {
$current_class = $data;
$current_class_level = $brace_level;
$declared_classes[] = $current_class;
} elseif ($look_for == T_INTERFACE) {
$current_interface = $data;
$current_class_level = $brace_level;
$declared_interfaces[] = $current_interface;
} elseif ($look_for == T_IMPLEMENTS) {
$implements[$current_class] = $data;
} elseif ($look_for == T_EXTENDS) {
$extends[$current_class] = $data;
} elseif ($look_for == T_FUNCTION) {
if ($current_class) {
$current_function = "$current_class::$data";
$declared_methods[$current_class][] = $data;
} elseif ($current_interface) {
$current_function = "$current_interface::$data";
$declared_methods[$current_interface][] = $data;
} else {
$current_function = $data;
$declared_functions[] = $current_function;
}
$current_function_level = $brace_level;
$m = array();
} elseif ($look_for == T_NEW) {
$used_classes[$data] = true;
}
$look_for = 0;
continue 2;
case T_VARIABLE:
$look_for = 0;
continue 2;
case T_DOC_COMMENT:
case T_COMMENT:
if (preg_match('!^/\*\*\s!', $data)) {
$lastphpdoc = $data;
if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
$nodeps = array_merge($nodeps, $m[1]);
}
}
continue 2;
case T_DOUBLE_COLON:
if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
array('file' => $file));
return false;
}
$class = $tokens[$i - 1][1];
if (strtolower($class) != 'parent') {
$used_classes[$class] = true;
}
continue 2;
}
}
return array(
"source_file" => $file,
"declared_classes" => $declared_classes,
"declared_interfaces" => $declared_interfaces,
"declared_methods" => $declared_methods,
"declared_functions" => $declared_functions,
"used_classes" => array_diff(array_keys($used_classes), $nodeps),
"inheritance" => $extends,
"implements" => $implements,
);
}
 
/**
* Build a "provides" array from data returned by
* analyzeSourceCode(). The format of the built array is like
* this:
*
* array(
* 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
* ...
* )
*
*
* @param array $srcinfo array with information about a source file
* as returned by the analyzeSourceCode() method.
*
* @return void
*
* @access private
*
*/
function _buildProvidesArray($srcinfo)
{
if (!$this->_isValid) {
return false;
}
$file = basename($srcinfo['source_file']);
$pn = $this->getPackage();
$pnl = strlen($pn);
foreach ($srcinfo['declared_classes'] as $class) {
$key = "class;$class";
if (isset($this->_packageInfo['provides'][$key])) {
continue;
}
$this->_packageInfo['provides'][$key] =
array('file'=> $file, 'type' => 'class', 'name' => $class);
if (isset($srcinfo['inheritance'][$class])) {
$this->_packageInfo['provides'][$key]['extends'] =
$srcinfo['inheritance'][$class];
}
}
foreach ($srcinfo['declared_methods'] as $class => $methods) {
foreach ($methods as $method) {
$function = "$class::$method";
$key = "function;$function";
if ($method{0} == '_' || !strcasecmp($method, $class) ||
isset($this->_packageInfo['provides'][$key])) {
continue;
}
$this->_packageInfo['provides'][$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
}
 
foreach ($srcinfo['declared_functions'] as $function) {
$key = "function;$function";
if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) {
continue;
}
if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
$warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
}
$this->_packageInfo['provides'][$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFile/v2.php
New file
0,0 → 1,2039
<?php
/**
* PEAR_PackageFile_v2, package.xml version 2.0
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v2.php,v 1.136 2007/02/20 00:16:12 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* For error handling
*/
require_once 'PEAR/ErrorStack.php';
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_PackageFile_v2
{
 
/**
* Parsed package information
* @var array
* @access private
*/
var $_packageInfo = array();
 
/**
* path to package .tgz or false if this is a local/extracted package.xml
* @var string|false
* @access private
*/
var $_archiveFile;
 
/**
* path to package .xml or false if this is an abstract parsed-from-string xml
* @var string|false
* @access private
*/
var $_packageFile;
 
/**
* This is used by file analysis routines to log progress information
* @var PEAR_Common
* @access protected
*/
var $_logger;
 
/**
* This is set to the highest validation level that has been validated
*
* If the package.xml is invalid or unknown, this is set to 0. If
* normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL. If
* downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING
* or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING. This allows validation
* "caching" to occur, which is particularly important for package validation, so
* that PHP files are not validated twice
* @var int
* @access private
*/
var $_isValid = 0;
 
/**
* True if the filelist has been validated
* @param bool
*/
var $_filesValid = false;
 
/**
* @var PEAR_Registry
* @access protected
*/
var $_registry;
 
/**
* @var PEAR_Config
* @access protected
*/
var $_config;
 
/**
* Optional Dependency group requested for installation
* @var string
* @access private
*/
var $_requestedGroup = false;
 
/**
* @var PEAR_ErrorStack
* @access protected
*/
var $_stack;
 
/**
* Namespace prefix used for tasks in this package.xml - use tasks: whenever possible
*/
var $_tasksNs;
 
/**
* Determines whether this packagefile was initialized only with partial package info
*
* If this package file was constructed via parsing REST, it will only contain
*
* - package name
* - channel name
* - dependencies
* @var boolean
* @access private
*/
var $_incomplete = true;
 
/**
* @var PEAR_PackageFile_v2_Validator
*/
var $_v2Validator;
 
/**
* The constructor merely sets up the private error stack
*/
function PEAR_PackageFile_v2()
{
$this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null);
$this->_isValid = false;
}
 
/**
* To make unit-testing easier
* @param PEAR_Frontend_*
* @param array options
* @param PEAR_Config
* @return PEAR_Downloader
* @access protected
*/
function &getPEARDownloader(&$i, $o, &$c)
{
$z = &new PEAR_Downloader($i, $o, $c);
return $z;
}
 
/**
* To make unit-testing easier
* @param PEAR_Config
* @param array options
* @param array package name as returned from {@link PEAR_Registry::parsePackageName()}
* @param int PEAR_VALIDATE_* constant
* @return PEAR_Dependency2
* @access protected
*/
function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING)
{
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
$z = &new PEAR_Dependency2($c, $o, $p, $s);
return $z;
}
 
function getInstalledBinary()
{
return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] :
false;
}
 
/**
* Installation of source package has failed, attempt to download and install the
* binary version of this package.
* @param PEAR_Installer
* @return array|false
*/
function installBinary(&$installer)
{
if (!OS_WINDOWS) {
$a = false;
return $a;
}
if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
$releasetype = $this->getPackageType() . 'release';
if (!is_array($installer->getInstallPackages())) {
$a = false;
return $a;
}
foreach ($installer->getInstallPackages() as $p) {
if ($p->isExtension($this->_packageInfo['providesextension'])) {
if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') {
$a = false;
return $a; // the user probably downloaded it separately
}
}
}
if (isset($this->_packageInfo[$releasetype]['binarypackage'])) {
$installer->log(0, 'Attempting to download binary version of extension "' .
$this->_packageInfo['providesextension'] . '"');
$params = $this->_packageInfo[$releasetype]['binarypackage'];
if (!is_array($params) || !isset($params[0])) {
$params = array($params);
}
if (isset($this->_packageInfo['channel'])) {
foreach ($params as $i => $param) {
$params[$i] = array('channel' => $this->_packageInfo['channel'],
'package' => $param, 'version' => $this->getVersion());
}
}
$dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(),
$installer->config);
$verbose = $dl->config->get('verbose');
$dl->config->set('verbose', -1);
foreach ($params as $param) {
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$ret = $dl->download(array($param));
PEAR::popErrorHandling();
if (is_array($ret) && count($ret)) {
break;
}
}
$dl->config->set('verbose', $verbose);
if (is_array($ret)) {
if (count($ret) == 1) {
$pf = $ret[0]->getPackageFile();
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $installer->install($ret[0]);
PEAR::popErrorHandling();
if (is_array($err)) {
$this->_packageInfo['#binarypackage'] = $ret[0]->getPackage();
// "install" self, so all dependencies will work transparently
$this->_registry->addPackage2($this);
$installer->log(0, 'Download and install of binary extension "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $pf->getChannel(),
'package' => $pf->getPackage()), true) . '" successful');
$a = array($ret[0], $err);
return $a;
}
$installer->log(0, 'Download and install of binary extension "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $pf->getChannel(),
'package' => $pf->getPackage()), true) . '" failed');
}
}
}
}
$a = false;
return $a;
}
 
/**
* @return string|false Extension name
*/
function getProvidesExtension()
{
if (in_array($this->getPackageType(),
array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
if (isset($this->_packageInfo['providesextension'])) {
return $this->_packageInfo['providesextension'];
}
}
return false;
}
 
/**
* @param string Extension name
* @return bool
*/
function isExtension($extension)
{
if (in_array($this->getPackageType(),
array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
return $this->_packageInfo['providesextension'] == $extension;
}
return false;
}
 
/**
* Tests whether every part of the package.xml 1.0 is represented in
* this package.xml 2.0
* @param PEAR_PackageFile_v1
* @return bool
*/
function isEquivalent($pf1)
{
if (!$pf1) {
return true;
}
if ($this->getPackageType() == 'bundle') {
return false;
}
$this->_stack->getErrors(true);
if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) {
return false;
}
$pass = true;
if ($pf1->getPackage() != $this->getPackage()) {
$this->_differentPackage($pf1->getPackage());
$pass = false;
}
if ($pf1->getVersion() != $this->getVersion()) {
$this->_differentVersion($pf1->getVersion());
$pass = false;
}
if (trim($pf1->getSummary()) != $this->getSummary()) {
$this->_differentSummary($pf1->getSummary());
$pass = false;
}
if (preg_replace('/\s+/', '', $pf1->getDescription()) !=
preg_replace('/\s+/', '', $this->getDescription())) {
$this->_differentDescription($pf1->getDescription());
$pass = false;
}
if ($pf1->getState() != $this->getState()) {
$this->_differentState($pf1->getState());
$pass = false;
}
if (!strstr(preg_replace('/\s+/', '', $this->getNotes()),
preg_replace('/\s+/', '', $pf1->getNotes()))) {
$this->_differentNotes($pf1->getNotes());
$pass = false;
}
$mymaintainers = $this->getMaintainers();
$yourmaintainers = $pf1->getMaintainers();
for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) {
$reset = false;
for ($i2 = 0; $i2 < count($mymaintainers); $i2++) {
if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) {
if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) {
$this->_differentRole($mymaintainers[$i2]['handle'],
$yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']);
$pass = false;
}
if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) {
$this->_differentEmail($mymaintainers[$i2]['handle'],
$yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']);
$pass = false;
}
if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) {
$this->_differentName($mymaintainers[$i2]['handle'],
$yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']);
$pass = false;
}
unset($mymaintainers[$i2]);
$mymaintainers = array_values($mymaintainers);
unset($yourmaintainers[$i1]);
$yourmaintainers = array_values($yourmaintainers);
$reset = true;
break;
}
}
if ($reset) {
$i1 = -1;
}
}
$this->_unmatchedMaintainers($mymaintainers, $yourmaintainers);
$filelist = $this->getFilelist();
foreach ($pf1->getFilelist() as $file => $atts) {
if (!isset($filelist[$file])) {
$this->_missingFile($file);
$pass = false;
}
}
return $pass;
}
 
function _differentPackage($package)
{
$this->_stack->push(__FUNCTION__, 'error', array('package' => $package,
'self' => $this->getPackage()),
'package.xml 1.0 package "%package%" does not match "%self%"');
}
 
function _differentVersion($version)
{
$this->_stack->push(__FUNCTION__, 'error', array('version' => $version,
'self' => $this->getVersion()),
'package.xml 1.0 version "%version%" does not match "%self%"');
}
 
function _differentState($state)
{
$this->_stack->push(__FUNCTION__, 'error', array('state' => $state,
'self' => $this->getState()),
'package.xml 1.0 state "%state%" does not match "%self%"');
}
 
function _differentRole($handle, $role, $selfrole)
{
$this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
'role' => $role, 'self' => $selfrole),
'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"');
}
 
function _differentEmail($handle, $email, $selfemail)
{
$this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
'email' => $email, 'self' => $selfemail),
'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"');
}
 
function _differentName($handle, $name, $selfname)
{
$this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
'name' => $name, 'self' => $selfname),
'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"');
}
 
function _unmatchedMaintainers($my, $yours)
{
if ($my) {
array_walk($my, create_function('&$i, $k', '$i = $i["handle"];'));
$this->_stack->push(__FUNCTION__, 'error', array('handles' => $my),
'package.xml 2.0 has unmatched extra maintainers "%handles%"');
}
if ($yours) {
array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];'));
$this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours),
'package.xml 1.0 has unmatched extra maintainers "%handles%"');
}
}
 
function _differentNotes($notes)
{
$truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...';
$truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() :
substr($this->getNotes(), 0, 24) . '...';
$this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes,
'self' => $truncmynotes),
'package.xml 1.0 release notes "%notes%" do not match "%self%"');
}
 
function _differentSummary($summary)
{
$truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...';
$truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() :
substr($this->getsummary(), 0, 24) . '...';
$this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary,
'self' => $truncmysummary),
'package.xml 1.0 summary "%summary%" does not match "%self%"');
}
 
function _differentDescription($description)
{
$truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...');
$truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() :
substr($this->getdescription(), 0, 24) . '...');
$this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription,
'self' => $truncmydescription),
'package.xml 1.0 description "%description%" does not match "%self%"');
}
 
function _missingFile($file)
{
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
'package.xml 1.0 file "%file%" is not present in <contents>');
}
 
/**
* WARNING - do not use this function unless you know what you're doing
*/
function setRawState($state)
{
$this->_packageInfo['stability']['release'] = $state;
}
 
/**
* WARNING - do not use this function unless you know what you're doing
*/
function setRawCompatible($compatible)
{
$this->_packageInfo['compatible'] = $compatible;
}
 
/**
* WARNING - do not use this function unless you know what you're doing
*/
function setRawPackage($package)
{
$this->_packageInfo['name'] = $package;
}
 
/**
* WARNING - do not use this function unless you know what you're doing
*/
function setRawChannel($channel)
{
$this->_packageInfo['channel'] = $channel;
}
 
function setRequestedGroup($group)
{
$this->_requestedGroup = $group;
}
 
function getRequestedGroup()
{
if (isset($this->_requestedGroup)) {
return $this->_requestedGroup;
}
return false;
}
 
/**
* For saving in the registry.
*
* Set the last version that was installed
* @param string
*/
function setLastInstalledVersion($version)
{
$this->_packageInfo['_lastversion'] = $version;
}
 
/**
* @return string|false
*/
function getLastInstalledVersion()
{
if (isset($this->_packageInfo['_lastversion'])) {
return $this->_packageInfo['_lastversion'];
}
return false;
}
 
/**
* Determines whether this package.xml has post-install scripts or not
* @return array|false
*/
function listPostinstallScripts()
{
$filelist = $this->getFilelist();
$contents = $this->getContents();
$contents = $contents['dir']['file'];
if (!is_array($contents) || !isset($contents[0])) {
$contents = array($contents);
}
$taskfiles = array();
foreach ($contents as $file) {
$atts = $file['attribs'];
unset($file['attribs']);
if (count($file)) {
$taskfiles[$atts['name']] = $file;
}
}
$common = new PEAR_Common;
$common->debug = $this->_config->get('verbose');
$this->_scripts = array();
$ret = array();
foreach ($taskfiles as $name => $tasks) {
if (!isset($filelist[$name])) {
// ignored files will not be in the filelist
continue;
}
$atts = $filelist[$name];
foreach ($tasks as $tag => $raw) {
$task = $this->getTask($tag);
$task = &new $task($this->_config, $common, PEAR_TASK_INSTALL);
if ($task->isScript()) {
$ret[] = $filelist[$name]['installed_as'];
}
}
}
if (count($ret)) {
return $ret;
}
return false;
}
 
/**
* Initialize post-install scripts for running
*
* This method can be used to detect post-install scripts, as the return value
* indicates whether any exist
* @return bool
*/
function initPostinstallScripts()
{
$filelist = $this->getFilelist();
$contents = $this->getContents();
$contents = $contents['dir']['file'];
if (!is_array($contents) || !isset($contents[0])) {
$contents = array($contents);
}
$taskfiles = array();
foreach ($contents as $file) {
$atts = $file['attribs'];
unset($file['attribs']);
if (count($file)) {
$taskfiles[$atts['name']] = $file;
}
}
$common = new PEAR_Common;
$common->debug = $this->_config->get('verbose');
$this->_scripts = array();
foreach ($taskfiles as $name => $tasks) {
if (!isset($filelist[$name])) {
// file was not installed due to installconditions
continue;
}
$atts = $filelist[$name];
foreach ($tasks as $tag => $raw) {
$taskname = $this->getTask($tag);
$task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL);
if (!$task->isScript()) {
continue; // scripts are only handled after installation
}
$lastversion = isset($this->_packageInfo['_lastversion']) ?
$this->_packageInfo['_lastversion'] : null;
$task->init($raw, $atts, $lastversion);
$res = $task->startSession($this, $atts['installed_as']);
if (!$res) {
continue; // skip this file
}
if (PEAR::isError($res)) {
return $res;
}
$assign = &$task;
$this->_scripts[] = &$assign;
}
}
if (count($this->_scripts)) {
return true;
}
return false;
}
 
function runPostinstallScripts()
{
if ($this->initPostinstallScripts()) {
$ui = &PEAR_Frontend::singleton();
if ($ui) {
$ui->runPostinstallScripts($this->_scripts, $this);
}
}
}
 
 
/**
* Convert a recursive set of <dir> and <file> tags into a single <dir> tag with
* <file> tags.
*/
function flattenFilelist()
{
if (isset($this->_packageInfo['bundle'])) {
return;
}
$filelist = array();
if (isset($this->_packageInfo['contents']['dir']['dir'])) {
$this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']);
if (!isset($filelist[1])) {
$filelist = $filelist[0];
}
$this->_packageInfo['contents']['dir']['file'] = $filelist;
unset($this->_packageInfo['contents']['dir']['dir']);
} else {
// else already flattened but check for baseinstalldir propagation
if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) {
if (isset($this->_packageInfo['contents']['dir']['file'][0])) {
foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) {
if (isset($file['attribs']['baseinstalldir'])) {
continue;
}
$this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir']
= $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'];
}
} else {
if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) {
$this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir']
= $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'];
}
}
}
}
}
 
/**
* @param array the final flattened file list
* @param array the current directory being processed
* @param string|false any recursively inherited baeinstalldir attribute
* @param string private recursion variable
* @return array
* @access protected
*/
function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '')
{
if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) {
$baseinstall = $dir['attribs']['baseinstalldir'];
}
if (isset($dir['dir'])) {
if (!isset($dir['dir'][0])) {
$dir['dir'] = array($dir['dir']);
}
foreach ($dir['dir'] as $subdir) {
if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) {
$name = '*unknown*';
} else {
$name = $subdir['attribs']['name'];
}
$newpath = empty($path) ? $name :
$path . '/' . $name;
$this->_getFlattenedFilelist($files, $subdir,
$baseinstall, $newpath);
}
}
if (isset($dir['file'])) {
if (!isset($dir['file'][0])) {
$dir['file'] = array($dir['file']);
}
foreach ($dir['file'] as $file) {
$attrs = $file['attribs'];
$name = $attrs['name'];
if ($baseinstall && !isset($attrs['baseinstalldir'])) {
$attrs['baseinstalldir'] = $baseinstall;
}
$attrs['name'] = empty($path) ? $name : $path . '/' . $name;
$attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
$attrs['name']);
$file['attribs'] = $attrs;
$files[] = $file;
}
}
}
 
function setConfig(&$config)
{
$this->_config = &$config;
$this->_registry = &$config->getRegistry();
}
 
function setLogger(&$logger)
{
if (!is_object($logger) || !method_exists($logger, 'log')) {
return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
}
$this->_logger = &$logger;
}
 
/**
* WARNING - do not use this function directly unless you know what you're doing
*/
function setDeps($deps)
{
$this->_packageInfo['dependencies'] = $deps;
}
 
/**
* WARNING - do not use this function directly unless you know what you're doing
*/
function setCompatible($compat)
{
$this->_packageInfo['compatible'] = $compat;
}
 
function setPackagefile($file, $archive = false)
{
$this->_packageFile = $file;
$this->_archiveFile = $archive ? $archive : $file;
}
 
/**
* Wrapper to {@link PEAR_ErrorStack::getErrors()}
* @param boolean determines whether to purge the error stack after retrieving
* @return array
*/
function getValidationWarnings($purge = true)
{
return $this->_stack->getErrors($purge);
}
 
function getPackageFile()
{
return $this->_packageFile;
}
 
function getArchiveFile()
{
return $this->_archiveFile;
}
 
 
/**
* Directly set the array that defines this packagefile
*
* WARNING: no validation. This should only be performed by internal methods
* inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2
* @param array
*/
function fromArray($pinfo)
{
unset($pinfo['old']);
unset($pinfo['xsdversion']);
$this->_incomplete = false;
$this->_packageInfo = $pinfo;
}
 
function isIncomplete()
{
return $this->_incomplete;
}
 
/**
* @return array
*/
function toArray($forreg = false)
{
if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
return false;
}
return $this->getArray($forreg);
}
 
function getArray($forReg = false)
{
if ($forReg) {
$arr = $this->_packageInfo;
$arr['old'] = array();
$arr['old']['version'] = $this->getVersion();
$arr['old']['release_date'] = $this->getDate();
$arr['old']['release_state'] = $this->getState();
$arr['old']['release_license'] = $this->getLicense();
$arr['old']['release_notes'] = $this->getNotes();
$arr['old']['release_deps'] = $this->getDeps();
$arr['old']['maintainers'] = $this->getMaintainers();
$arr['xsdversion'] = '2.0';
return $arr;
} else {
$info = $this->_packageInfo;
unset($info['dirtree']);
if (isset($info['_lastversion'])) {
unset($info['_lastversion']);
}
if (isset($info['#binarypackage'])) {
unset($info['#binarypackage']);
}
return $info;
}
}
 
function packageInfo($field)
{
$arr = $this->getArray(true);
if ($field == 'state') {
return $arr['stability']['release'];
}
if ($field == 'api-version') {
return $arr['version']['api'];
}
if ($field == 'api-state') {
return $arr['stability']['api'];
}
if (isset($arr['old'][$field])) {
if (!is_string($arr['old'][$field])) {
return null;
}
return $arr['old'][$field];
}
if (isset($arr[$field])) {
if (!is_string($arr[$field])) {
return null;
}
return $arr[$field];
}
return null;
}
 
function getName()
{
return $this->getPackage();
}
 
function getPackage()
{
if (isset($this->_packageInfo['name'])) {
return $this->_packageInfo['name'];
}
return false;
}
 
function getChannel()
{
if (isset($this->_packageInfo['uri'])) {
return '__uri';
}
if (isset($this->_packageInfo['channel'])) {
return strtolower($this->_packageInfo['channel']);
}
return false;
}
 
function getUri()
{
if (isset($this->_packageInfo['uri'])) {
return $this->_packageInfo['uri'];
}
return false;
}
 
function getExtends()
{
if (isset($this->_packageInfo['extends'])) {
return $this->_packageInfo['extends'];
}
return false;
}
 
function getSummary()
{
if (isset($this->_packageInfo['summary'])) {
return $this->_packageInfo['summary'];
}
return false;
}
 
function getDescription()
{
if (isset($this->_packageInfo['description'])) {
return $this->_packageInfo['description'];
}
return false;
}
 
function getMaintainers($raw = false)
{
if (!isset($this->_packageInfo['lead'])) {
return false;
}
if ($raw) {
$ret = array('lead' => $this->_packageInfo['lead']);
(isset($this->_packageInfo['developer'])) ?
$ret['developer'] = $this->_packageInfo['developer'] :null;
(isset($this->_packageInfo['contributor'])) ?
$ret['contributor'] = $this->_packageInfo['contributor'] :null;
(isset($this->_packageInfo['helper'])) ?
$ret['helper'] = $this->_packageInfo['helper'] :null;
return $ret;
} else {
$ret = array();
$leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] :
array($this->_packageInfo['lead']);
foreach ($leads as $lead) {
$s = $lead;
$s['handle'] = $s['user'];
unset($s['user']);
$s['role'] = 'lead';
$ret[] = $s;
}
if (isset($this->_packageInfo['developer'])) {
$leads = isset($this->_packageInfo['developer'][0]) ?
$this->_packageInfo['developer'] :
array($this->_packageInfo['developer']);
foreach ($leads as $maintainer) {
$s = $maintainer;
$s['handle'] = $s['user'];
unset($s['user']);
$s['role'] = 'developer';
$ret[] = $s;
}
}
if (isset($this->_packageInfo['contributor'])) {
$leads = isset($this->_packageInfo['contributor'][0]) ?
$this->_packageInfo['contributor'] :
array($this->_packageInfo['contributor']);
foreach ($leads as $maintainer) {
$s = $maintainer;
$s['handle'] = $s['user'];
unset($s['user']);
$s['role'] = 'contributor';
$ret[] = $s;
}
}
if (isset($this->_packageInfo['helper'])) {
$leads = isset($this->_packageInfo['helper'][0]) ?
$this->_packageInfo['helper'] :
array($this->_packageInfo['helper']);
foreach ($leads as $maintainer) {
$s = $maintainer;
$s['handle'] = $s['user'];
unset($s['user']);
$s['role'] = 'helper';
$ret[] = $s;
}
}
return $ret;
}
return false;
}
 
function getLeads()
{
if (isset($this->_packageInfo['lead'])) {
return $this->_packageInfo['lead'];
}
return false;
}
 
function getDevelopers()
{
if (isset($this->_packageInfo['developer'])) {
return $this->_packageInfo['developer'];
}
return false;
}
 
function getContributors()
{
if (isset($this->_packageInfo['contributor'])) {
return $this->_packageInfo['contributor'];
}
return false;
}
 
function getHelpers()
{
if (isset($this->_packageInfo['helper'])) {
return $this->_packageInfo['helper'];
}
return false;
}
 
function setDate($date)
{
if (!isset($this->_packageInfo['date'])) {
// ensure that the extends tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('time', 'version',
'stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease',
'zendextbinrelease', 'bundle', 'changelog'), array(), 'date');
}
$this->_packageInfo['date'] = $date;
$this->_isValid = 0;
}
 
function setTime($time)
{
$this->_isValid = 0;
if (!isset($this->_packageInfo['time'])) {
// ensure that the time tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('version',
'stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease',
'zendextbinrelease', 'bundle', 'changelog'), $time, 'time');
}
$this->_packageInfo['time'] = $time;
}
 
function getDate()
{
if (isset($this->_packageInfo['date'])) {
return $this->_packageInfo['date'];
}
return false;
}
 
function getTime()
{
if (isset($this->_packageInfo['time'])) {
return $this->_packageInfo['time'];
}
return false;
}
 
/**
* @param package|api version category to return
*/
function getVersion($key = 'release')
{
if (isset($this->_packageInfo['version'][$key])) {
return $this->_packageInfo['version'][$key];
}
return false;
}
 
function getStability()
{
if (isset($this->_packageInfo['stability'])) {
return $this->_packageInfo['stability'];
}
return false;
}
 
function getState($key = 'release')
{
if (isset($this->_packageInfo['stability'][$key])) {
return $this->_packageInfo['stability'][$key];
}
return false;
}
 
function getLicense($raw = false)
{
if (isset($this->_packageInfo['license'])) {
if ($raw) {
return $this->_packageInfo['license'];
}
if (is_array($this->_packageInfo['license'])) {
return $this->_packageInfo['license']['_content'];
} else {
return $this->_packageInfo['license'];
}
}
return false;
}
 
function getLicenseLocation()
{
if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) {
return false;
}
return $this->_packageInfo['license']['attribs'];
}
 
function getNotes()
{
if (isset($this->_packageInfo['notes'])) {
return $this->_packageInfo['notes'];
}
return false;
}
 
/**
* Return the <usesrole> tag contents, if any
* @return array|false
*/
function getUsesrole()
{
if (isset($this->_packageInfo['usesrole'])) {
return $this->_packageInfo['usesrole'];
}
return false;
}
 
/**
* Return the <usestask> tag contents, if any
* @return array|false
*/
function getUsestask()
{
if (isset($this->_packageInfo['usestask'])) {
return $this->_packageInfo['usestask'];
}
return false;
}
 
/**
* This should only be used to retrieve filenames and install attributes
*/
function getFilelist($preserve = false)
{
if (isset($this->_packageInfo['filelist']) && !$preserve) {
return $this->_packageInfo['filelist'];
}
$this->flattenFilelist();
if ($contents = $this->getContents()) {
$ret = array();
if (!isset($contents['dir']['file'][0])) {
$contents['dir']['file'] = array($contents['dir']['file']);
}
foreach ($contents['dir']['file'] as $file) {
$name = $file['attribs']['name'];
if (!$preserve) {
$file = $file['attribs'];
}
$ret[$name] = $file;
}
if (!$preserve) {
$this->_packageInfo['filelist'] = $ret;
}
return $ret;
}
return false;
}
 
/**
* Return configure options array, if any
*
* @return array|false
*/
function getConfigureOptions()
{
if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
return false;
}
$releases = $this->getReleases();
if (isset($releases[0])) {
$releases = $releases[0];
}
if (isset($releases['configureoption'])) {
if (!isset($releases['configureoption'][0])) {
$releases['configureoption'] = array($releases['configureoption']);
}
for ($i = 0; $i < count($releases['configureoption']); $i++) {
$releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs'];
}
return $releases['configureoption'];
}
return false;
}
 
/**
* This is only used at install-time, after all serialization
* is over.
*/
function resetFilelist()
{
$this->_packageInfo['filelist'] = array();
}
 
/**
* Retrieve a list of files that should be installed on this computer
* @return array
*/
function getInstallationFilelist($forfilecheck = false)
{
$contents = $this->getFilelist(true);
if (isset($contents['dir']['attribs']['baseinstalldir'])) {
$base = $contents['dir']['attribs']['baseinstalldir'];
}
if (isset($this->_packageInfo['bundle'])) {
return PEAR::raiseError(
'Exception: bundles should be handled in download code only');
}
$release = $this->getReleases();
if ($release) {
if (!isset($release[0])) {
if (!isset($release['installconditions']) && !isset($release['filelist'])) {
if ($forfilecheck) {
return $this->getFilelist();
}
return $contents;
}
$release = array($release);
}
$depchecker = &$this->getPEARDependency2($this->_config, array(),
array('channel' => $this->getChannel(), 'package' => $this->getPackage()),
PEAR_VALIDATE_INSTALLING);
foreach ($release as $instance) {
if (isset($instance['installconditions'])) {
$installconditions = $instance['installconditions'];
if (is_array($installconditions)) {
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
foreach ($installconditions as $type => $conditions) {
if (!isset($conditions[0])) {
$conditions = array($conditions);
}
foreach ($conditions as $condition) {
$ret = $depchecker->{"validate{$type}Dependency"}($condition);
if (PEAR::isError($ret)) {
PEAR::popErrorHandling();
continue 3; // skip this release
}
}
}
PEAR::popErrorHandling();
}
}
// this is the release to use
if (isset($instance['filelist'])) {
// ignore files
if (isset($instance['filelist']['ignore'])) {
$ignore = isset($instance['filelist']['ignore'][0]) ?
$instance['filelist']['ignore'] :
array($instance['filelist']['ignore']);
foreach ($ignore as $ig) {
unset ($contents[$ig['attribs']['name']]);
}
}
// install files as this name
if (isset($instance['filelist']['install'])) {
$installas = isset($instance['filelist']['install'][0]) ?
$instance['filelist']['install'] :
array($instance['filelist']['install']);
foreach ($installas as $as) {
$contents[$as['attribs']['name']]['attribs']['install-as'] =
$as['attribs']['as'];
}
}
}
if ($forfilecheck) {
foreach ($contents as $file => $attrs) {
$contents[$file] = $attrs['attribs'];
}
}
return $contents;
}
} else { // simple release - no installconditions or install-as
if ($forfilecheck) {
return $this->getFilelist();
}
return $contents;
}
// no releases matched
return PEAR::raiseError('No releases in package.xml matched the existing operating ' .
'system, extensions installed, or architecture, cannot install');
}
 
/**
* This is only used at install-time, after all serialization
* is over.
* @param string file name
* @param string installed path
*/
function setInstalledAs($file, $path)
{
if ($path) {
return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
}
unset($this->_packageInfo['filelist'][$file]['installed_as']);
}
 
function getInstalledLocation($file)
{
if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) {
return $this->_packageInfo['filelist'][$file]['installed_as'];
}
return false;
}
 
/**
* This is only used at install-time, after all serialization
* is over.
*/
function installedFile($file, $atts)
{
if (isset($this->_packageInfo['filelist'][$file])) {
$this->_packageInfo['filelist'][$file] =
array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']);
} else {
$this->_packageInfo['filelist'][$file] = $atts['attribs'];
}
}
 
/**
* Retrieve the contents tag
*/
function getContents()
{
if (isset($this->_packageInfo['contents'])) {
return $this->_packageInfo['contents'];
}
return false;
}
 
/**
* @param string full path to file
* @param string attribute name
* @param string attribute value
* @param int risky but fast - use this to choose a file based on its position in the list
* of files. Index is zero-based like PHP arrays.
* @return bool success of operation
*/
function setFileAttribute($filename, $attr, $value, $index = false)
{
$this->_isValid = 0;
if (in_array($attr, array('role', 'name', 'baseinstalldir'))) {
$this->_filesValid = false;
}
if ($index !== false &&
isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) {
$this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value;
return true;
}
if (!isset($this->_packageInfo['contents']['dir']['file'])) {
return false;
}
$files = $this->_packageInfo['contents']['dir']['file'];
if (!isset($files[0])) {
$files = array($files);
$ind = false;
} else {
$ind = true;
}
foreach ($files as $i => $file) {
if (isset($file['attribs'])) {
if ($file['attribs']['name'] == $filename) {
if ($ind) {
$this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value;
} else {
$this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value;
}
return true;
}
}
}
return false;
}
 
function setDirtree($path)
{
if (!isset($this->_packageInfo['dirtree'])) {
$this->_packageInfo['dirtree'] = array();
}
$this->_packageInfo['dirtree'][$path] = true;
}
 
function getDirtree()
{
if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
return $this->_packageInfo['dirtree'];
}
return false;
}
 
function resetDirtree()
{
unset($this->_packageInfo['dirtree']);
}
 
/**
* Determines whether this package claims it is compatible with the version of
* the package that has a recommended version dependency
* @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package
* @return boolean
*/
function isCompatible($pf)
{
if (!isset($this->_packageInfo['compatible'])) {
return false;
}
if (!isset($this->_packageInfo['channel'])) {
return false;
}
$me = $pf->getVersion();
$compatible = $this->_packageInfo['compatible'];
if (!isset($compatible[0])) {
$compatible = array($compatible);
}
$found = false;
foreach ($compatible as $info) {
if (strtolower($info['name']) == strtolower($pf->getPackage())) {
if (strtolower($info['channel']) == strtolower($pf->getChannel())) {
$found = true;
break;
}
}
}
if (!$found) {
return false;
}
if (isset($info['exclude'])) {
if (!isset($info['exclude'][0])) {
$info['exclude'] = array($info['exclude']);
}
foreach ($info['exclude'] as $exclude) {
if (version_compare($me, $exclude, '==')) {
return false;
}
}
}
if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) {
return true;
}
return false;
}
 
/**
* @return array|false
*/
function getCompatible()
{
if (isset($this->_packageInfo['compatible'])) {
return $this->_packageInfo['compatible'];
}
return false;
}
 
function getDependencies()
{
if (isset($this->_packageInfo['dependencies'])) {
return $this->_packageInfo['dependencies'];
}
return false;
}
 
function isSubpackageOf($p)
{
return $p->isSubpackage($this);
}
 
/**
* Determines whether the passed in package is a subpackage of this package.
*
* No version checking is done, only name verification.
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @return bool
*/
function isSubpackage($p)
{
$sub = array();
if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) {
$sub = $this->_packageInfo['dependencies']['required']['subpackage'];
if (!isset($sub[0])) {
$sub = array($sub);
}
}
if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) {
$sub1 = $this->_packageInfo['dependencies']['optional']['subpackage'];
if (!isset($sub1[0])) {
$sub1 = array($sub1);
}
$sub = array_merge($sub, $sub1);
}
if (isset($this->_packageInfo['dependencies']['group'])) {
$group = $this->_packageInfo['dependencies']['group'];
if (!isset($group[0])) {
$group = array($group);
}
foreach ($group as $deps) {
if (isset($deps['subpackage'])) {
$sub2 = $deps['subpackage'];
if (!isset($sub2[0])) {
$sub2 = array($sub2);
}
$sub = array_merge($sub, $sub2);
}
}
}
foreach ($sub as $dep) {
if (strtolower($dep['name']) == strtolower($p->getPackage())) {
if (isset($dep['channel'])) {
if (strtolower($dep['channel']) == strtolower($p->getChannel())) {
return true;
}
} else {
if ($dep['uri'] == $p->getURI()) {
return true;
}
}
}
}
return false;
}
 
function dependsOn($package, $channel)
{
if (!($deps = $this->getDependencies())) {
return false;
}
foreach (array('package', 'subpackage') as $type) {
foreach (array('required', 'optional') as $needed) {
if (isset($deps[$needed][$type])) {
if (!isset($deps[$needed][$type][0])) {
$deps[$needed][$type] = array($deps[$needed][$type]);
}
foreach ($deps[$needed][$type] as $dep) {
$depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
if (strtolower($dep['name']) == strtolower($package) &&
$depchannel == $channel) {
return true;
}
}
}
}
if (isset($deps['group'])) {
if (!isset($deps['group'][0])) {
$dep['group'] = array($deps['group']);
}
foreach ($deps['group'] as $group) {
if (isset($group[$type])) {
if (!is_array($group[$type])) {
$group[$type] = array($group[$type]);
}
foreach ($group[$type] as $dep) {
$depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
if (strtolower($dep['name']) == strtolower($package) &&
$depchannel == $channel) {
return true;
}
}
}
}
}
}
return false;
}
 
/**
* Get the contents of a dependency group
* @param string
* @return array|false
*/
function getDependencyGroup($name)
{
$name = strtolower($name);
if (!isset($this->_packageInfo['dependencies']['group'])) {
return false;
}
$groups = $this->_packageInfo['dependencies']['group'];
if (!isset($groups[0])) {
$groups = array($groups);
}
foreach ($groups as $group) {
if (strtolower($group['attribs']['name']) == $name) {
return $group;
}
}
return false;
}
 
/**
* Retrieve a partial package.xml 1.0 representation of dependencies
*
* a very limited representation of dependencies is returned by this method.
* The <exclude> tag for excluding certain versions of a dependency is
* completely ignored. In addition, dependency groups are ignored, with the
* assumption that all dependencies in dependency groups are also listed in
* the optional group that work with all dependency groups
* @param boolean return package.xml 2.0 <dependencies> tag
* @return array|false
*/
function getDeps($raw = false, $nopearinstaller = false)
{
if (isset($this->_packageInfo['dependencies'])) {
if ($raw) {
return $this->_packageInfo['dependencies'];
}
$ret = array();
$map = array(
'php' => 'php',
'package' => 'pkg',
'subpackage' => 'pkg',
'extension' => 'ext',
'os' => 'os',
'pearinstaller' => 'pkg',
);
foreach (array('required', 'optional') as $type) {
$optional = ($type == 'optional') ? 'yes' : 'no';
if (!isset($this->_packageInfo['dependencies'][$type])) {
continue;
}
foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) {
if ($dtype == 'pearinstaller' && $nopearinstaller) {
continue;
}
if (!isset($deps[0])) {
$deps = array($deps);
}
foreach ($deps as $dep) {
if (!isset($map[$dtype])) {
// no support for arch type
continue;
}
if ($dtype == 'pearinstaller') {
$dep['name'] = 'PEAR';
$dep['channel'] = 'pear.php.net';
}
$s = array('type' => $map[$dtype]);
if (isset($dep['channel'])) {
$s['channel'] = $dep['channel'];
}
if (isset($dep['uri'])) {
$s['uri'] = $dep['uri'];
}
if (isset($dep['name'])) {
$s['name'] = $dep['name'];
}
if (isset($dep['conflicts'])) {
$s['rel'] = 'not';
} else {
if (!isset($dep['min']) &&
!isset($dep['max'])) {
$s['rel'] = 'has';
$s['optional'] = $optional;
} elseif (isset($dep['min']) &&
isset($dep['max'])) {
$s['rel'] = 'ge';
$s1 = $s;
$s1['rel'] = 'le';
$s['version'] = $dep['min'];
$s1['version'] = $dep['max'];
if (isset($dep['channel'])) {
$s1['channel'] = $dep['channel'];
}
if ($dtype != 'php') {
$s['name'] = $dep['name'];
$s1['name'] = $dep['name'];
}
$s['optional'] = $optional;
$s1['optional'] = $optional;
$ret[] = $s1;
} elseif (isset($dep['min'])) {
if (isset($dep['exclude']) &&
$dep['exclude'] == $dep['min']) {
$s['rel'] = 'gt';
} else {
$s['rel'] = 'ge';
}
$s['version'] = $dep['min'];
$s['optional'] = $optional;
if ($dtype != 'php') {
$s['name'] = $dep['name'];
}
} elseif (isset($dep['max'])) {
if (isset($dep['exclude']) &&
$dep['exclude'] == $dep['max']) {
$s['rel'] = 'lt';
} else {
$s['rel'] = 'le';
}
$s['version'] = $dep['max'];
$s['optional'] = $optional;
if ($dtype != 'php') {
$s['name'] = $dep['name'];
}
}
}
$ret[] = $s;
}
}
}
if (count($ret)) {
return $ret;
}
}
return false;
}
 
/**
* @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false
*/
function getPackageType()
{
if (isset($this->_packageInfo['phprelease'])) {
return 'php';
}
if (isset($this->_packageInfo['extsrcrelease'])) {
return 'extsrc';
}
if (isset($this->_packageInfo['extbinrelease'])) {
return 'extbin';
}
if (isset($this->_packageInfo['zendextsrcrelease'])) {
return 'zendextsrc';
}
if (isset($this->_packageInfo['zendextbinrelease'])) {
return 'zendextbin';
}
if (isset($this->_packageInfo['bundle'])) {
return 'bundle';
}
return false;
}
 
/**
* @return array|false
*/
function getReleases()
{
$type = $this->getPackageType();
if ($type != 'bundle') {
$type .= 'release';
}
if ($this->getPackageType() && isset($this->_packageInfo[$type])) {
return $this->_packageInfo[$type];
}
return false;
}
 
/**
* @return array
*/
function getChangelog()
{
if (isset($this->_packageInfo['changelog'])) {
return $this->_packageInfo['changelog'];
}
return false;
}
 
function hasDeps()
{
return isset($this->_packageInfo['dependencies']);
}
 
function getPackagexmlVersion()
{
if (isset($this->_packageInfo['zendextsrcrelease'])) {
return '2.1';
}
if (isset($this->_packageInfo['zendextbinrelease'])) {
return '2.1';
}
return '2.0';
}
 
/**
* @return array|false
*/
function getSourcePackage()
{
if (isset($this->_packageInfo['extbinrelease']) ||
isset($this->_packageInfo['zendextbinrelease'])) {
return array('channel' => $this->_packageInfo['srcchannel'],
'package' => $this->_packageInfo['srcpackage']);
}
return false;
}
 
function getBundledPackages()
{
if (isset($this->_packageInfo['bundle'])) {
return $this->_packageInfo['contents']['bundledpackage'];
}
return false;
}
 
function getLastModified()
{
if (isset($this->_packageInfo['_lastmodified'])) {
return $this->_packageInfo['_lastmodified'];
}
return false;
}
 
/**
* Get the contents of a file listed within the package.xml
* @param string
* @return string
*/
function getFileContents($file)
{
if ($this->_archiveFile == $this->_packageFile) { // unpacked
$dir = dirname($this->_packageFile);
$file = $dir . DIRECTORY_SEPARATOR . $file;
$file = str_replace(array('/', '\\'),
array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
if (file_exists($file) && is_readable($file)) {
return implode('', file($file));
}
} else { // tgz
$tar = &new Archive_Tar($this->_archiveFile);
$tar->pushErrorHandling(PEAR_ERROR_RETURN);
if ($file != 'package.xml' && $file != 'package2.xml') {
$file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
}
$file = $tar->extractInString($file);
$tar->popErrorHandling();
if (PEAR::isError($file)) {
return PEAR::raiseError("Cannot locate file '$file' in archive");
}
return $file;
}
}
 
function &getRW()
{
if (!class_exists('PEAR_PackageFile_v2_rw')) {
require_once 'PEAR/PackageFile/v2/rw.php';
}
$a = new PEAR_PackageFile_v2_rw;
foreach (get_object_vars($this) as $name => $unused) {
if (!isset($this->$name)) {
continue;
}
if ($name == '_config' || $name == '_logger'|| $name == '_registry' ||
$name == '_stack') {
$a->$name = &$this->$name;
} else {
$a->$name = $this->$name;
}
}
return $a;
}
 
function &getDefaultGenerator()
{
if (!class_exists('PEAR_PackageFile_Generator_v2')) {
require_once 'PEAR/PackageFile/Generator/v2.php';
}
$a = &new PEAR_PackageFile_Generator_v2($this);
return $a;
}
 
function analyzeSourceCode($file, $string = false)
{
if (!isset($this->_v2Validator) ||
!is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) {
if (!class_exists('PEAR_PackageFile_v2_Validator')) {
require_once 'PEAR/PackageFile/v2/Validator.php';
}
$this->_v2Validator = new PEAR_PackageFile_v2_Validator;
}
return $this->_v2Validator->analyzeSourceCode($file, $string);
}
 
function validate($state = PEAR_VALIDATE_NORMAL)
{
if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) {
return false;
}
if (!isset($this->_v2Validator) ||
!is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) {
if (!class_exists('PEAR_PackageFile_v2_Validator')) {
require_once 'PEAR/PackageFile/v2/Validator.php';
}
$this->_v2Validator = new PEAR_PackageFile_v2_Validator;
}
if (isset($this->_packageInfo['xsdversion'])) {
unset($this->_packageInfo['xsdversion']);
}
return $this->_v2Validator->validate($this, $state);
}
 
function getTasksNs()
{
if (!isset($this->_tasksNs)) {
if (isset($this->_packageInfo['attribs'])) {
foreach ($this->_packageInfo['attribs'] as $name => $value) {
if ($value == 'http://pear.php.net/dtd/tasks-1.0') {
$this->_tasksNs = str_replace('xmlns:', '', $name);
break;
}
}
}
}
return $this->_tasksNs;
}
 
/**
* Determine whether a task name is a valid task. Custom tasks may be defined
* using subdirectories by putting a "-" in the name, as in <tasks:mycustom-task>
*
* Note that this method will auto-load the task class file and test for the existence
* of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class
* PEAR_Task_mycustom_task
* @param string
* @return boolean
*/
function getTask($task)
{
$this->getTasksNs();
// transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace
$task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task);
$task = str_replace(' ', '/', ucwords($task));
$ps = (strtolower(substr(PHP_OS, 0, 3)) == 'win') ? ';' : ':';
foreach (explode($ps, ini_get('include_path')) as $path) {
if (file_exists($path . "/PEAR/Task/$task.php")) {
include_once "PEAR/Task/$task.php";
$task = str_replace('/', '_', $task);
if (class_exists("PEAR_Task_$task")) {
return "PEAR_Task_$task";
}
}
}
return false;
}
 
/**
* Key-friendly array_splice
* @param tagname to splice a value in before
* @param mixed the value to splice in
* @param string the new tag name
*/
function _ksplice($array, $key, $value, $newkey)
{
$offset = array_search($key, array_keys($array));
$after = array_slice($array, $offset);
$before = array_slice($array, 0, $offset);
$before[$newkey] = $value;
return array_merge($before, $after);
}
 
/**
* @param array a list of possible keys, in the order they may occur
* @param mixed contents of the new package.xml tag
* @param string tag name
* @access private
*/
function _insertBefore($array, $keys, $contents, $newkey)
{
foreach ($keys as $key) {
if (isset($array[$key])) {
return $array = $this->_ksplice($array, $key, $contents, $newkey);
}
}
$array[$newkey] = $contents;
return $array;
}
 
/**
* @param subsection of {@link $_packageInfo}
* @param array|string tag contents
* @param array format:
* <pre>
* array(
* tagname => array(list of tag names that follow this one),
* childtagname => array(list of child tag names that follow this one),
* )
* </pre>
*
* This allows construction of nested tags
* @access private
*/
function _mergeTag($manip, $contents, $order)
{
if (count($order)) {
foreach ($order as $tag => $curorder) {
if (!isset($manip[$tag])) {
// ensure that the tag is set up
$manip = $this->_insertBefore($manip, $curorder, array(), $tag);
}
if (count($order) > 1) {
$manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1));
return $manip;
}
}
} else {
return $manip;
}
if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) {
$manip[$tag][] = $contents;
} else {
if (!count($manip[$tag])) {
$manip[$tag] = $contents;
} else {
$manip[$tag] = array($manip[$tag]);
$manip[$tag][] = $contents;
}
}
return $manip;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFile/Generator/v1.php
New file
0,0 → 1,1272
<?php
/**
* package.xml generation class, package.xml version 1.0
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v1.php,v 1.72 2006/05/10 02:56:19 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* needed for PEAR_VALIDATE_* constants
*/
require_once 'PEAR/Validate.php';
require_once 'System.php';
require_once 'PEAR/PackageFile/v2.php';
/**
* This class converts a PEAR_PackageFile_v1 object into any output format.
*
* Supported output formats include array, XML string, and a PEAR_PackageFile_v2
* object, for converting package.xml 1.0 into package.xml 2.0 with no sweat.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_PackageFile_Generator_v1
{
/**
* @var PEAR_PackageFile_v1
*/
var $_packagefile;
function PEAR_PackageFile_Generator_v1(&$packagefile)
{
$this->_packagefile = &$packagefile;
}
 
function getPackagerVersion()
{
return '1.5.1';
}
 
/**
* @param PEAR_Packager
* @param bool if true, a .tgz is written, otherwise a .tar is written
* @param string|null directory in which to save the .tgz
* @return string|PEAR_Error location of package or error object
*/
function toTgz(&$packager, $compress = true, $where = null)
{
require_once 'Archive/Tar.php';
if ($where === null) {
if (!($where = System::mktemp(array('-d')))) {
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: mktemp failed');
}
} elseif (!@System::mkDir(array('-p', $where))) {
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: "' . $where . '" could' .
' not be created');
}
if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') &&
!is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) {
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: unable to save package.xml as' .
' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"');
}
if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) {
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: invalid package file');
}
$pkginfo = $this->_packagefile->getArray();
$ext = $compress ? '.tgz' : '.tar';
$pkgver = $pkginfo['package'] . '-' . $pkginfo['version'];
$dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext;
if (file_exists(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext) &&
!is_file(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext)) {
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: cannot create tgz file "' .
getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext . '"');
}
if ($pkgfile = $this->_packagefile->getPackageFile()) {
$pkgdir = dirname(realpath($pkgfile));
$pkgfile = basename($pkgfile);
} else {
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: package file object must ' .
'be created from a real file');
}
// {{{ Create the package file list
$filelist = array();
$i = 0;
 
foreach ($this->_packagefile->getFilelist() as $fname => $atts) {
$file = $pkgdir . DIRECTORY_SEPARATOR . $fname;
if (!file_exists($file)) {
return PEAR::raiseError("File does not exist: $fname");
} else {
$filelist[$i++] = $file;
if (!isset($atts['md5sum'])) {
$this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($file));
}
$packager->log(2, "Adding file $fname");
}
}
// }}}
$packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true);
if ($packagexml) {
$tar =& new Archive_Tar($dest_package, $compress);
$tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors
// ----- Creates with the package.xml file
$ok = $tar->createModify(array($packagexml), '', $where);
if (PEAR::isError($ok)) {
return $ok;
} elseif (!$ok) {
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed');
}
// ----- Add the content of the package
if (!$tar->addModify($filelist, $pkgver, $pkgdir)) {
return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed');
}
return $dest_package;
}
}
 
/**
* @param string|null directory to place the package.xml in, or null for a temporary dir
* @param int one of the PEAR_VALIDATE_* constants
* @param string name of the generated file
* @param bool if true, then no analysis will be performed on role="php" files
* @return string|PEAR_Error path to the created file on success
*/
function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml',
$nofilechecking = false)
{
if (!$this->_packagefile->validate($state, $nofilechecking)) {
return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: invalid package.xml',
null, null, null, $this->_packagefile->getValidationWarnings());
}
if ($where === null) {
if (!($where = System::mktemp(array('-d')))) {
return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: mktemp failed');
}
} elseif (!@System::mkDir(array('-p', $where))) {
return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: "' . $where . '" could' .
' not be created');
}
$newpkgfile = $where . DIRECTORY_SEPARATOR . $name;
$np = @fopen($newpkgfile, 'wb');
if (!$np) {
return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: unable to save ' .
"$name as $newpkgfile");
}
fwrite($np, $this->toXml($state, true));
fclose($np);
return $newpkgfile;
}
 
/**
* fix both XML encoding to be UTF8, and replace standard XML entities < > " & '
*
* @param string $string
* @return string
* @access private
*/
function _fixXmlEncoding($string)
{
if (version_compare(phpversion(), '5.0.0', 'lt')) {
$string = utf8_encode($string);
}
return strtr($string, array(
'&' => '&amp;',
'>' => '&gt;',
'<' => '&lt;',
'"' => '&quot;',
'\'' => '&apos;' ));
}
 
/**
* Return an XML document based on the package info (as returned
* by the PEAR_Common::infoFrom* methods).
*
* @return string XML data
*/
function toXml($state = PEAR_VALIDATE_NORMAL, $nofilevalidation = false)
{
$this->_packagefile->setDate(date('Y-m-d'));
if (!$this->_packagefile->validate($state, $nofilevalidation)) {
return false;
}
$pkginfo = $this->_packagefile->getArray();
static $maint_map = array(
"handle" => "user",
"name" => "name",
"email" => "email",
"role" => "role",
);
$ret = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
$ret .= "<!DOCTYPE package SYSTEM \"http://pear.php.net/dtd/package-1.0\">\n";
$ret .= "<package version=\"1.0\" packagerversion=\"1.5.1\">\n" .
" <name>$pkginfo[package]</name>";
if (isset($pkginfo['extends'])) {
$ret .= "\n<extends>$pkginfo[extends]</extends>";
}
$ret .=
"\n <summary>".$this->_fixXmlEncoding($pkginfo['summary'])."</summary>\n" .
" <description>".trim($this->_fixXmlEncoding($pkginfo['description']))."\n </description>\n" .
" <maintainers>\n";
foreach ($pkginfo['maintainers'] as $maint) {
$ret .= " <maintainer>\n";
foreach ($maint_map as $idx => $elm) {
$ret .= " <$elm>";
$ret .= $this->_fixXmlEncoding($maint[$idx]);
$ret .= "</$elm>\n";
}
$ret .= " </maintainer>\n";
}
$ret .= " </maintainers>\n";
$ret .= $this->_makeReleaseXml($pkginfo, false, $state);
if (isset($pkginfo['changelog']) && count($pkginfo['changelog']) > 0) {
$ret .= " <changelog>\n";
foreach ($pkginfo['changelog'] as $oldrelease) {
$ret .= $this->_makeReleaseXml($oldrelease, true);
}
$ret .= " </changelog>\n";
}
$ret .= "</package>\n";
return $ret;
}
 
// }}}
// {{{ _makeReleaseXml()
 
/**
* Generate part of an XML description with release information.
*
* @param array $pkginfo array with release information
* @param bool $changelog whether the result will be in a changelog element
*
* @return string XML data
*
* @access private
*/
function _makeReleaseXml($pkginfo, $changelog = false, $state = PEAR_VALIDATE_NORMAL)
{
// XXX QUOTE ENTITIES IN PCDATA, OR EMBED IN CDATA BLOCKS!!
$indent = $changelog ? " " : "";
$ret = "$indent <release>\n";
if (!empty($pkginfo['version'])) {
$ret .= "$indent <version>$pkginfo[version]</version>\n";
}
if (!empty($pkginfo['release_date'])) {
$ret .= "$indent <date>$pkginfo[release_date]</date>\n";
}
if (!empty($pkginfo['release_license'])) {
$ret .= "$indent <license>$pkginfo[release_license]</license>\n";
}
if (!empty($pkginfo['release_state'])) {
$ret .= "$indent <state>$pkginfo[release_state]</state>\n";
}
if (!empty($pkginfo['release_notes'])) {
$ret .= "$indent <notes>".trim($this->_fixXmlEncoding($pkginfo['release_notes']))
."\n$indent </notes>\n";
}
if (!empty($pkginfo['release_warnings'])) {
$ret .= "$indent <warnings>".$this->_fixXmlEncoding($pkginfo['release_warnings'])."</warnings>\n";
}
if (isset($pkginfo['release_deps']) && sizeof($pkginfo['release_deps']) > 0) {
$ret .= "$indent <deps>\n";
foreach ($pkginfo['release_deps'] as $dep) {
$ret .= "$indent <dep type=\"$dep[type]\" rel=\"$dep[rel]\"";
if (isset($dep['version'])) {
$ret .= " version=\"$dep[version]\"";
}
if (isset($dep['optional'])) {
$ret .= " optional=\"$dep[optional]\"";
}
if (isset($dep['name'])) {
$ret .= ">$dep[name]</dep>\n";
} else {
$ret .= "/>\n";
}
}
$ret .= "$indent </deps>\n";
}
if (isset($pkginfo['configure_options'])) {
$ret .= "$indent <configureoptions>\n";
foreach ($pkginfo['configure_options'] as $c) {
$ret .= "$indent <configureoption name=\"".
$this->_fixXmlEncoding($c['name']) . "\"";
if (isset($c['default'])) {
$ret .= " default=\"" . $this->_fixXmlEncoding($c['default']) . "\"";
}
$ret .= " prompt=\"" . $this->_fixXmlEncoding($c['prompt']) . "\"";
$ret .= "/>\n";
}
$ret .= "$indent </configureoptions>\n";
}
if (isset($pkginfo['provides'])) {
foreach ($pkginfo['provides'] as $key => $what) {
$ret .= "$indent <provides type=\"$what[type]\" ";
$ret .= "name=\"$what[name]\" ";
if (isset($what['extends'])) {
$ret .= "extends=\"$what[extends]\" ";
}
$ret .= "/>\n";
}
}
if (isset($pkginfo['filelist'])) {
$ret .= "$indent <filelist>\n";
if ($state ^ PEAR_VALIDATE_PACKAGING) {
$ret .= $this->recursiveXmlFilelist($pkginfo['filelist']);
} else {
foreach ($pkginfo['filelist'] as $file => $fa) {
if (!isset($fa['role'])) {
$fa['role'] = '';
}
$ret .= "$indent <file role=\"$fa[role]\"";
if (isset($fa['baseinstalldir'])) {
$ret .= ' baseinstalldir="' .
$this->_fixXmlEncoding($fa['baseinstalldir']) . '"';
}
if (isset($fa['md5sum'])) {
$ret .= " md5sum=\"$fa[md5sum]\"";
}
if (isset($fa['platform'])) {
$ret .= " platform=\"$fa[platform]\"";
}
if (!empty($fa['install-as'])) {
$ret .= ' install-as="' .
$this->_fixXmlEncoding($fa['install-as']) . '"';
}
$ret .= ' name="' . $this->_fixXmlEncoding($file) . '"';
if (empty($fa['replacements'])) {
$ret .= "/>\n";
} else {
$ret .= ">\n";
foreach ($fa['replacements'] as $r) {
$ret .= "$indent <replace";
foreach ($r as $k => $v) {
$ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"';
}
$ret .= "/>\n";
}
$ret .= "$indent </file>\n";
}
}
}
$ret .= "$indent </filelist>\n";
}
$ret .= "$indent </release>\n";
return $ret;
}
 
/**
* @param array
* @access protected
*/
function recursiveXmlFilelist($list)
{
$this->_dirs = array();
foreach ($list as $file => $attributes) {
$this->_addDir($this->_dirs, explode('/', dirname($file)), $file, $attributes);
}
return $this->_formatDir($this->_dirs);
}
 
/**
* @param array
* @param array
* @param string|null
* @param array|null
* @access private
*/
function _addDir(&$dirs, $dir, $file = null, $attributes = null)
{
if ($dir == array() || $dir == array('.')) {
$dirs['files'][basename($file)] = $attributes;
return;
}
$curdir = array_shift($dir);
if (!isset($dirs['dirs'][$curdir])) {
$dirs['dirs'][$curdir] = array();
}
$this->_addDir($dirs['dirs'][$curdir], $dir, $file, $attributes);
}
 
/**
* @param array
* @param string
* @param string
* @access private
*/
function _formatDir($dirs, $indent = '', $curdir = '')
{
$ret = '';
if (!count($dirs)) {
return '';
}
if (isset($dirs['dirs'])) {
uksort($dirs['dirs'], 'strnatcasecmp');
foreach ($dirs['dirs'] as $dir => $contents) {
$usedir = "$curdir/$dir";
$ret .= "$indent <dir name=\"$dir\">\n";
$ret .= $this->_formatDir($contents, "$indent ", $usedir);
$ret .= "$indent </dir> <!-- $usedir -->\n";
}
}
if (isset($dirs['files'])) {
uksort($dirs['files'], 'strnatcasecmp');
foreach ($dirs['files'] as $file => $attribs) {
$ret .= $this->_formatFile($file, $attribs, $indent);
}
}
return $ret;
}
 
/**
* @param string
* @param array
* @param string
* @access private
*/
function _formatFile($file, $attributes, $indent)
{
$ret = "$indent <file role=\"$attributes[role]\"";
if (isset($attributes['baseinstalldir'])) {
$ret .= ' baseinstalldir="' .
$this->_fixXmlEncoding($attributes['baseinstalldir']) . '"';
}
if (isset($attributes['md5sum'])) {
$ret .= " md5sum=\"$attributes[md5sum]\"";
}
if (isset($attributes['platform'])) {
$ret .= " platform=\"$attributes[platform]\"";
}
if (!empty($attributes['install-as'])) {
$ret .= ' install-as="' .
$this->_fixXmlEncoding($attributes['install-as']) . '"';
}
$ret .= ' name="' . $this->_fixXmlEncoding($file) . '"';
if (empty($attributes['replacements'])) {
$ret .= "/>\n";
} else {
$ret .= ">\n";
foreach ($attributes['replacements'] as $r) {
$ret .= "$indent <replace";
foreach ($r as $k => $v) {
$ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"';
}
$ret .= "/>\n";
}
$ret .= "$indent </file>\n";
}
return $ret;
}
 
// {{{ _unIndent()
 
/**
* Unindent given string (?)
*
* @param string $str The string that has to be unindented.
* @return string
* @access private
*/
function _unIndent($str)
{
// remove leading newlines
$str = preg_replace('/^[\r\n]+/', '', $str);
// find whitespace at the beginning of the first line
$indent_len = strspn($str, " \t");
$indent = substr($str, 0, $indent_len);
$data = '';
// remove the same amount of whitespace from following lines
foreach (explode("\n", $str) as $line) {
if (substr($line, 0, $indent_len) == $indent) {
$data .= substr($line, $indent_len) . "\n";
}
}
return $data;
}
 
/**
* @return array
*/
function dependenciesToV2()
{
$arr = array();
$this->_convertDependencies2_0($arr);
return $arr['dependencies'];
}
 
/**
* Convert a package.xml version 1.0 into version 2.0
*
* Note that this does a basic conversion, to allow more advanced
* features like bundles and multiple releases
* @param string the classname to instantiate and return. This must be
* PEAR_PackageFile_v2 or a descendant
* @param boolean if true, only valid, deterministic package.xml 1.0 as defined by the
* strictest parameters will be converted
* @return PEAR_PackageFile_v2|PEAR_Error
*/
function &toV2($class = 'PEAR_PackageFile_v2', $strict = false)
{
if ($strict) {
if (!$this->_packagefile->validate()) {
$a = PEAR::raiseError('invalid package.xml version 1.0 cannot be converted' .
' to version 2.0', null, null, null,
$this->_packagefile->getValidationWarnings(true));
return $a;
}
}
$arr = array(
'attribs' => array(
'version' => '2.0',
'xmlns' => 'http://pear.php.net/dtd/package-2.0',
'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation' => "http://pear.php.net/dtd/tasks-1.0\n" .
"http://pear.php.net/dtd/tasks-1.0.xsd\n" .
"http://pear.php.net/dtd/package-2.0\n" .
'http://pear.php.net/dtd/package-2.0.xsd',
),
'name' => $this->_packagefile->getPackage(),
'channel' => 'pear.php.net',
);
$arr['summary'] = $this->_packagefile->getSummary();
$arr['description'] = $this->_packagefile->getDescription();
$maintainers = $this->_packagefile->getMaintainers();
foreach ($maintainers as $maintainer) {
if ($maintainer['role'] != 'lead') {
continue;
}
$new = array(
'name' => $maintainer['name'],
'user' => $maintainer['handle'],
'email' => $maintainer['email'],
'active' => 'yes',
);
$arr['lead'][] = $new;
}
if (!isset($arr['lead'])) { // some people... you know?
$arr['lead'] = array(
'name' => 'unknown',
'user' => 'unknown',
'email' => 'noleadmaintainer@example.com',
'active' => 'no',
);
}
if (count($arr['lead']) == 1) {
$arr['lead'] = $arr['lead'][0];
}
foreach ($maintainers as $maintainer) {
if ($maintainer['role'] == 'lead') {
continue;
}
$new = array(
'name' => $maintainer['name'],
'user' => $maintainer['handle'],
'email' => $maintainer['email'],
'active' => 'yes',
);
$arr[$maintainer['role']][] = $new;
}
if (isset($arr['developer']) && count($arr['developer']) == 1) {
$arr['developer'] = $arr['developer'][0];
}
if (isset($arr['contributor']) && count($arr['contributor']) == 1) {
$arr['contributor'] = $arr['contributor'][0];
}
if (isset($arr['helper']) && count($arr['helper']) == 1) {
$arr['helper'] = $arr['helper'][0];
}
$arr['date'] = $this->_packagefile->getDate();
$arr['version'] =
array(
'release' => $this->_packagefile->getVersion(),
'api' => $this->_packagefile->getVersion(),
);
$arr['stability'] =
array(
'release' => $this->_packagefile->getState(),
'api' => $this->_packagefile->getState(),
);
$licensemap =
array(
'php' => 'http://www.php.net/license',
'php license' => 'http://www.php.net/license',
'lgpl' => 'http://www.gnu.org/copyleft/lesser.html',
'bsd' => 'http://www.opensource.org/licenses/bsd-license.php',
'bsd style' => 'http://www.opensource.org/licenses/bsd-license.php',
'bsd-style' => 'http://www.opensource.org/licenses/bsd-license.php',
'mit' => 'http://www.opensource.org/licenses/mit-license.php',
'gpl' => 'http://www.gnu.org/copyleft/gpl.html',
'apache' => 'http://www.opensource.org/licenses/apache2.0.php'
);
if (isset($licensemap[strtolower($this->_packagefile->getLicense())])) {
$arr['license'] = array(
'attribs' => array('uri' =>
$licensemap[strtolower($this->_packagefile->getLicense())]),
'_content' => $this->_packagefile->getLicense()
);
} else {
// don't use bogus uri
$arr['license'] = $this->_packagefile->getLicense();
}
$arr['notes'] = $this->_packagefile->getNotes();
$temp = array();
$arr['contents'] = $this->_convertFilelist2_0($temp);
$this->_convertDependencies2_0($arr);
$release = ($this->_packagefile->getConfigureOptions() || $this->_isExtension) ?
'extsrcrelease' : 'phprelease';
if ($release == 'extsrcrelease') {
$arr['channel'] = 'pecl.php.net';
$arr['providesextension'] = $arr['name']; // assumption
}
$arr[$release] = array();
if ($this->_packagefile->getConfigureOptions()) {
$arr[$release]['configureoption'] = $this->_packagefile->getConfigureOptions();
foreach ($arr[$release]['configureoption'] as $i => $opt) {
$arr[$release]['configureoption'][$i] = array('attribs' => $opt);
}
if (count($arr[$release]['configureoption']) == 1) {
$arr[$release]['configureoption'] = $arr[$release]['configureoption'][0];
}
}
$this->_convertRelease2_0($arr[$release], $temp);
if ($release == 'extsrcrelease' && count($arr[$release]) > 1) {
// multiple extsrcrelease tags added in PEAR 1.4.1
$arr['dependencies']['required']['pearinstaller']['min'] = '1.4.1';
}
if ($cl = $this->_packagefile->getChangelog()) {
foreach ($cl as $release) {
$rel = array();
$rel['version'] =
array(
'release' => $release['version'],
'api' => $release['version'],
);
if (!isset($release['release_state'])) {
$release['release_state'] = 'stable';
}
$rel['stability'] =
array(
'release' => $release['release_state'],
'api' => $release['release_state'],
);
if (isset($release['release_date'])) {
$rel['date'] = $release['release_date'];
} else {
$rel['date'] = date('Y-m-d');
}
if (isset($release['release_license'])) {
if (isset($licensemap[strtolower($release['release_license'])])) {
$uri = $licensemap[strtolower($release['release_license'])];
} else {
$uri = 'http://www.example.com';
}
$rel['license'] = array(
'attribs' => array('uri' => $uri),
'_content' => $release['release_license']
);
} else {
$rel['license'] = $arr['license'];
}
if (!isset($release['release_notes'])) {
$release['release_notes'] = 'no release notes';
}
$rel['notes'] = $release['release_notes'];
$arr['changelog']['release'][] = $rel;
}
}
$ret = new $class;
$ret->setConfig($this->_packagefile->_config);
if (isset($this->_packagefile->_logger) && is_object($this->_packagefile->_logger)) {
$ret->setLogger($this->_packagefile->_logger);
}
$ret->fromArray($arr);
return $ret;
}
 
/**
* @param array
* @param bool
* @access private
*/
function _convertDependencies2_0(&$release, $internal = false)
{
$peardep = array('pearinstaller' =>
array('min' => '1.4.0b1')); // this is a lot safer
$required = $optional = array();
$release['dependencies'] = array();
if ($this->_packagefile->hasDeps()) {
foreach ($this->_packagefile->getDeps() as $dep) {
if (!isset($dep['optional']) || $dep['optional'] == 'no') {
$required[] = $dep;
} else {
$optional[] = $dep;
}
}
foreach (array('required', 'optional') as $arr) {
$deps = array();
foreach ($$arr as $dep) {
// organize deps by dependency type and name
if (!isset($deps[$dep['type']])) {
$deps[$dep['type']] = array();
}
if (isset($dep['name'])) {
$deps[$dep['type']][$dep['name']][] = $dep;
} else {
$deps[$dep['type']][] = $dep;
}
}
do {
if (isset($deps['php'])) {
$php = array();
if (count($deps['php']) > 1) {
$php = $this->_processPhpDeps($deps['php']);
} else {
if (!isset($deps['php'][0])) {
list($key, $blah) = each ($deps['php']); // stupid buggy versions
$deps['php'] = array($blah[0]);
}
$php = $this->_processDep($deps['php'][0]);
if (!$php) {
break; // poor mans throw
}
}
$release['dependencies'][$arr]['php'] = $php;
}
} while (false);
do {
if (isset($deps['pkg'])) {
$pkg = array();
$pkg = $this->_processMultipleDepsName($deps['pkg']);
if (!$pkg) {
break; // poor mans throw
}
$release['dependencies'][$arr]['package'] = $pkg;
}
} while (false);
do {
if (isset($deps['ext'])) {
$pkg = array();
$pkg = $this->_processMultipleDepsName($deps['ext']);
$release['dependencies'][$arr]['extension'] = $pkg;
}
} while (false);
// skip sapi - it's not supported so nobody will have used it
// skip os - it's not supported in 1.0
}
}
if (isset($release['dependencies']['required'])) {
$release['dependencies']['required'] =
array_merge($peardep, $release['dependencies']['required']);
} else {
$release['dependencies']['required'] = $peardep;
}
if (!isset($release['dependencies']['required']['php'])) {
$release['dependencies']['required']['php'] =
array('min' => '4.0.0');
}
$order = array();
$bewm = $release['dependencies']['required'];
$order['php'] = $bewm['php'];
$order['pearinstaller'] = $bewm['pearinstaller'];
isset($bewm['package']) ? $order['package'] = $bewm['package'] :0;
isset($bewm['extension']) ? $order['extension'] = $bewm['extension'] :0;
$release['dependencies']['required'] = $order;
}
 
/**
* @param array
* @access private
*/
function _convertFilelist2_0(&$package)
{
$ret = array('dir' =>
array(
'attribs' => array('name' => '/'),
'file' => array()
)
);
$package['platform'] =
$package['install-as'] = array();
$this->_isExtension = false;
foreach ($this->_packagefile->getFilelist() as $name => $file) {
$file['name'] = $name;
if (isset($file['role']) && $file['role'] == 'src') {
$this->_isExtension = true;
}
if (isset($file['replacements'])) {
$repl = $file['replacements'];
unset($file['replacements']);
} else {
unset($repl);
}
if (isset($file['install-as'])) {
$package['install-as'][$name] = $file['install-as'];
unset($file['install-as']);
}
if (isset($file['platform'])) {
$package['platform'][$name] = $file['platform'];
unset($file['platform']);
}
$file = array('attribs' => $file);
if (isset($repl)) {
foreach ($repl as $replace ) {
$file['tasks:replace'][] = array('attribs' => $replace);
}
if (count($repl) == 1) {
$file['tasks:replace'] = $file['tasks:replace'][0];
}
}
$ret['dir']['file'][] = $file;
}
return $ret;
}
 
/**
* Post-process special files with install-as/platform attributes and
* make the release tag.
*
* This complex method follows this work-flow to create the release tags:
*
* <pre>
* - if any install-as/platform exist, create a generic release and fill it with
* o <install as=..> tags for <file name=... install-as=...>
* o <install as=..> tags for <file name=... platform=!... install-as=..>
* o <ignore> tags for <file name=... platform=...>
* o <ignore> tags for <file name=... platform=... install-as=..>
* - create a release for each platform encountered and fill with
* o <install as..> tags for <file name=... install-as=...>
* o <install as..> tags for <file name=... platform=this platform install-as=..>
* o <install as..> tags for <file name=... platform=!other platform install-as=..>
* o <ignore> tags for <file name=... platform=!this platform>
* o <ignore> tags for <file name=... platform=other platform>
* o <ignore> tags for <file name=... platform=other platform install-as=..>
* o <ignore> tags for <file name=... platform=!this platform install-as=..>
* </pre>
*
* It does this by accessing the $package parameter, which contains an array with
* indices:
*
* - platform: mapping of file => OS the file should be installed on
* - install-as: mapping of file => installed name
* - osmap: mapping of OS => list of files that should be installed
* on that OS
* - notosmap: mapping of OS => list of files that should not be
* installed on that OS
*
* @param array
* @param array
* @access private
*/
function _convertRelease2_0(&$release, $package)
{
//- if any install-as/platform exist, create a generic release and fill it with
if (count($package['platform']) || count($package['install-as'])) {
$generic = array();
$genericIgnore = array();
foreach ($package['install-as'] as $file => $as) {
//o <install as=..> tags for <file name=... install-as=...>
if (!isset($package['platform'][$file])) {
$generic[] = $file;
continue;
}
//o <install as=..> tags for <file name=... platform=!... install-as=..>
if (isset($package['platform'][$file]) &&
$package['platform'][$file]{0} == '!') {
$generic[] = $file;
continue;
}
//o <ignore> tags for <file name=... platform=... install-as=..>
if (isset($package['platform'][$file]) &&
$package['platform'][$file]{0} != '!') {
$genericIgnore[] = $file;
continue;
}
}
foreach ($package['platform'] as $file => $platform) {
if (isset($package['install-as'][$file])) {
continue;
}
if ($platform{0} != '!') {
//o <ignore> tags for <file name=... platform=...>
$genericIgnore[] = $file;
}
}
if (count($package['platform'])) {
$oses = $notplatform = $platform = array();
foreach ($package['platform'] as $file => $os) {
// get a list of oses
if ($os{0} == '!') {
if (isset($oses[substr($os, 1)])) {
continue;
}
$oses[substr($os, 1)] = count($oses);
} else {
if (isset($oses[$os])) {
continue;
}
$oses[$os] = count($oses);
}
}
//- create a release for each platform encountered and fill with
foreach ($oses as $os => $releaseNum) {
$release[$releaseNum]['installconditions']['os']['name'] = $os;
$release[$releaseNum]['filelist'] = array('install' => array(),
'ignore' => array());
foreach ($package['install-as'] as $file => $as) {
//o <install as=..> tags for <file name=... install-as=...>
if (!isset($package['platform'][$file])) {
$release[$releaseNum]['filelist']['install'][] =
array(
'attribs' => array(
'name' => $file,
'as' => $as,
),
);
continue;
}
//o <install as..> tags for
// <file name=... platform=this platform install-as=..>
if (isset($package['platform'][$file]) &&
$package['platform'][$file] == $os) {
$release[$releaseNum]['filelist']['install'][] =
array(
'attribs' => array(
'name' => $file,
'as' => $as,
),
);
continue;
}
//o <install as..> tags for
// <file name=... platform=!other platform install-as=..>
if (isset($package['platform'][$file]) &&
$package['platform'][$file] != "!$os" &&
$package['platform'][$file]{0} == '!') {
$release[$releaseNum]['filelist']['install'][] =
array(
'attribs' => array(
'name' => $file,
'as' => $as,
),
);
continue;
}
//o <ignore> tags for
// <file name=... platform=!this platform install-as=..>
if (isset($package['platform'][$file]) &&
$package['platform'][$file] == "!$os") {
$release[$releaseNum]['filelist']['ignore'][] =
array(
'attribs' => array(
'name' => $file,
),
);
continue;
}
//o <ignore> tags for
// <file name=... platform=other platform install-as=..>
if (isset($package['platform'][$file]) &&
$package['platform'][$file]{0} != '!' &&
$package['platform'][$file] != $os) {
$release[$releaseNum]['filelist']['ignore'][] =
array(
'attribs' => array(
'name' => $file,
),
);
continue;
}
}
foreach ($package['platform'] as $file => $platform) {
if (isset($package['install-as'][$file])) {
continue;
}
//o <ignore> tags for <file name=... platform=!this platform>
if ($platform == "!$os") {
$release[$releaseNum]['filelist']['ignore'][] =
array(
'attribs' => array(
'name' => $file,
),
);
continue;
}
//o <ignore> tags for <file name=... platform=other platform>
if ($platform{0} != '!' && $platform != $os) {
$release[$releaseNum]['filelist']['ignore'][] =
array(
'attribs' => array(
'name' => $file,
),
);
}
}
if (!count($release[$releaseNum]['filelist']['install'])) {
unset($release[$releaseNum]['filelist']['install']);
}
if (!count($release[$releaseNum]['filelist']['ignore'])) {
unset($release[$releaseNum]['filelist']['ignore']);
}
}
if (count($generic) || count($genericIgnore)) {
$release[count($oses)] = array();
if (count($generic)) {
foreach ($generic as $file) {
if (isset($package['install-as'][$file])) {
$installas = $package['install-as'][$file];
} else {
$installas = $file;
}
$release[count($oses)]['filelist']['install'][] =
array(
'attribs' => array(
'name' => $file,
'as' => $installas,
)
);
}
}
if (count($genericIgnore)) {
foreach ($genericIgnore as $file) {
$release[count($oses)]['filelist']['ignore'][] =
array(
'attribs' => array(
'name' => $file,
)
);
}
}
}
// cleanup
foreach ($release as $i => $rel) {
if (isset($rel['filelist']['install']) &&
count($rel['filelist']['install']) == 1) {
$release[$i]['filelist']['install'] =
$release[$i]['filelist']['install'][0];
}
if (isset($rel['filelist']['ignore']) &&
count($rel['filelist']['ignore']) == 1) {
$release[$i]['filelist']['ignore'] =
$release[$i]['filelist']['ignore'][0];
}
}
if (count($release) == 1) {
$release = $release[0];
}
} else {
// no platform atts, but some install-as atts
foreach ($package['install-as'] as $file => $value) {
$release['filelist']['install'][] =
array(
'attribs' => array(
'name' => $file,
'as' => $value
)
);
}
if (count($release['filelist']['install']) == 1) {
$release['filelist']['install'] = $release['filelist']['install'][0];
}
}
}
}
 
/**
* @param array
* @return array
* @access private
*/
function _processDep($dep)
{
if ($dep['type'] == 'php') {
if ($dep['rel'] == 'has') {
// come on - everyone has php!
return false;
}
}
$php = array();
if ($dep['type'] != 'php') {
$php['name'] = $dep['name'];
if ($dep['type'] == 'pkg') {
$php['channel'] = 'pear.php.net';
}
}
switch ($dep['rel']) {
case 'gt' :
$php['min'] = $dep['version'];
$php['exclude'] = $dep['version'];
break;
case 'ge' :
if (!isset($dep['version'])) {
if ($dep['type'] == 'php') {
if (isset($dep['name'])) {
$dep['version'] = $dep['name'];
}
}
}
$php['min'] = $dep['version'];
break;
case 'lt' :
$php['max'] = $dep['version'];
$php['exclude'] = $dep['version'];
break;
case 'le' :
$php['max'] = $dep['version'];
break;
case 'eq' :
$php['min'] = $dep['version'];
$php['max'] = $dep['version'];
break;
case 'ne' :
$php['exclude'] = $dep['version'];
break;
case 'not' :
$php['conflicts'] = 'yes';
break;
}
return $php;
}
 
/**
* @param array
* @return array
*/
function _processPhpDeps($deps)
{
$test = array();
foreach ($deps as $dep) {
$test[] = $this->_processDep($dep);
}
$min = array();
$max = array();
foreach ($test as $dep) {
if (!$dep) {
continue;
}
if (isset($dep['min'])) {
$min[$dep['min']] = count($min);
}
if (isset($dep['max'])) {
$max[$dep['max']] = count($max);
}
}
if (count($min) > 0) {
uksort($min, 'version_compare');
}
if (count($max) > 0) {
uksort($max, 'version_compare');
}
if (count($min)) {
// get the highest minimum
$min = array_pop($a = array_flip($min));
} else {
$min = false;
}
if (count($max)) {
// get the lowest maximum
$max = array_shift($a = array_flip($max));
} else {
$max = false;
}
if ($min) {
$php['min'] = $min;
}
if ($max) {
$php['max'] = $max;
}
$exclude = array();
foreach ($test as $dep) {
if (!isset($dep['exclude'])) {
continue;
}
$exclude[] = $dep['exclude'];
}
if (count($exclude)) {
$php['exclude'] = $exclude;
}
return $php;
}
 
/**
* process multiple dependencies that have a name, like package deps
* @param array
* @return array
* @access private
*/
function _processMultipleDepsName($deps)
{
$tests = array();
foreach ($deps as $name => $dep) {
foreach ($dep as $d) {
$tests[$name][] = $this->_processDep($d);
}
}
foreach ($tests as $name => $test) {
$php = array();
$min = array();
$max = array();
$php['name'] = $name;
foreach ($test as $dep) {
if (!$dep) {
continue;
}
if (isset($dep['channel'])) {
$php['channel'] = 'pear.php.net';
}
if (isset($dep['conflicts']) && $dep['conflicts'] == 'yes') {
$php['conflicts'] = 'yes';
}
if (isset($dep['min'])) {
$min[$dep['min']] = count($min);
}
if (isset($dep['max'])) {
$max[$dep['max']] = count($max);
}
}
if (count($min) > 0) {
uksort($min, 'version_compare');
}
if (count($max) > 0) {
uksort($max, 'version_compare');
}
if (count($min)) {
// get the highest minimum
$min = array_pop($a = array_flip($min));
} else {
$min = false;
}
if (count($max)) {
// get the lowest maximum
$max = array_shift($a = array_flip($max));
} else {
$max = false;
}
if ($min) {
$php['min'] = $min;
}
if ($max) {
$php['max'] = $max;
}
$exclude = array();
foreach ($test as $dep) {
if (!isset($dep['exclude'])) {
continue;
}
$exclude[] = $dep['exclude'];
}
if (count($exclude)) {
$php['exclude'] = $exclude;
}
$ret[] = $php;
}
return $ret;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFile/Generator/v2.php
New file
0,0 → 1,1527
<?php
/**
* package.xml generation class, package.xml version 2.0
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Stephan Schmidt (original XML_Serializer code)
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v2.php,v 1.35 2006/03/25 21:09:08 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* file/dir manipulation routines
*/
require_once 'System.php';
/**
* This class converts a PEAR_PackageFile_v2 object into any output format.
*
* Supported output formats include array, XML string (using S. Schmidt's
* XML_Serializer, slightly customized)
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Stephan Schmidt (original XML_Serializer code)
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_PackageFile_Generator_v2
{
/**
* default options for the serialization
* @access private
* @var array $_defaultOptions
*/
var $_defaultOptions = array(
'indent' => ' ', // string used for indentation
'linebreak' => "\n", // string used for newlines
'typeHints' => false, // automatically add type hin attributes
'addDecl' => true, // add an XML declaration
'defaultTagName' => 'XML_Serializer_Tag', // tag used for indexed arrays or invalid names
'classAsTagName' => false, // use classname for objects in indexed arrays
'keyAttribute' => '_originalKey', // attribute where original key is stored
'typeAttribute' => '_type', // attribute for type (only if typeHints => true)
'classAttribute' => '_class', // attribute for class of objects (only if typeHints => true)
'scalarAsAttributes' => false, // scalar values (strings, ints,..) will be serialized as attribute
'prependAttributes' => '', // prepend string for attributes
'indentAttributes' => false, // indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column
'mode' => 'simplexml', // use 'simplexml' to use parent name as tagname if transforming an indexed array
'addDoctype' => false, // add a doctype declaration
'doctype' => null, // supply a string or an array with id and uri ({@see PEAR_PackageFile_Generator_v2_PEAR_PackageFile_Generator_v2_XML_Util::getDoctypeDeclaration()}
'rootName' => 'package', // name of the root tag
'rootAttributes' => array(
'version' => '2.0',
'xmlns' => 'http://pear.php.net/dtd/package-2.0',
'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0
http://pear.php.net/dtd/tasks-1.0.xsd
http://pear.php.net/dtd/package-2.0
http://pear.php.net/dtd/package-2.0.xsd',
), // attributes of the root tag
'attributesArray' => 'attribs', // all values in this key will be treated as attributes
'contentName' => '_content', // this value will be used directly as content, instead of creating a new tag, may only be used in conjuction with attributesArray
'beautifyFilelist' => false,
'encoding' => 'UTF-8',
);
 
/**
* options for the serialization
* @access private
* @var array $options
*/
var $options = array();
 
/**
* current tag depth
* @var integer $_tagDepth
*/
var $_tagDepth = 0;
 
/**
* serilialized representation of the data
* @var string $_serializedData
*/
var $_serializedData = null;
/**
* @var PEAR_PackageFile_v2
*/
var $_packagefile;
/**
* @param PEAR_PackageFile_v2
*/
function PEAR_PackageFile_Generator_v2(&$packagefile)
{
$this->_packagefile = &$packagefile;
}
 
/**
* @return string
*/
function getPackagerVersion()
{
return '1.5.1';
}
 
/**
* @param PEAR_Packager
* @param bool generate a .tgz or a .tar
* @param string|null temporary directory to package in
*/
function toTgz(&$packager, $compress = true, $where = null)
{
$a = null;
return $this->toTgz2($packager, $a, $compress, $where);
}
 
/**
* Package up both a package.xml and package2.xml for the same release
* @param PEAR_Packager
* @param PEAR_PackageFile_v1
* @param bool generate a .tgz or a .tar
* @param string|null temporary directory to package in
*/
function toTgz2(&$packager, &$pf1, $compress = true, $where = null)
{
require_once 'Archive/Tar.php';
if (!$this->_packagefile->isEquivalent($pf1)) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' .
basename($pf1->getPackageFile()) .
'" is not equivalent to "' . basename($this->_packagefile->getPackageFile())
. '"');
}
if ($where === null) {
if (!($where = System::mktemp(array('-d')))) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: mktemp failed');
}
} elseif (!@System::mkDir(array('-p', $where))) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . $where . '" could' .
' not be created');
}
if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') &&
!is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' .
' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"');
}
if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: invalid package.xml');
}
$ext = $compress ? '.tgz' : '.tar';
$pkgver = $this->_packagefile->getPackage() . '-' . $this->_packagefile->getVersion();
$dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext;
if (file_exists(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext) &&
!is_file(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext)) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' .
getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext . '"');
}
if ($pkgfile = $this->_packagefile->getPackageFile()) {
$pkgdir = dirname(realpath($pkgfile));
$pkgfile = basename($pkgfile);
} else {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: package file object must ' .
'be created from a real file');
}
// {{{ Create the package file list
$filelist = array();
$i = 0;
$this->_packagefile->flattenFilelist();
$contents = $this->_packagefile->getContents();
if (isset($contents['bundledpackage'])) { // bundles of packages
$contents = $contents['bundledpackage'];
if (!isset($contents[0])) {
$contents = array($contents);
}
$packageDir = $where;
foreach ($contents as $i => $package) {
$fname = $package;
$file = $pkgdir . DIRECTORY_SEPARATOR . $fname;
if (!file_exists($file)) {
return $packager->raiseError("File does not exist: $fname");
}
$tfile = $packageDir . DIRECTORY_SEPARATOR . $fname;
System::mkdir(array('-p', dirname($tfile)));
copy($file, $tfile);
$filelist[$i++] = $tfile;
$packager->log(2, "Adding package $fname");
}
} else { // normal packages
$contents = $contents['dir']['file'];
if (!isset($contents[0])) {
$contents = array($contents);
}
$packageDir = $where;
foreach ($contents as $i => $file) {
$fname = $file['attribs']['name'];
$atts = $file['attribs'];
$orig = $file;
$file = $pkgdir . DIRECTORY_SEPARATOR . $fname;
if (!file_exists($file)) {
return $packager->raiseError("File does not exist: $fname");
} else {
$tfile = $packageDir . DIRECTORY_SEPARATOR . $fname;
unset($orig['attribs']);
if (count($orig)) { // file with tasks
// run any package-time tasks
$contents = file_get_contents($file);
foreach ($orig as $tag => $raw) {
$tag = str_replace($this->_packagefile->getTasksNs() . ':', '', $tag);
$task = "PEAR_Task_$tag";
$task = &new $task($this->_packagefile->_config,
$this->_packagefile->_logger,
PEAR_TASK_PACKAGE);
$task->init($raw, $atts, null);
$res = $task->startSession($this->_packagefile, $contents, $tfile);
if (!$res) {
continue; // skip this task
}
if (PEAR::isError($res)) {
return $res;
}
$contents = $res; // save changes
System::mkdir(array('-p', dirname($tfile)));
$wp = fopen($tfile, "wb");
fwrite($wp, $contents);
fclose($wp);
}
}
if (!file_exists($tfile)) {
System::mkdir(array('-p', dirname($tfile)));
copy($file, $tfile);
}
$filelist[$i++] = $tfile;
$this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($tfile), $i - 1);
$packager->log(2, "Adding file $fname");
}
}
}
// }}}
if ($pf1 !== null) {
$name = 'package2.xml';
} else {
$name = 'package.xml';
}
$packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, $name);
if ($packagexml) {
$tar =& new Archive_Tar($dest_package, $compress);
$tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors
// ----- Creates with the package.xml file
$ok = $tar->createModify(array($packagexml), '', $where);
if (PEAR::isError($ok)) {
return $packager->raiseError($ok);
} elseif (!$ok) {
return $packager->raiseError('PEAR_Packagefile_v2::toTgz(): adding ' . $name .
' failed');
}
// ----- Add the content of the package
if (!$tar->addModify($filelist, $pkgver, $where)) {
return $packager->raiseError(
'PEAR_Packagefile_v2::toTgz(): tarball creation failed');
}
// add the package.xml version 1.0
if ($pf1 !== null) {
$pfgen = &$pf1->getDefaultGenerator();
$packagexml1 = $pfgen->toPackageFile($where, PEAR_VALIDATE_PACKAGING,
'package.xml', true);
if (!$tar->addModify(array($packagexml1), '', $where)) {
return $packager->raiseError(
'PEAR_Packagefile_v2::toTgz(): adding package.xml failed');
}
}
return $dest_package;
}
}
 
function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml')
{
if (!$this->_packagefile->validate($state)) {
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: invalid package.xml',
null, null, null, $this->_packagefile->getValidationWarnings());
}
if ($where === null) {
if (!($where = System::mktemp(array('-d')))) {
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: mktemp failed');
}
} elseif (!@System::mkDir(array('-p', $where))) {
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' . $where . '" could' .
' not be created');
}
$newpkgfile = $where . DIRECTORY_SEPARATOR . $name;
$np = @fopen($newpkgfile, 'wb');
if (!$np) {
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: unable to save ' .
"$name as $newpkgfile");
}
fwrite($np, $this->toXml($state));
fclose($np);
return $newpkgfile;
}
 
function &toV2()
{
return $this->_packagefile;
}
 
/**
* Return an XML document based on the package info (as returned
* by the PEAR_Common::infoFrom* methods).
*
* @return string XML data
*/
function toXml($state = PEAR_VALIDATE_NORMAL, $options = array())
{
$this->_packagefile->setDate(date('Y-m-d'));
$this->_packagefile->setTime(date('H:i:s'));
if (!$this->_packagefile->validate($state)) {
return false;
}
if (is_array($options)) {
$this->options = array_merge($this->_defaultOptions, $options);
} else {
$this->options = $this->_defaultOptions;
}
$arr = $this->_packagefile->getArray();
if (isset($arr['filelist'])) {
unset($arr['filelist']);
}
if (isset($arr['_lastversion'])) {
unset($arr['_lastversion']);
}
if ($state ^ PEAR_VALIDATE_PACKAGING && !isset($arr['bundle'])) {
$use = $this->_recursiveXmlFilelist($arr['contents']['dir']['file']);
unset($arr['contents']['dir']['file']);
if (isset($use['dir'])) {
$arr['contents']['dir']['dir'] = $use['dir'];
}
if (isset($use['file'])) {
$arr['contents']['dir']['file'] = $use['file'];
}
$this->options['beautifyFilelist'] = true;
}
$arr['attribs']['packagerversion'] = '1.5.1';
if ($this->serialize($arr, $options)) {
return $this->_serializedData . "\n";
}
return false;
}
 
 
function _recursiveXmlFilelist($list)
{
$dirs = array();
if (isset($list['attribs'])) {
$file = $list['attribs']['name'];
unset($list['attribs']['name']);
$attributes = $list['attribs'];
$this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes);
} else {
foreach ($list as $a) {
$file = $a['attribs']['name'];
$attributes = $a['attribs'];
unset($a['attribs']);
$this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes, $a);
}
}
$this->_formatDir($dirs);
$this->_deFormat($dirs);
return $dirs;
}
 
function _addDir(&$dirs, $dir, $file = null, $attributes = null, $tasks = null)
{
if (!$tasks) {
$tasks = array();
}
if ($dir == array() || $dir == array('.')) {
$dirs['file'][basename($file)] = $tasks;
$attributes['name'] = basename($file);
$dirs['file'][basename($file)]['attribs'] = $attributes;
return;
}
$curdir = array_shift($dir);
if (!isset($dirs['dir'][$curdir])) {
$dirs['dir'][$curdir] = array();
}
$this->_addDir($dirs['dir'][$curdir], $dir, $file, $attributes, $tasks);
}
 
function _formatDir(&$dirs)
{
if (!count($dirs)) {
return array();
}
$newdirs = array();
if (isset($dirs['dir'])) {
$newdirs['dir'] = $dirs['dir'];
}
if (isset($dirs['file'])) {
$newdirs['file'] = $dirs['file'];
}
$dirs = $newdirs;
if (isset($dirs['dir'])) {
uksort($dirs['dir'], 'strnatcasecmp');
foreach ($dirs['dir'] as $dir => $contents) {
$this->_formatDir($dirs['dir'][$dir]);
}
}
if (isset($dirs['file'])) {
uksort($dirs['file'], 'strnatcasecmp');
};
}
 
function _deFormat(&$dirs)
{
if (!count($dirs)) {
return array();
}
$newdirs = array();
if (isset($dirs['dir'])) {
foreach ($dirs['dir'] as $dir => $contents) {
$newdir = array();
$newdir['attribs']['name'] = $dir;
$this->_deFormat($contents);
foreach ($contents as $tag => $val) {
$newdir[$tag] = $val;
}
$newdirs['dir'][] = $newdir;
}
if (count($newdirs['dir']) == 1) {
$newdirs['dir'] = $newdirs['dir'][0];
}
}
if (isset($dirs['file'])) {
foreach ($dirs['file'] as $name => $file) {
$newdirs['file'][] = $file;
}
if (count($newdirs['file']) == 1) {
$newdirs['file'] = $newdirs['file'][0];
}
}
$dirs = $newdirs;
}
 
/**
* reset all options to default options
*
* @access public
* @see setOption(), XML_Unserializer()
*/
function resetOptions()
{
$this->options = $this->_defaultOptions;
}
 
/**
* set an option
*
* You can use this method if you do not want to set all options in the constructor
*
* @access public
* @see resetOption(), XML_Serializer()
*/
function setOption($name, $value)
{
$this->options[$name] = $value;
}
/**
* sets several options at once
*
* You can use this method if you do not want to set all options in the constructor
*
* @access public
* @see resetOption(), XML_Unserializer(), setOption()
*/
function setOptions($options)
{
$this->options = array_merge($this->options, $options);
}
 
/**
* serialize data
*
* @access public
* @param mixed $data data to serialize
* @return boolean true on success, pear error on failure
*/
function serialize($data, $options = null)
{
// if options have been specified, use them instead
// of the previously defined ones
if (is_array($options)) {
$optionsBak = $this->options;
if (isset($options['overrideOptions']) && $options['overrideOptions'] == true) {
$this->options = array_merge($this->_defaultOptions, $options);
} else {
$this->options = array_merge($this->options, $options);
}
}
else {
$optionsBak = null;
}
// start depth is zero
$this->_tagDepth = 0;
 
$this->_serializedData = '';
// serialize an array
if (is_array($data)) {
if (isset($this->options['rootName'])) {
$tagName = $this->options['rootName'];
} else {
$tagName = 'array';
}
 
$this->_serializedData .= $this->_serializeArray($data, $tagName, $this->options['rootAttributes']);
}
// add doctype declaration
if ($this->options['addDoctype'] === true) {
$this->_serializedData = PEAR_PackageFile_Generator_v2_XML_Util::getDoctypeDeclaration($tagName, $this->options['doctype'])
. $this->options['linebreak']
. $this->_serializedData;
}
 
// build xml declaration
if ($this->options['addDecl']) {
$atts = array();
if (isset($this->options['encoding']) ) {
$encoding = $this->options['encoding'];
} else {
$encoding = null;
}
$this->_serializedData = PEAR_PackageFile_Generator_v2_XML_Util::getXMLDeclaration('1.0', $encoding)
. $this->options['linebreak']
. $this->_serializedData;
}
if ($optionsBak !== null) {
$this->options = $optionsBak;
}
return true;
}
 
/**
* get the result of the serialization
*
* @access public
* @return string serialized XML
*/
function getSerializedData()
{
if ($this->_serializedData == null ) {
return $this->raiseError('No serialized data available. Use XML_Serializer::serialize() first.', XML_SERIALIZER_ERROR_NO_SERIALIZATION);
}
return $this->_serializedData;
}
/**
* serialize any value
*
* This method checks for the type of the value and calls the appropriate method
*
* @access private
* @param mixed $value
* @param string $tagName
* @param array $attributes
* @return string
*/
function _serializeValue($value, $tagName = null, $attributes = array())
{
if (is_array($value)) {
$xml = $this->_serializeArray($value, $tagName, $attributes);
} elseif (is_object($value)) {
$xml = $this->_serializeObject($value, $tagName);
} else {
$tag = array(
'qname' => $tagName,
'attributes' => $attributes,
'content' => $value
);
$xml = $this->_createXMLTag($tag);
}
return $xml;
}
/**
* serialize an array
*
* @access private
* @param array $array array to serialize
* @param string $tagName name of the root tag
* @param array $attributes attributes for the root tag
* @return string $string serialized data
* @uses PEAR_PackageFile_Generator_v2_XML_Util::isValidName() to check, whether key has to be substituted
*/
function _serializeArray(&$array, $tagName = null, $attributes = array())
{
$_content = null;
/**
* check for special attributes
*/
if ($this->options['attributesArray'] !== null) {
if (isset($array[$this->options['attributesArray']])) {
$attributes = $array[$this->options['attributesArray']];
unset($array[$this->options['attributesArray']]);
}
/**
* check for special content
*/
if ($this->options['contentName'] !== null) {
if (isset($array[$this->options['contentName']])) {
$_content = $array[$this->options['contentName']];
unset($array[$this->options['contentName']]);
}
}
}
 
/*
* if mode is set to simpleXML, check whether
* the array is associative or indexed
*/
if (is_array($array) && $this->options['mode'] == 'simplexml') {
$indexed = true;
if (!count($array)) {
$indexed = false;
}
foreach ($array as $key => $val) {
if (!is_int($key)) {
$indexed = false;
break;
}
}
 
if ($indexed && $this->options['mode'] == 'simplexml') {
$string = '';
foreach ($array as $key => $val) {
if ($this->options['beautifyFilelist'] && $tagName == 'dir') {
if (!isset($this->_curdir)) {
$this->_curdir = '';
}
$savedir = $this->_curdir;
if (isset($val['attribs'])) {
if ($val['attribs']['name'] == '/') {
$this->_curdir = '/';
} else {
if ($this->_curdir == '/') {
$this->_curdir = '';
}
$this->_curdir .= '/' . $val['attribs']['name'];
}
}
}
$string .= $this->_serializeValue( $val, $tagName, $attributes);
if ($this->options['beautifyFilelist'] && $tagName == 'dir') {
$string .= ' <!-- ' . $this->_curdir . ' -->';
if (empty($savedir)) {
unset($this->_curdir);
} else {
$this->_curdir = $savedir;
}
}
$string .= $this->options['linebreak'];
// do indentation
if ($this->options['indent']!==null && $this->_tagDepth>0) {
$string .= str_repeat($this->options['indent'], $this->_tagDepth);
}
}
return rtrim($string);
}
}
if ($this->options['scalarAsAttributes'] === true) {
foreach ($array as $key => $value) {
if (is_scalar($value) && (PEAR_PackageFile_Generator_v2_XML_Util::isValidName($key) === true)) {
unset($array[$key]);
$attributes[$this->options['prependAttributes'].$key] = $value;
}
}
}
 
// check for empty array => create empty tag
if (empty($array)) {
$tag = array(
'qname' => $tagName,
'content' => $_content,
'attributes' => $attributes
);
 
} else {
$this->_tagDepth++;
$tmp = $this->options['linebreak'];
foreach ($array as $key => $value) {
// do indentation
if ($this->options['indent']!==null && $this->_tagDepth>0) {
$tmp .= str_repeat($this->options['indent'], $this->_tagDepth);
}
// copy key
$origKey = $key;
// key cannot be used as tagname => use default tag
$valid = PEAR_PackageFile_Generator_v2_XML_Util::isValidName($key);
if (PEAR::isError($valid)) {
if ($this->options['classAsTagName'] && is_object($value)) {
$key = get_class($value);
} else {
$key = $this->options['defaultTagName'];
}
}
$atts = array();
if ($this->options['typeHints'] === true) {
$atts[$this->options['typeAttribute']] = gettype($value);
if ($key !== $origKey) {
$atts[$this->options['keyAttribute']] = (string)$origKey;
}
}
if ($this->options['beautifyFilelist'] && $key == 'dir') {
if (!isset($this->_curdir)) {
$this->_curdir = '';
}
$savedir = $this->_curdir;
if (isset($value['attribs'])) {
if ($value['attribs']['name'] == '/') {
$this->_curdir = '/';
} else {
$this->_curdir .= '/' . $value['attribs']['name'];
}
}
}
 
if (is_string($value) && $value && ($value{strlen($value) - 1} == "\n")) {
$value .= str_repeat($this->options['indent'], $this->_tagDepth);
}
$tmp .= $this->_createXMLTag(array(
'qname' => $key,
'attributes' => $atts,
'content' => $value )
);
if ($this->options['beautifyFilelist'] && $key == 'dir') {
if (isset($value['attribs'])) {
$tmp .= ' <!-- ' . $this->_curdir . ' -->';
if (empty($savedir)) {
unset($this->_curdir);
} else {
$this->_curdir = $savedir;
}
}
}
$tmp .= $this->options['linebreak'];
}
$this->_tagDepth--;
if ($this->options['indent']!==null && $this->_tagDepth>0) {
$tmp .= str_repeat($this->options['indent'], $this->_tagDepth);
}
if (trim($tmp) === '') {
$tmp = null;
}
$tag = array(
'qname' => $tagName,
'content' => $tmp,
'attributes' => $attributes
);
}
if ($this->options['typeHints'] === true) {
if (!isset($tag['attributes'][$this->options['typeAttribute']])) {
$tag['attributes'][$this->options['typeAttribute']] = 'array';
}
}
 
$string = $this->_createXMLTag($tag, false);
return $string;
}
/**
* create a tag from an array
* this method awaits an array in the following format
* array(
* 'qname' => $tagName,
* 'attributes' => array(),
* 'content' => $content, // optional
* 'namespace' => $namespace // optional
* 'namespaceUri' => $namespaceUri // optional
* )
*
* @access private
* @param array $tag tag definition
* @param boolean $replaceEntities whether to replace XML entities in content or not
* @return string $string XML tag
*/
function _createXMLTag( $tag, $replaceEntities = true )
{
if ($this->options['indentAttributes'] !== false) {
$multiline = true;
$indent = str_repeat($this->options['indent'], $this->_tagDepth);
 
if ($this->options['indentAttributes'] == '_auto') {
$indent .= str_repeat(' ', (strlen($tag['qname'])+2));
 
} else {
$indent .= $this->options['indentAttributes'];
}
} else {
$multiline = false;
$indent = false;
}
if (is_array($tag['content'])) {
if (empty($tag['content'])) {
$tag['content'] = '';
}
} elseif(is_scalar($tag['content']) && (string)$tag['content'] == '') {
$tag['content'] = '';
}
if (is_scalar($tag['content']) || is_null($tag['content'])) {
if ($this->options['encoding'] == 'UTF-8' &&
version_compare(phpversion(), '5.0.0', 'lt')) {
$encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_UTF8_XML;
} else {
$encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML;
}
$tag = PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak'], $encoding);
} elseif (is_array($tag['content'])) {
$tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']);
} elseif (is_object($tag['content'])) {
$tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']);
} elseif (is_resource($tag['content'])) {
settype($tag['content'], 'string');
$tag = PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag, $replaceEntities);
}
return $tag;
}
}
 
// well, it's one way to do things without extra deps ...
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Stephan Schmidt <schst@php-tools.net> |
// +----------------------------------------------------------------------+
//
// $Id: v2.php,v 1.35 2006/03/25 21:09:08 cellog Exp $
 
/**
* error code for invalid chars in XML name
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_CHARS", 51);
 
/**
* error code for invalid chars in XML name
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_START", 52);
 
/**
* error code for non-scalar tag content
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NON_SCALAR_CONTENT", 60);
/**
* error code for missing tag name
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NO_TAG_NAME", 61);
/**
* replace XML entities
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES", 1);
 
/**
* embedd content in a CData Section
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_CDATA_SECTION", 2);
 
/**
* do not replace entitites
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE", 0);
 
/**
* replace all XML entitites
* This setting will replace <, >, ", ' and &
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML", 1);
 
/**
* replace only required XML entitites
* This setting will replace <, " and &
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED", 2);
 
/**
* replace HTML entitites
* @link http://www.php.net/htmlentities
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML", 3);
 
/**
* replace all XML entitites, and encode from ISO-8859-1 to UTF-8
* This setting will replace <, >, ", ' and &
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_UTF8_XML", 4);
 
/**
* utility class for working with XML documents
*
* customized version of XML_Util 0.6.0
*
* @category XML
* @package PEAR
* @version 0.6.0
* @author Stephan Schmidt <schst@php.net>
* @author Gregory Beaver <cellog@php.net>
*/
class PEAR_PackageFile_Generator_v2_XML_Util {
 
/**
* return API version
*
* @access public
* @static
* @return string $version API version
*/
function apiVersion()
{
return "0.6";
}
 
/**
* replace XML entities
*
* With the optional second parameter, you may select, which
* entities should be replaced.
*
* <code>
* require_once 'XML/Util.php';
*
* // replace XML entites:
* $string = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities("This string contains < & >.");
* </code>
*
* @access public
* @static
* @param string string where XML special chars should be replaced
* @param integer setting for entities in attribute values (one of PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML)
* @return string string with replaced chars
*/
function replaceEntities($string, $replaceEntities = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML)
{
switch ($replaceEntities) {
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_UTF8_XML:
return strtr(utf8_encode($string),array(
'&' => '&amp;',
'>' => '&gt;',
'<' => '&lt;',
'"' => '&quot;',
'\'' => '&apos;' ));
break;
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML:
return strtr($string,array(
'&' => '&amp;',
'>' => '&gt;',
'<' => '&lt;',
'"' => '&quot;',
'\'' => '&apos;' ));
break;
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED:
return strtr($string,array(
'&' => '&amp;',
'<' => '&lt;',
'"' => '&quot;' ));
break;
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML:
return htmlspecialchars($string);
break;
}
return $string;
}
 
/**
* build an xml declaration
*
* <code>
* require_once 'XML/Util.php';
*
* // get an XML declaration:
* $xmlDecl = PEAR_PackageFile_Generator_v2_XML_Util::getXMLDeclaration("1.0", "UTF-8", true);
* </code>
*
* @access public
* @static
* @param string $version xml version
* @param string $encoding character encoding
* @param boolean $standAlone document is standalone (or not)
* @return string $decl xml declaration
* @uses PEAR_PackageFile_Generator_v2_XML_Util::attributesToString() to serialize the attributes of the XML declaration
*/
function getXMLDeclaration($version = "1.0", $encoding = null, $standalone = null)
{
$attributes = array(
"version" => $version,
);
// add encoding
if ($encoding !== null) {
$attributes["encoding"] = $encoding;
}
// add standalone, if specified
if ($standalone !== null) {
$attributes["standalone"] = $standalone ? "yes" : "no";
}
return sprintf("<?xml%s?>", PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($attributes, false));
}
 
/**
* build a document type declaration
*
* <code>
* require_once 'XML/Util.php';
*
* // get a doctype declaration:
* $xmlDecl = PEAR_PackageFile_Generator_v2_XML_Util::getDocTypeDeclaration("rootTag","myDocType.dtd");
* </code>
*
* @access public
* @static
* @param string $root name of the root tag
* @param string $uri uri of the doctype definition (or array with uri and public id)
* @param string $internalDtd internal dtd entries
* @return string $decl doctype declaration
* @since 0.2
*/
function getDocTypeDeclaration($root, $uri = null, $internalDtd = null)
{
if (is_array($uri)) {
$ref = sprintf( ' PUBLIC "%s" "%s"', $uri["id"], $uri["uri"] );
} elseif (!empty($uri)) {
$ref = sprintf( ' SYSTEM "%s"', $uri );
} else {
$ref = "";
}
 
if (empty($internalDtd)) {
return sprintf("<!DOCTYPE %s%s>", $root, $ref);
} else {
return sprintf("<!DOCTYPE %s%s [\n%s\n]>", $root, $ref, $internalDtd);
}
}
 
/**
* create string representation of an attribute list
*
* <code>
* require_once 'XML/Util.php';
*
* // build an attribute string
* $att = array(
* "foo" => "bar",
* "argh" => "tomato"
* );
*
* $attList = PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($att);
* </code>
*
* @access public
* @static
* @param array $attributes attribute array
* @param boolean|array $sort sort attribute list alphabetically, may also be an assoc array containing the keys 'sort', 'multiline', 'indent', 'linebreak' and 'entities'
* @param boolean $multiline use linebreaks, if more than one attribute is given
* @param string $indent string used for indentation of multiline attributes
* @param string $linebreak string used for linebreaks of multiline attributes
* @param integer $entities setting for entities in attribute values (one of PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML)
* @return string string representation of the attributes
* @uses PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities() to replace XML entities in attribute values
* @todo allow sort also to be an options array
*/
function attributesToString($attributes, $sort = true, $multiline = false, $indent = ' ', $linebreak = "\n", $entities = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML)
{
/**
* second parameter may be an array
*/
if (is_array($sort)) {
if (isset($sort['multiline'])) {
$multiline = $sort['multiline'];
}
if (isset($sort['indent'])) {
$indent = $sort['indent'];
}
if (isset($sort['linebreak'])) {
$multiline = $sort['linebreak'];
}
if (isset($sort['entities'])) {
$entities = $sort['entities'];
}
if (isset($sort['sort'])) {
$sort = $sort['sort'];
} else {
$sort = true;
}
}
$string = '';
if (is_array($attributes) && !empty($attributes)) {
if ($sort) {
ksort($attributes);
}
if( !$multiline || count($attributes) == 1) {
foreach ($attributes as $key => $value) {
if ($entities != PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE) {
$value = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities($value, $entities);
}
$string .= ' '.$key.'="'.$value.'"';
}
} else {
$first = true;
foreach ($attributes as $key => $value) {
if ($entities != PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE) {
$value = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities($value, $entities);
}
if ($first) {
$string .= " ".$key.'="'.$value.'"';
$first = false;
} else {
$string .= $linebreak.$indent.$key.'="'.$value.'"';
}
}
}
}
return $string;
}
 
/**
* create a tag
*
* This method will call PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray(), which
* is more flexible.
*
* <code>
* require_once 'XML/Util.php';
*
* // create an XML tag:
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createTag("myNs:myTag", array("foo" => "bar"), "This is inside the tag", "http://www.w3c.org/myNs#");
* </code>
*
* @access public
* @static
* @param string $qname qualified tagname (including namespace)
* @param array $attributes array containg attributes
* @param mixed $content
* @param string $namespaceUri URI of the namespace
* @param integer $replaceEntities whether to replace XML special chars in content, embedd it in a CData section or none of both
* @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line
* @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column)
* @param string $linebreak string used for linebreaks
* @param string $encoding encoding that should be used to translate content
* @return string $string XML tag
* @see PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray()
* @uses PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray() to create the tag
*/
function createTag($qname, $attributes = array(), $content = null, $namespaceUri = null, $replaceEntities = PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES, $multiline = false, $indent = "_auto", $linebreak = "\n", $encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML)
{
$tag = array(
"qname" => $qname,
"attributes" => $attributes
);
 
// add tag content
if ($content !== null) {
$tag["content"] = $content;
}
// add namespace Uri
if ($namespaceUri !== null) {
$tag["namespaceUri"] = $namespaceUri;
}
 
return PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $linebreak, $encoding);
}
 
/**
* create a tag from an array
* this method awaits an array in the following format
* <pre>
* array(
* "qname" => $qname // qualified name of the tag
* "namespace" => $namespace // namespace prefix (optional, if qname is specified or no namespace)
* "localpart" => $localpart, // local part of the tagname (optional, if qname is specified)
* "attributes" => array(), // array containing all attributes (optional)
* "content" => $content, // tag content (optional)
* "namespaceUri" => $namespaceUri // namespaceUri for the given namespace (optional)
* )
* </pre>
*
* <code>
* require_once 'XML/Util.php';
*
* $tag = array(
* "qname" => "foo:bar",
* "namespaceUri" => "http://foo.com",
* "attributes" => array( "key" => "value", "argh" => "fruit&vegetable" ),
* "content" => "I'm inside the tag",
* );
* // creating a tag with qualified name and namespaceUri
* $string = PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag);
* </code>
*
* @access public
* @static
* @param array $tag tag definition
* @param integer $replaceEntities whether to replace XML special chars in content, embedd it in a CData section or none of both
* @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line
* @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column)
* @param string $linebreak string used for linebreaks
* @return string $string XML tag
* @see PEAR_PackageFile_Generator_v2_XML_Util::createTag()
* @uses PEAR_PackageFile_Generator_v2_XML_Util::attributesToString() to serialize the attributes of the tag
* @uses PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName() to get local part and namespace of a qualified name
*/
function createTagFromArray($tag, $replaceEntities = PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES, $multiline = false, $indent = "_auto", $linebreak = "\n", $encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML)
{
if (isset($tag["content"]) && !is_scalar($tag["content"])) {
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( "Supplied non-scalar value as tag content", PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NON_SCALAR_CONTENT );
}
 
if (!isset($tag['qname']) && !isset($tag['localPart'])) {
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( 'You must either supply a qualified name (qname) or local tag name (localPart).', PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NO_TAG_NAME );
}
 
// if no attributes hav been set, use empty attributes
if (!isset($tag["attributes"]) || !is_array($tag["attributes"])) {
$tag["attributes"] = array();
}
// qualified name is not given
if (!isset($tag["qname"])) {
// check for namespace
if (isset($tag["namespace"]) && !empty($tag["namespace"])) {
$tag["qname"] = $tag["namespace"].":".$tag["localPart"];
} else {
$tag["qname"] = $tag["localPart"];
}
// namespace URI is set, but no namespace
} elseif (isset($tag["namespaceUri"]) && !isset($tag["namespace"])) {
$parts = PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName($tag["qname"]);
$tag["localPart"] = $parts["localPart"];
if (isset($parts["namespace"])) {
$tag["namespace"] = $parts["namespace"];
}
}
 
if (isset($tag["namespaceUri"]) && !empty($tag["namespaceUri"])) {
// is a namespace given
if (isset($tag["namespace"]) && !empty($tag["namespace"])) {
$tag["attributes"]["xmlns:".$tag["namespace"]] = $tag["namespaceUri"];
} else {
// define this Uri as the default namespace
$tag["attributes"]["xmlns"] = $tag["namespaceUri"];
}
}
 
// check for multiline attributes
if ($multiline === true) {
if ($indent === "_auto") {
$indent = str_repeat(" ", (strlen($tag["qname"])+2));
}
}
// create attribute list
$attList = PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($tag["attributes"], true, $multiline, $indent, $linebreak );
if (!isset($tag["content"]) || (string)$tag["content"] == '') {
$tag = sprintf("<%s%s />", $tag["qname"], $attList);
} else {
if ($replaceEntities == PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES) {
$tag["content"] = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities($tag["content"], $encoding);
} elseif ($replaceEntities == PEAR_PackageFile_Generator_v2_XML_Util_CDATA_SECTION) {
$tag["content"] = PEAR_PackageFile_Generator_v2_XML_Util::createCDataSection($tag["content"]);
}
$tag = sprintf("<%s%s>%s</%s>", $tag["qname"], $attList, $tag["content"], $tag["qname"] );
}
return $tag;
}
 
/**
* create a start element
*
* <code>
* require_once 'XML/Util.php';
*
* // create an XML start element:
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createStartElement("myNs:myTag", array("foo" => "bar") ,"http://www.w3c.org/myNs#");
* </code>
*
* @access public
* @static
* @param string $qname qualified tagname (including namespace)
* @param array $attributes array containg attributes
* @param string $namespaceUri URI of the namespace
* @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line
* @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column)
* @param string $linebreak string used for linebreaks
* @return string $string XML start element
* @see PEAR_PackageFile_Generator_v2_XML_Util::createEndElement(), PEAR_PackageFile_Generator_v2_XML_Util::createTag()
*/
function createStartElement($qname, $attributes = array(), $namespaceUri = null, $multiline = false, $indent = '_auto', $linebreak = "\n")
{
// if no attributes hav been set, use empty attributes
if (!isset($attributes) || !is_array($attributes)) {
$attributes = array();
}
if ($namespaceUri != null) {
$parts = PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName($qname);
}
 
// check for multiline attributes
if ($multiline === true) {
if ($indent === "_auto") {
$indent = str_repeat(" ", (strlen($qname)+2));
}
}
 
if ($namespaceUri != null) {
// is a namespace given
if (isset($parts["namespace"]) && !empty($parts["namespace"])) {
$attributes["xmlns:".$parts["namespace"]] = $namespaceUri;
} else {
// define this Uri as the default namespace
$attributes["xmlns"] = $namespaceUri;
}
}
 
// create attribute list
$attList = PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($attributes, true, $multiline, $indent, $linebreak);
$element = sprintf("<%s%s>", $qname, $attList);
return $element;
}
 
/**
* create an end element
*
* <code>
* require_once 'XML/Util.php';
*
* // create an XML start element:
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createEndElement("myNs:myTag");
* </code>
*
* @access public
* @static
* @param string $qname qualified tagname (including namespace)
* @return string $string XML end element
* @see PEAR_PackageFile_Generator_v2_XML_Util::createStartElement(), PEAR_PackageFile_Generator_v2_XML_Util::createTag()
*/
function createEndElement($qname)
{
$element = sprintf("</%s>", $qname);
return $element;
}
/**
* create an XML comment
*
* <code>
* require_once 'XML/Util.php';
*
* // create an XML start element:
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createComment("I am a comment");
* </code>
*
* @access public
* @static
* @param string $content content of the comment
* @return string $comment XML comment
*/
function createComment($content)
{
$comment = sprintf("<!-- %s -->", $content);
return $comment;
}
/**
* create a CData section
*
* <code>
* require_once 'XML/Util.php';
*
* // create a CData section
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createCDataSection("I am content.");
* </code>
*
* @access public
* @static
* @param string $data data of the CData section
* @return string $string CData section with content
*/
function createCDataSection($data)
{
return sprintf("<![CDATA[%s]]>", $data);
}
 
/**
* split qualified name and return namespace and local part
*
* <code>
* require_once 'XML/Util.php';
*
* // split qualified tag
* $parts = PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName("xslt:stylesheet");
* </code>
* the returned array will contain two elements:
* <pre>
* array(
* "namespace" => "xslt",
* "localPart" => "stylesheet"
* );
* </pre>
*
* @access public
* @static
* @param string $qname qualified tag name
* @param string $defaultNs default namespace (optional)
* @return array $parts array containing namespace and local part
*/
function splitQualifiedName($qname, $defaultNs = null)
{
if (strstr($qname, ':')) {
$tmp = explode(":", $qname);
return array(
"namespace" => $tmp[0],
"localPart" => $tmp[1]
);
}
return array(
"namespace" => $defaultNs,
"localPart" => $qname
);
}
 
/**
* check, whether string is valid XML name
*
* <p>XML names are used for tagname, attribute names and various
* other, lesser known entities.</p>
* <p>An XML name may only consist of alphanumeric characters,
* dashes, undescores and periods, and has to start with a letter
* or an underscore.
* </p>
*
* <code>
* require_once 'XML/Util.php';
*
* // verify tag name
* $result = PEAR_PackageFile_Generator_v2_XML_Util::isValidName("invalidTag?");
* if (PEAR_PackageFile_Generator_v2_XML_Util::isError($result)) {
* print "Invalid XML name: " . $result->getMessage();
* }
* </code>
*
* @access public
* @static
* @param string $string string that should be checked
* @return mixed $valid true, if string is a valid XML name, PEAR error otherwise
* @todo support for other charsets
*/
function isValidName($string)
{
// check for invalid chars
if (!preg_match("/^[[:alnum:]_\-.]$/", $string{0})) {
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( "XML names may only start with letter or underscore", PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_START );
}
// check for invalid chars
if (!preg_match("/^([a-zA-Z_]([a-zA-Z0-9_\-\.]*)?:)?[a-zA-Z_]([a-zA-Z0-9_\-\.]+)?$/", $string)) {
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( "XML names may only contain alphanumeric chars, period, hyphen, colon and underscores", PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_CHARS );
}
// XML name is valid
return true;
}
 
/**
* replacement for PEAR_PackageFile_Generator_v2_XML_Util::raiseError
*
* Avoids the necessity to always require
* PEAR.php
*
* @access public
* @param string error message
* @param integer error code
* @return object PEAR_Error
*/
function raiseError($msg, $code)
{
require_once 'PEAR.php';
return PEAR::raiseError($msg, $code);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFile/v2/Validator.php
New file
0,0 → 1,2058
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 5 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2004 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 3.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available through the world-wide-web at the following url: |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Greg Beaver <cellog@php.net> |
// | |
// +----------------------------------------------------------------------+
//
// $Id: Validator.php,v 1.97 2007/02/10 05:56:18 cellog Exp $
/**
* Private validation class used by PEAR_PackageFile_v2 - do not use directly, its
* sole purpose is to split up the PEAR/PackageFile/v2.php file to make it smaller
* @author Greg Beaver <cellog@php.net>
* @access private
*/
class PEAR_PackageFile_v2_Validator
{
/**
* @var array
*/
var $_packageInfo;
/**
* @var PEAR_PackageFile_v2
*/
var $_pf;
/**
* @var PEAR_ErrorStack
*/
var $_stack;
/**
* @var int
*/
var $_isValid = 0;
/**
* @var int
*/
var $_filesValid = 0;
/**
* @var int
*/
var $_curState = 0;
/**
* @param PEAR_PackageFile_v2
* @param int
*/
function validate(&$pf, $state = PEAR_VALIDATE_NORMAL)
{
$this->_pf = &$pf;
$this->_curState = $state;
$this->_packageInfo = $this->_pf->getArray();
$this->_isValid = $this->_pf->_isValid;
$this->_filesValid = $this->_pf->_filesValid;
$this->_stack = &$pf->_stack;
$this->_stack->getErrors(true);
if (($this->_isValid & $state) == $state) {
return true;
}
if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) {
return false;
}
if (!isset($this->_packageInfo['attribs']['version']) ||
($this->_packageInfo['attribs']['version'] != '2.0' &&
$this->_packageInfo['attribs']['version'] != '2.1')) {
$this->_noPackageVersion();
}
$structure =
array(
'name',
'channel|uri',
'*extends', // can't be multiple, but this works fine
'summary',
'description',
'+lead', // these all need content checks
'*developer',
'*contributor',
'*helper',
'date',
'*time',
'version',
'stability',
'license->?uri->?filesource',
'notes',
'contents', //special validation needed
'*compatible',
'dependencies', //special validation needed
'*usesrole',
'*usestask', // reserve these for 1.4.0a1 to implement
// this will allow a package.xml to gracefully say it
// needs a certain package installed in order to implement a role or task
'*providesextension',
'*srcpackage|*srcuri',
'+phprelease|+extsrcrelease|+extbinrelease|' .
'+zendextsrcrelease|+zendextbinrelease|bundle', //special validation needed
'*changelog',
);
$test = $this->_packageInfo;
if (isset($test['dependencies']) &&
isset($test['dependencies']['required']) &&
isset($test['dependencies']['required']['pearinstaller']) &&
isset($test['dependencies']['required']['pearinstaller']['min']) &&
version_compare('1.5.1',
$test['dependencies']['required']['pearinstaller']['min'], '<')) {
$this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']);
return false;
}
// ignore post-installation array fields
if (array_key_exists('filelist', $test)) {
unset($test['filelist']);
}
if (array_key_exists('_lastmodified', $test)) {
unset($test['_lastmodified']);
}
if (array_key_exists('#binarypackage', $test)) {
unset($test['#binarypackage']);
}
if (array_key_exists('old', $test)) {
unset($test['old']);
}
if (array_key_exists('_lastversion', $test)) {
unset($test['_lastversion']);
}
if (!$this->_stupidSchemaValidate($structure,
$test, '<package>')) {
return false;
}
if (empty($this->_packageInfo['name'])) {
$this->_tagCannotBeEmpty('name');
}
if (isset($this->_packageInfo['uri'])) {
$test = 'uri';
} else {
$test = 'channel';
}
if (empty($this->_packageInfo[$test])) {
$this->_tagCannotBeEmpty($test);
}
if (is_array($this->_packageInfo['license']) &&
(!isset($this->_packageInfo['license']['_content']) ||
empty($this->_packageInfo['license']['_content']))) {
$this->_tagCannotBeEmpty('license');
} elseif (empty($this->_packageInfo['license'])) {
$this->_tagCannotBeEmpty('license');
}
if (empty($this->_packageInfo['summary'])) {
$this->_tagCannotBeEmpty('summary');
}
if (empty($this->_packageInfo['description'])) {
$this->_tagCannotBeEmpty('description');
}
if (empty($this->_packageInfo['date'])) {
$this->_tagCannotBeEmpty('date');
}
if (empty($this->_packageInfo['notes'])) {
$this->_tagCannotBeEmpty('notes');
}
if (isset($this->_packageInfo['time']) && empty($this->_packageInfo['time'])) {
$this->_tagCannotBeEmpty('time');
}
if (isset($this->_packageInfo['dependencies'])) {
$this->_validateDependencies();
}
if (isset($this->_packageInfo['compatible'])) {
$this->_validateCompatible();
}
if (!isset($this->_packageInfo['bundle'])) {
if (empty($this->_packageInfo['contents'])) {
$this->_tagCannotBeEmpty('contents');
}
if (!isset($this->_packageInfo['contents']['dir'])) {
$this->_filelistMustContainDir('contents');
return false;
}
if (isset($this->_packageInfo['contents']['file'])) {
$this->_filelistCannotContainFile('contents');
return false;
}
}
$this->_validateMaintainers();
$this->_validateStabilityVersion();
$fail = false;
if (array_key_exists('usesrole', $this->_packageInfo)) {
$roles = $this->_packageInfo['usesrole'];
if (!is_array($roles) || !isset($roles[0])) {
$roles = array($roles);
}
foreach ($roles as $role) {
if (!isset($role['role'])) {
$this->_usesroletaskMustHaveRoleTask('usesrole', 'role');
$fail = true;
} else {
if (!isset($role['channel'])) {
if (!isset($role['uri'])) {
$this->_usesroletaskMustHaveChannelOrUri($role['role'], 'usesrole');
$fail = true;
}
} elseif (!isset($role['package'])) {
$this->_usesroletaskMustHavePackage($role['role'], 'usesrole');
$fail = true;
}
}
}
}
if (array_key_exists('usestask', $this->_packageInfo)) {
$roles = $this->_packageInfo['usestask'];
if (!is_array($roles) || !isset($roles[0])) {
$roles = array($roles);
}
foreach ($roles as $role) {
if (!isset($role['task'])) {
$this->_usesroletaskMustHaveRoleTask('usestask', 'task');
$fail = true;
} else {
if (!isset($role['channel'])) {
if (!isset($role['uri'])) {
$this->_usesroletaskMustHaveChannelOrUri($role['task'], 'usestask');
$fail = true;
}
} elseif (!isset($role['package'])) {
$this->_usesroletaskMustHavePackage($role['task'], 'usestask');
$fail = true;
}
}
}
}
if ($fail) {
return false;
}
$list = $this->_packageInfo['contents'];
if (isset($list['dir']) && is_array($list['dir']) && isset($list['dir'][0])) {
$this->_multipleToplevelDirNotAllowed();
return $this->_isValid = 0;
}
$this->_validateFilelist();
$this->_validateRelease();
if (!$this->_stack->hasErrors()) {
$chan = $this->_pf->_registry->getChannel($this->_pf->getChannel(), true);
if (PEAR::isError($chan)) {
$this->_unknownChannel($this->_pf->getChannel());
} else {
$valpack = $chan->getValidationPackage();
// for channel validator packages, always use the default PEAR validator.
// otherwise, they can't be installed or packaged
$validator = $chan->getValidationObject($this->_pf->getPackage());
if (!$validator) {
$this->_stack->push(__FUNCTION__, 'error',
array_merge(
array('channel' => $chan->getName(),
'package' => $this->_pf->getPackage()),
$valpack
),
'package "%channel%/%package%" cannot be properly validated without ' .
'validation package "%channel%/%name%-%version%"');
return $this->_isValid = 0;
}
$validator->setPackageFile($this->_pf);
$validator->validate($state);
$failures = $validator->getFailures();
foreach ($failures['errors'] as $error) {
$this->_stack->push(__FUNCTION__, 'error', $error,
'Channel validator error: field "%field%" - %reason%');
}
foreach ($failures['warnings'] as $warning) {
$this->_stack->push(__FUNCTION__, 'warning', $warning,
'Channel validator warning: field "%field%" - %reason%');
}
}
}
$this->_pf->_isValid = $this->_isValid = !$this->_stack->hasErrors('error');
if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$this->_filesValid) {
if ($this->_pf->getPackageType() == 'bundle') {
if ($this->_analyzeBundledPackages()) {
$this->_filesValid = $this->_pf->_filesValid = true;
} else {
$this->_pf->_isValid = $this->_isValid = 0;
}
} else {
if (!$this->_analyzePhpFiles()) {
$this->_pf->_isValid = $this->_isValid = 0;
} else {
$this->_filesValid = $this->_pf->_filesValid = true;
}
}
}
if ($this->_isValid) {
return $this->_pf->_isValid = $this->_isValid = $state;
}
return $this->_pf->_isValid = $this->_isValid = 0;
}
 
function _stupidSchemaValidate($structure, $xml, $root)
{
if (!is_array($xml)) {
$xml = array();
}
$keys = array_keys($xml);
reset($keys);
$key = current($keys);
while ($key == 'attribs' || $key == '_contents') {
$key = next($keys);
}
$unfoundtags = $optionaltags = array();
$ret = true;
$mismatch = false;
foreach ($structure as $struc) {
if ($key) {
$tag = $xml[$key];
}
$test = $this->_processStructure($struc);
if (isset($test['choices'])) {
$loose = true;
foreach ($test['choices'] as $choice) {
if ($key == $choice['tag']) {
$key = next($keys);
while ($key == 'attribs' || $key == '_contents') {
$key = next($keys);
}
$unfoundtags = $optionaltags = array();
$mismatch = false;
if ($key && $key != $choice['tag'] && isset($choice['multiple'])) {
$unfoundtags[] = $choice['tag'];
$optionaltags[] = $choice['tag'];
if ($key) {
$mismatch = true;
}
}
$ret &= $this->_processAttribs($choice, $tag, $root);
continue 2;
} else {
$unfoundtags[] = $choice['tag'];
$mismatch = true;
}
if (!isset($choice['multiple']) || $choice['multiple'] != '*') {
$loose = false;
} else {
$optionaltags[] = $choice['tag'];
}
}
if (!$loose) {
$this->_invalidTagOrder($unfoundtags, $key, $root);
return false;
}
} else {
if ($key != $test['tag']) {
if (isset($test['multiple']) && $test['multiple'] != '*') {
$unfoundtags[] = $test['tag'];
$this->_invalidTagOrder($unfoundtags, $key, $root);
return false;
} else {
if ($key) {
$mismatch = true;
}
$unfoundtags[] = $test['tag'];
$optionaltags[] = $test['tag'];
}
if (!isset($test['multiple'])) {
$this->_invalidTagOrder($unfoundtags, $key, $root);
return false;
}
continue;
} else {
$unfoundtags = $optionaltags = array();
$mismatch = false;
}
$key = next($keys);
while ($key == 'attribs' || $key == '_contents') {
$key = next($keys);
}
if ($key && $key != $test['tag'] && isset($test['multiple'])) {
$unfoundtags[] = $test['tag'];
$optionaltags[] = $test['tag'];
$mismatch = true;
}
$ret &= $this->_processAttribs($test, $tag, $root);
continue;
}
}
if (!$mismatch && count($optionaltags)) {
// don't error out on any optional tags
$unfoundtags = array_diff($unfoundtags, $optionaltags);
}
if (count($unfoundtags)) {
$this->_invalidTagOrder($unfoundtags, $key, $root);
} elseif ($key) {
// unknown tags
$this->_invalidTagOrder('*no tags allowed here*', $key, $root);
while ($key = next($keys)) {
$this->_invalidTagOrder('*no tags allowed here*', $key, $root);
}
}
return $ret;
}
 
function _processAttribs($choice, $tag, $context)
{
if (isset($choice['attribs'])) {
if (!is_array($tag)) {
$tag = array($tag);
}
$tags = $tag;
if (!isset($tags[0])) {
$tags = array($tags);
}
$ret = true;
foreach ($tags as $i => $tag) {
if (!is_array($tag) || !isset($tag['attribs'])) {
foreach ($choice['attribs'] as $attrib) {
if ($attrib{0} != '?') {
$ret &= $this->_tagHasNoAttribs($choice['tag'],
$context);
continue 2;
}
}
}
foreach ($choice['attribs'] as $attrib) {
if ($attrib{0} != '?') {
if (!isset($tag['attribs'][$attrib])) {
$ret &= $this->_tagMissingAttribute($choice['tag'],
$attrib, $context);
}
}
}
}
return $ret;
}
return true;
}
 
function _processStructure($key)
{
$ret = array();
if (count($pieces = explode('|', $key)) > 1) {
$ret['choices'] = array();
foreach ($pieces as $piece) {
$ret['choices'][] = $this->_processStructure($piece);
}
return $ret;
}
$multi = $key{0};
if ($multi == '+' || $multi == '*') {
$ret['multiple'] = $key{0};
$key = substr($key, 1);
}
if (count($attrs = explode('->', $key)) > 1) {
$ret['tag'] = array_shift($attrs);
$ret['attribs'] = $attrs;
} else {
$ret['tag'] = $key;
}
return $ret;
}
 
function _validateStabilityVersion()
{
$structure = array('release', 'api');
$a = $this->_stupidSchemaValidate($structure, $this->_packageInfo['version'], '<version>');
$a &= $this->_stupidSchemaValidate($structure, $this->_packageInfo['stability'], '<stability>');
if ($a) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$this->_packageInfo['version']['release'])) {
$this->_invalidVersion('release', $this->_packageInfo['version']['release']);
}
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$this->_packageInfo['version']['api'])) {
$this->_invalidVersion('api', $this->_packageInfo['version']['api']);
}
if (!in_array($this->_packageInfo['stability']['release'],
array('snapshot', 'devel', 'alpha', 'beta', 'stable'))) {
$this->_invalidState('release', $this->_packageinfo['stability']['release']);
}
if (!in_array($this->_packageInfo['stability']['api'],
array('devel', 'alpha', 'beta', 'stable'))) {
$this->_invalidState('api', $this->_packageinfo['stability']['api']);
}
}
}
 
function _validateMaintainers()
{
$structure =
array(
'name',
'user',
'email',
'active',
);
foreach (array('lead', 'developer', 'contributor', 'helper') as $type) {
if (!isset($this->_packageInfo[$type])) {
continue;
}
if (isset($this->_packageInfo[$type][0])) {
foreach ($this->_packageInfo[$type] as $lead) {
$this->_stupidSchemaValidate($structure, $lead, '<' . $type . '>');
}
} else {
$this->_stupidSchemaValidate($structure, $this->_packageInfo[$type],
'<' . $type . '>');
}
}
}
 
function _validatePhpDep($dep, $installcondition = false)
{
$structure = array(
'min',
'*max',
'*exclude',
);
$type = $installcondition ? '<installcondition><php>' : '<dependencies><required><php>';
$this->_stupidSchemaValidate($structure, $dep, $type);
if (isset($dep['min'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?$/',
$dep['min'])) {
$this->_invalidVersion($type . '<min>', $dep['min']);
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?$/',
$dep['max'])) {
$this->_invalidVersion($type . '<max>', $dep['max']);
}
}
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
foreach ($dep['exclude'] as $exclude) {
if (!preg_match(
'/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?$/',
$exclude)) {
$this->_invalidVersion($type . '<exclude>', $exclude);
}
}
}
}
 
function _validatePearinstallerDep($dep)
{
$structure = array(
'min',
'*max',
'*recommended',
'*exclude',
);
$this->_stupidSchemaValidate($structure, $dep, '<dependencies><required><pearinstaller>');
if (isset($dep['min'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['min'])) {
$this->_invalidVersion('<dependencies><required><pearinstaller><min>',
$dep['min']);
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['max'])) {
$this->_invalidVersion('<dependencies><required><pearinstaller><max>',
$dep['max']);
}
}
if (isset($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['recommended'])) {
$this->_invalidVersion('<dependencies><required><pearinstaller><recommended>',
$dep['recommended']);
}
}
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
foreach ($dep['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$exclude)) {
$this->_invalidVersion('<dependencies><required><pearinstaller><exclude>',
$exclude);
}
}
}
}
 
function _validatePackageDep($dep, $group, $type = '<package>')
{
if (isset($dep['uri'])) {
if (isset($dep['conflicts'])) {
$structure = array(
'name',
'uri',
'conflicts',
'*providesextension',
);
} else {
$structure = array(
'name',
'uri',
'*providesextension',
);
}
} else {
if (isset($dep['conflicts'])) {
$structure = array(
'name',
'channel',
'*min',
'*max',
'*exclude',
'conflicts',
'*providesextension',
);
} else {
$structure = array(
'name',
'channel',
'*min',
'*max',
'*recommended',
'*exclude',
'*nodefault',
'*providesextension',
);
}
}
if (isset($dep['name'])) {
$type .= '<name>' . $dep['name'] . '</name>';
}
$this->_stupidSchemaValidate($structure, $dep, '<dependencies>' . $group . $type);
if (isset($dep['uri']) && (isset($dep['min']) || isset($dep['max']) ||
isset($dep['recommended']) || isset($dep['exclude']))) {
$this->_uriDepsCannotHaveVersioning('<dependencies>' . $group . $type);
}
if (isset($dep['channel']) && strtolower($dep['channel']) == '__uri') {
$this->_DepchannelCannotBeUri('<dependencies>' . $group . $type);
}
if (isset($dep['min'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['min'])) {
$this->_invalidVersion('<dependencies>' . $group . $type . '<min>', $dep['min']);
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['max'])) {
$this->_invalidVersion('<dependencies>' . $group . $type . '<max>', $dep['max']);
}
}
if (isset($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['recommended'])) {
$this->_invalidVersion('<dependencies>' . $group . $type . '<recommended>',
$dep['recommended']);
}
}
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
foreach ($dep['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$exclude)) {
$this->_invalidVersion('<dependencies>' . $group . $type . '<exclude>',
$exclude);
}
}
}
}
 
function _validateSubpackageDep($dep, $group)
{
$this->_validatePackageDep($dep, $group, '<subpackage>');
if (isset($dep['providesextension'])) {
$this->_subpackageCannotProvideExtension(isset($dep['name']) ? $dep['name'] : '');
}
if (isset($dep['conflicts'])) {
$this->_subpackagesCannotConflict(isset($dep['name']) ? $dep['name'] : '');
}
}
 
function _validateExtensionDep($dep, $group = false, $installcondition = false)
{
if (isset($dep['conflicts'])) {
$structure = array(
'name',
'*min',
'*max',
'*exclude',
'conflicts',
);
} else {
$structure = array(
'name',
'*min',
'*max',
'*recommended',
'*exclude',
);
}
if ($installcondition) {
$type = '<installcondition><extension>';
} else {
$type = '<dependencies>' . $group . '<extension>';
}
if (isset($dep['name'])) {
$type .= '<name>' . $dep['name'] . '</name>';
}
$this->_stupidSchemaValidate($structure, $dep, $type);
if (isset($dep['min'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['min'])) {
$this->_invalidVersion(substr($type, 1) . '<min', $dep['min']);
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['max'])) {
$this->_invalidVersion(substr($type, 1) . '<max', $dep['max']);
}
}
if (isset($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['recommended'])) {
$this->_invalidVersion(substr($type, 1) . '<recommended', $dep['recommended']);
}
}
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
foreach ($dep['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$exclude)) {
$this->_invalidVersion(substr($type, 1) . '<exclude', $exclude);
}
}
}
}
 
function _validateOsDep($dep, $installcondition = false)
{
$structure = array(
'name',
'*conflicts',
);
$type = $installcondition ? '<installcondition><os>' : '<dependencies><required><os>';
if ($this->_stupidSchemaValidate($structure, $dep, $type)) {
if ($dep['name'] == '*') {
if (array_key_exists('conflicts', $dep)) {
$this->_cannotConflictWithAllOs($type);
}
}
}
}
 
function _validateArchDep($dep, $installcondition = false)
{
$structure = array(
'pattern',
'*conflicts',
);
$type = $installcondition ? '<installcondition><arch>' : '<dependencies><required><arch>';
$this->_stupidSchemaValidate($structure, $dep, $type);
}
 
function _validateInstallConditions($cond, $release)
{
$structure = array(
'*php',
'*extension',
'*os',
'*arch',
);
if (!$this->_stupidSchemaValidate($structure,
$cond, $release)) {
return false;
}
foreach (array('php', 'extension', 'os', 'arch') as $type) {
if (isset($cond[$type])) {
$iter = $cond[$type];
if (!is_array($iter) || !isset($iter[0])) {
$iter = array($iter);
}
foreach ($iter as $package) {
if ($type == 'extension') {
$this->{"_validate{$type}Dep"}($package, false, true);
} else {
$this->{"_validate{$type}Dep"}($package, true);
}
}
}
}
}
 
function _validateDependencies()
{
$structure = array(
'required',
'*optional',
'*group->name->hint'
);
if (!$this->_stupidSchemaValidate($structure,
$this->_packageInfo['dependencies'], '<dependencies>')) {
return false;
}
foreach (array('required', 'optional') as $simpledep) {
if (isset($this->_packageInfo['dependencies'][$simpledep])) {
if ($simpledep == 'optional') {
$structure = array(
'*package',
'*subpackage',
'*extension',
);
} else {
$structure = array(
'php',
'pearinstaller',
'*package',
'*subpackage',
'*extension',
'*os',
'*arch',
);
}
if ($this->_stupidSchemaValidate($structure,
$this->_packageInfo['dependencies'][$simpledep],
"<dependencies><$simpledep>")) {
foreach (array('package', 'subpackage', 'extension') as $type) {
if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) {
$iter = $this->_packageInfo['dependencies'][$simpledep][$type];
if (!isset($iter[0])) {
$iter = array($iter);
}
foreach ($iter as $package) {
if ($type != 'extension') {
if (isset($package['uri'])) {
if (isset($package['channel'])) {
$this->_UrlOrChannel($type,
$package['name']);
}
} else {
if (!isset($package['channel'])) {
$this->_NoChannel($type, $package['name']);
}
}
}
$this->{"_validate{$type}Dep"}($package, "<$simpledep>");
}
}
}
if ($simpledep == 'optional') {
continue;
}
foreach (array('php', 'pearinstaller', 'os', 'arch') as $type) {
if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) {
$iter = $this->_packageInfo['dependencies'][$simpledep][$type];
if (!isset($iter[0])) {
$iter = array($iter);
}
foreach ($iter as $package) {
$this->{"_validate{$type}Dep"}($package);
}
}
}
}
}
}
if (isset($this->_packageInfo['dependencies']['group'])) {
$groups = $this->_packageInfo['dependencies']['group'];
if (!isset($groups[0])) {
$groups = array($groups);
}
$structure = array(
'*package',
'*subpackage',
'*extension',
);
foreach ($groups as $group) {
if ($this->_stupidSchemaValidate($structure, $group, '<group>')) {
if (!PEAR_Validate::validGroupName($group['attribs']['name'])) {
$this->_invalidDepGroupName($group['attribs']['name']);
}
foreach (array('package', 'subpackage', 'extension') as $type) {
if (isset($group[$type])) {
$iter = $group[$type];
if (!isset($iter[0])) {
$iter = array($iter);
}
foreach ($iter as $package) {
if ($type != 'extension') {
if (isset($package['uri'])) {
if (isset($package['channel'])) {
$this->_UrlOrChannelGroup($type,
$package['name'],
$group['name']);
}
} else {
if (!isset($package['channel'])) {
$this->_NoChannelGroup($type,
$package['name'],
$group['name']);
}
}
}
$this->{"_validate{$type}Dep"}($package, '<group name="' .
$group['attribs']['name'] . '">');
}
}
}
}
}
}
}
 
function _validateCompatible()
{
$compat = $this->_packageInfo['compatible'];
if (!isset($compat[0])) {
$compat = array($compat);
}
$required = array('name', 'channel', 'min', 'max', '*exclude');
foreach ($compat as $package) {
$type = '<compatible>';
if (is_array($package) && array_key_exists('name', $package)) {
$type .= '<name>' . $package['name'] . '</name>';
}
$this->_stupidSchemaValidate($required, $package, $type);
if (is_array($package) && array_key_exists('min', $package)) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$package['min'])) {
$this->_invalidVersion(substr($type, 1) . '<min', $package['min']);
}
}
if (is_array($package) && array_key_exists('max', $package)) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$package['max'])) {
$this->_invalidVersion(substr($type, 1) . '<max', $package['max']);
}
}
if (is_array($package) && array_key_exists('exclude', $package)) {
if (!is_array($package['exclude'])) {
$package['exclude'] = array($package['exclude']);
}
foreach ($package['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$exclude)) {
$this->_invalidVersion(substr($type, 1) . '<exclude', $exclude);
}
}
}
}
}
 
function _validateBundle($list)
{
if (!is_array($list) || !isset($list['bundledpackage'])) {
return $this->_NoBundledPackages();
}
if (!is_array($list['bundledpackage']) || !isset($list['bundledpackage'][0])) {
return $this->_AtLeast2BundledPackages();
}
foreach ($list['bundledpackage'] as $package) {
if (!is_string($package)) {
$this->_bundledPackagesMustBeFilename();
}
}
}
 
function _validateFilelist($list = false, $allowignore = false, $dirs = '')
{
$iscontents = false;
if (!$list) {
$iscontents = true;
$list = $this->_packageInfo['contents'];
if (isset($this->_packageInfo['bundle'])) {
return $this->_validateBundle($list);
}
}
if ($allowignore) {
$struc = array(
'*install->name->as',
'*ignore->name'
);
} else {
$struc = array(
'*dir->name->?baseinstalldir',
'*file->name->role->?baseinstalldir->?md5sum'
);
if (isset($list['dir']) && isset($list['file'])) {
// stave off validation errors without requiring a set order.
$_old = $list;
if (isset($list['attribs'])) {
$list = array('attribs' => $_old['attribs']);
}
$list['dir'] = $_old['dir'];
$list['file'] = $_old['file'];
}
}
if (!isset($list['attribs']) || !isset($list['attribs']['name'])) {
$unknown = $allowignore ? '<filelist>' : '<dir name="*unknown*">';
$dirname = $iscontents ? '<contents>' : $unknown;
} else {
$dirname = '<dir name="' . $list['attribs']['name'] . '">';
}
$res = $this->_stupidSchemaValidate($struc, $list, $dirname);
if ($allowignore && $res) {
$ignored_or_installed = array();
$this->_pf->getFilelist();
$fcontents = $this->_pf->getContents();
$filelist = array();
if (!isset($fcontents['dir']['file'][0])) {
$fcontents['dir']['file'] = array($fcontents['dir']['file']);
}
foreach ($fcontents['dir']['file'] as $file) {
$filelist[$file['attribs']['name']] = true;
}
if (isset($list['install'])) {
if (!isset($list['install'][0])) {
$list['install'] = array($list['install']);
}
foreach ($list['install'] as $file) {
if (!isset($filelist[$file['attribs']['name']])) {
$this->_notInContents($file['attribs']['name'], 'install');
continue;
}
if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) {
$this->_multipleInstallAs($file['attribs']['name']);
}
if (!isset($ignored_or_installed[$file['attribs']['name']])) {
$ignored_or_installed[$file['attribs']['name']] = array();
}
$ignored_or_installed[$file['attribs']['name']][] = 1;
}
}
if (isset($list['ignore'])) {
if (!isset($list['ignore'][0])) {
$list['ignore'] = array($list['ignore']);
}
foreach ($list['ignore'] as $file) {
if (!isset($filelist[$file['attribs']['name']])) {
$this->_notInContents($file['attribs']['name'], 'ignore');
continue;
}
if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) {
$this->_ignoreAndInstallAs($file['attribs']['name']);
}
}
}
}
if (!$allowignore && isset($list['file'])) {
if (!isset($list['file'][0])) {
// single file
$list['file'] = array($list['file']);
}
foreach ($list['file'] as $i => $file)
{
if (isset($file['attribs']) && isset($file['attribs']['name']) &&
$file['attribs']['name']{0} == '.' &&
$file['attribs']['name']{1} == '/') {
// name is something like "./doc/whatever.txt"
$this->_invalidFileName($file['attribs']['name']);
}
if (isset($file['attribs']) && isset($file['attribs']['role'])) {
if (!$this->_validateRole($file['attribs']['role'])) {
if (isset($this->_packageInfo['usesrole'])) {
$roles = $this->_packageInfo['usesrole'];
if (!isset($roles[0])) {
$roles = array($roles);
}
foreach ($roles as $role) {
if ($role['role'] = $file['attribs']['role']) {
$msg = 'This package contains role "%role%" and requires ' .
'package "%package%" to be used';
if (isset($role['uri'])) {
$params = array('role' => $role['role'],
'package' => $role['uri']);
} else {
$params = array('role' => $role['role'],
'package' => $this->_pf->_registry->
parsedPackageNameToString(array('package' =>
$role['package'], 'channel' => $role['channel']),
true));
}
$this->_stack->push('_mustInstallRole', 'error', $params, $msg);
}
}
}
$this->_invalidFileRole($file['attribs']['name'],
$dirname, $file['attribs']['role']);
}
}
if (!isset($file['attribs'])) {
continue;
}
$save = $file['attribs'];
if ($dirs) {
$save['name'] = $dirs . '/' . $save['name'];
}
unset($file['attribs']);
if (count($file) && $this->_curState != PEAR_VALIDATE_DOWNLOADING) { // has tasks
foreach ($file as $task => $value) {
if ($tagClass = $this->_pf->getTask($task)) {
if (!is_array($value) || !isset($value[0])) {
$value = array($value);
}
foreach ($value as $v) {
$ret = call_user_func(array($tagClass, 'validateXml'),
$this->_pf, $v, $this->_pf->_config, $save);
if (is_array($ret)) {
$this->_invalidTask($task, $ret, isset($save['name']) ?
$save['name'] : '');
}
}
} else {
if (isset($this->_packageInfo['usestask'])) {
$roles = $this->_packageInfo['usestask'];
if (!isset($roles[0])) {
$roles = array($roles);
}
foreach ($roles as $role) {
if ($role['task'] = $task) {
$msg = 'This package contains task "%task%" and requires ' .
'package "%package%" to be used';
if (isset($role['uri'])) {
$params = array('task' => $role['task'],
'package' => $role['uri']);
} else {
$params = array('task' => $role['task'],
'package' => $this->_pf->_registry->
parsedPackageNameToString(array('package' =>
$role['package'], 'channel' => $role['channel']),
true));
}
$this->_stack->push('_mustInstallTask', 'error',
$params, $msg);
}
}
}
$this->_unknownTask($task, $save['name']);
}
}
}
}
}
if (isset($list['ignore'])) {
if (!$allowignore) {
$this->_ignoreNotAllowed('ignore');
}
}
if (isset($list['install'])) {
if (!$allowignore) {
$this->_ignoreNotAllowed('install');
}
}
if (isset($list['file'])) {
if ($allowignore) {
$this->_fileNotAllowed('file');
}
}
if (isset($list['dir'])) {
if ($allowignore) {
$this->_fileNotAllowed('dir');
} else {
if (!isset($list['dir'][0])) {
$list['dir'] = array($list['dir']);
}
foreach ($list['dir'] as $dir) {
if (isset($dir['attribs']) && isset($dir['attribs']['name'])) {
if ($dir['attribs']['name'] == '/' ||
!isset($this->_packageInfo['contents']['dir']['dir'])) {
// always use nothing if the filelist has already been flattened
$newdirs = '';
} elseif ($dirs == '') {
$newdirs = $dir['attribs']['name'];
} else {
$newdirs = $dirs . '/' . $dir['attribs']['name'];
}
} else {
$newdirs = $dirs;
}
$this->_validateFilelist($dir, $allowignore, $newdirs);
}
}
}
}
 
function _validateRelease()
{
if (isset($this->_packageInfo['phprelease'])) {
$release = 'phprelease';
if (isset($this->_packageInfo['providesextension'])) {
$this->_cannotProvideExtension($release);
}
if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) {
$this->_cannotHaveSrcpackage($release);
}
$releases = $this->_packageInfo['phprelease'];
if (!is_array($releases)) {
return true;
}
if (!isset($releases[0])) {
$releases = array($releases);
}
foreach ($releases as $rel) {
$this->_stupidSchemaValidate(array(
'*installconditions',
'*filelist',
), $rel, '<phprelease>');
}
}
foreach (array('', 'zend') as $prefix) {
$releasetype = $prefix . 'extsrcrelease';
if (isset($this->_packageInfo[$releasetype])) {
$release = $releasetype;
if (!isset($this->_packageInfo['providesextension'])) {
$this->_mustProvideExtension($release);
}
if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) {
$this->_cannotHaveSrcpackage($release);
}
$releases = $this->_packageInfo[$releasetype];
if (!is_array($releases)) {
return true;
}
if (!isset($releases[0])) {
$releases = array($releases);
}
foreach ($releases as $rel) {
$this->_stupidSchemaValidate(array(
'*installconditions',
'*configureoption->name->prompt->?default',
'*binarypackage',
'*filelist',
), $rel, '<' . $releasetype . '>');
if (isset($rel['binarypackage'])) {
if (!is_array($rel['binarypackage']) || !isset($rel['binarypackage'][0])) {
$rel['binarypackage'] = array($rel['binarypackage']);
}
foreach ($rel['binarypackage'] as $bin) {
if (!is_string($bin)) {
$this->_binaryPackageMustBePackagename();
}
}
}
}
}
$releasetype = 'extbinrelease';
if (isset($this->_packageInfo[$releasetype])) {
$release = $releasetype;
if (!isset($this->_packageInfo['providesextension'])) {
$this->_mustProvideExtension($release);
}
if (isset($this->_packageInfo['channel']) &&
!isset($this->_packageInfo['srcpackage'])) {
$this->_mustSrcPackage($release);
}
if (isset($this->_packageInfo['uri']) && !isset($this->_packageInfo['srcuri'])) {
$this->_mustSrcuri($release);
}
$releases = $this->_packageInfo[$releasetype];
if (!is_array($releases)) {
return true;
}
if (!isset($releases[0])) {
$releases = array($releases);
}
foreach ($releases as $rel) {
$this->_stupidSchemaValidate(array(
'*installconditions',
'*filelist',
), $rel, '<' . $releasetype . '>');
}
}
}
if (isset($this->_packageInfo['bundle'])) {
$release = 'bundle';
if (isset($this->_packageInfo['providesextension'])) {
$this->_cannotProvideExtension($release);
}
if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) {
$this->_cannotHaveSrcpackage($release);
}
$releases = $this->_packageInfo['bundle'];
if (!is_array($releases) || !isset($releases[0])) {
$releases = array($releases);
}
foreach ($releases as $rel) {
$this->_stupidSchemaValidate(array(
'*installconditions',
'*filelist',
), $rel, '<bundle>');
}
}
foreach ($releases as $rel) {
if (is_array($rel) && array_key_exists('installconditions', $rel)) {
$this->_validateInstallConditions($rel['installconditions'],
"<$release><installconditions>");
}
if (is_array($rel) && array_key_exists('filelist', $rel)) {
if ($rel['filelist']) {
$this->_validateFilelist($rel['filelist'], true);
}
}
}
}
 
/**
* This is here to allow role extension through plugins
* @param string
*/
function _validateRole($role)
{
return in_array($role, PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType()));
}
 
function _pearVersionTooLow($version)
{
$this->_stack->push(__FUNCTION__, 'error',
array('version' => $version),
'This package.xml requires PEAR version %version% to parse properly, we are ' .
'version 1.5.1');
}
 
function _invalidTagOrder($oktags, $actual, $root)
{
$this->_stack->push(__FUNCTION__, 'error',
array('oktags' => $oktags, 'actual' => $actual, 'root' => $root),
'Invalid tag order in %root%, found <%actual%> expected one of "%oktags%"');
}
 
function _ignoreNotAllowed($type)
{
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type),
'<%type%> is not allowed inside global <contents>, only inside ' .
'<phprelease>/<extbinrelease>/<zendextbinrelease>, use <dir> and <file> only');
}
 
function _fileNotAllowed($type)
{
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type),
'<%type%> is not allowed inside release <filelist>, only inside ' .
'<contents>, use <ignore> and <install> only');
}
 
function _tagMissingAttribute($tag, $attr, $context)
{
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag,
'attribute' => $attr, 'context' => $context),
'tag <%tag%> in context "%context%" has no attribute "%attribute%"');
}
 
function _tagHasNoAttribs($tag, $context)
{
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag,
'context' => $context),
'tag <%tag%> has no attributes in context "%context%"');
}
 
function _invalidInternalStructure()
{
$this->_stack->push(__FUNCTION__, 'exception', array(),
'internal array was not generated by compatible parser, or extreme parser error, cannot continue');
}
 
function _invalidFileRole($file, $dir, $role)
{
$this->_stack->push(__FUNCTION__, 'error', array(
'file' => $file, 'dir' => $dir, 'role' => $role,
'roles' => PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())),
'File "%file%" in directory "%dir%" has invalid role "%role%", should be one of %roles%');
}
 
function _invalidFileName($file, $dir)
{
$this->_stack->push(__FUNCTION__, 'error', array(
'file' => $file),
'File "%file%" cannot begin with "."');
}
 
function _filelistCannotContainFile($filelist)
{
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist),
'<%tag%> can only contain <dir>, contains <file>. Use ' .
'<dir name="/"> as the first dir element');
}
 
function _filelistMustContainDir($filelist)
{
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist),
'<%tag%> must contain <dir>. Use <dir name="/"> as the ' .
'first dir element');
}
 
function _tagCannotBeEmpty($tag)
{
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag),
'<%tag%> cannot be empty (<%tag%/>)');
}
 
function _UrlOrChannel($type, $name)
{
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type,
'name' => $name),
'Required dependency <%type%> "%name%" can have either url OR ' .
'channel attributes, and not both');
}
 
function _NoChannel($type, $name)
{
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type,
'name' => $name),
'Required dependency <%type%> "%name%" must have either url OR ' .
'channel attributes');
}
 
function _UrlOrChannelGroup($type, $name, $group)
{
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type,
'name' => $name, 'group' => $group),
'Group "%group%" dependency <%type%> "%name%" can have either url OR ' .
'channel attributes, and not both');
}
 
function _NoChannelGroup($type, $name, $group)
{
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type,
'name' => $name, 'group' => $group),
'Group "%group%" dependency <%type%> "%name%" must have either url OR ' .
'channel attributes');
}
 
function _unknownChannel($channel)
{
$this->_stack->push(__FUNCTION__, 'error', array('channel' => $channel),
'Unknown channel "%channel%"');
}
 
function _noPackageVersion()
{
$this->_stack->push(__FUNCTION__, 'error', array(),
'package.xml <package> tag has no version attribute, or version is not 2.0');
}
 
function _NoBundledPackages()
{
$this->_stack->push(__FUNCTION__, 'error', array(),
'No <bundledpackage> tag was found in <contents>, required for bundle packages');
}
 
function _AtLeast2BundledPackages()
{
$this->_stack->push(__FUNCTION__, 'error', array(),
'At least 2 packages must be bundled in a bundle package');
}
 
function _ChannelOrUri($name)
{
$this->_stack->push(__FUNCTION__, 'error', array('name' => $name),
'Bundled package "%name%" can have either a uri or a channel, not both');
}
 
function _noChildTag($child, $tag)
{
$this->_stack->push(__FUNCTION__, 'error', array('child' => $child, 'tag' => $tag),
'Tag <%tag%> is missing child tag <%child%>');
}
 
function _invalidVersion($type, $value)
{
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value),
'Version type <%type%> is not a valid version (%value%)');
}
 
function _invalidState($type, $value)
{
$states = array('stable', 'beta', 'alpha', 'devel');
if ($type != 'api') {
$states[] = 'snapshot';
}
if (strtolower($value) == 'rc') {
$this->_stack->push(__FUNCTION__, 'error',
array('version' => $this->_packageInfo['version']['release']),
'RC is not a state, it is a version postfix, try %version%RC1, stability beta');
}
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value,
'types' => $states),
'Stability type <%type%> is not a valid stability (%value%), must be one of ' .
'%types%');
}
 
function _invalidTask($task, $ret, $file)
{
switch ($ret[0]) {
case PEAR_TASK_ERROR_MISSING_ATTRIB :
$info = array('attrib' => $ret[1], 'task' => $task, 'file' => $file);
$msg = 'task <%task%> is missing attribute "%attrib%" in file %file%';
break;
case PEAR_TASK_ERROR_NOATTRIBS :
$info = array('task' => $task, 'file' => $file);
$msg = 'task <%task%> has no attributes in file %file%';
break;
case PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE :
$info = array('attrib' => $ret[1], 'values' => $ret[3],
'was' => $ret[2], 'task' => $task, 'file' => $file);
$msg = 'task <%task%> attribute "%attrib%" has the wrong value "%was%" '.
'in file %file%, expecting one of "%values%"';
break;
case PEAR_TASK_ERROR_INVALID :
$info = array('reason' => $ret[1], 'task' => $task, 'file' => $file);
$msg = 'task <%task%> in file %file% is invalid because of "%reason%"';
break;
}
$this->_stack->push(__FUNCTION__, 'error', $info, $msg);
}
 
function _unknownTask($task, $file)
{
$this->_stack->push(__FUNCTION__, 'error', array('task' => $task, 'file' => $file),
'Unknown task "%task%" passed in file <file name="%file%">');
}
 
function _subpackageCannotProvideExtension($name)
{
$this->_stack->push(__FUNCTION__, 'error', array('name' => $name),
'Subpackage dependency "%name%" cannot use <providesextension>, ' .
'only package dependencies can use this tag');
}
 
function _subpackagesCannotConflict($name)
{
$this->_stack->push(__FUNCTION__, 'error', array('name' => $name),
'Subpackage dependency "%name%" cannot use <conflicts/>, ' .
'only package dependencies can use this tag');
}
 
function _cannotProvideExtension($release)
{
$this->_stack->push(__FUNCTION__, 'error', array('release' => $release),
'<%release%> packages cannot use <providesextension>, only extbinrelease, extsrcrelease, zendextsrcrelease, and zendextbinrelease can provide a PHP extension');
}
 
function _mustProvideExtension($release)
{
$this->_stack->push(__FUNCTION__, 'error', array('release' => $release),
'<%release%> packages must use <providesextension> to indicate which PHP extension is provided');
}
 
function _cannotHaveSrcpackage($release)
{
$this->_stack->push(__FUNCTION__, 'error', array('release' => $release),
'<%release%> packages cannot specify a source code package, only extension binaries may use the <srcpackage> tag');
}
 
function _mustSrcPackage($release)
{
$this->_stack->push(__FUNCTION__, 'error', array('release' => $release),
'<extbinrelease>/<zendextbinrelease> packages must specify a source code package with <srcpackage>');
}
 
function _mustSrcuri($release)
{
$this->_stack->push(__FUNCTION__, 'error', array('release' => $release),
'<extbinrelease>/<zendextbinrelease> packages must specify a source code package with <srcuri>');
}
 
function _uriDepsCannotHaveVersioning($type)
{
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type),
'%type%: dependencies with a <uri> tag cannot have any versioning information');
}
 
function _conflictingDepsCannotHaveVersioning($type)
{
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type),
'%type%: conflicting dependencies cannot have versioning info, use <exclude> to ' .
'exclude specific versions of a dependency');
}
 
function _DepchannelCannotBeUri($type)
{
$this->_stack->push(__FUNCTION__, 'error', array('type' => $type),
'%type%: channel cannot be __uri, this is a pseudo-channel reserved for uri ' .
'dependencies only');
}
 
function _bundledPackagesMustBeFilename()
{
$this->_stack->push(__FUNCTION__, 'error', array(),
'<bundledpackage> tags must contain only the filename of a package release ' .
'in the bundle');
}
 
function _binaryPackageMustBePackagename()
{
$this->_stack->push(__FUNCTION__, 'error', array(),
'<binarypackage> tags must contain the name of a package that is ' .
'a compiled version of this extsrc/zendextsrc package');
}
 
function _fileNotFound($file)
{
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
'File "%file%" in package.xml does not exist');
}
 
function _notInContents($file, $tag)
{
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file, 'tag' => $tag),
'<%tag% name="%file%"> is invalid, file is not in <contents>');
}
 
function _cannotValidateNoPathSet()
{
$this->_stack->push(__FUNCTION__, 'error', array(),
'Cannot validate files, no path to package file is set (use setPackageFile())');
}
 
function _usesroletaskMustHaveChannelOrUri($role, $tag)
{
$this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag),
'<%tag%> must contain either <uri>, or <channel> and <package>');
}
 
function _usesroletaskMustHavePackage($role, $tag)
{
$this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag),
'<%tag%> must contain <package>');
}
 
function _usesroletaskMustHaveRoleTask($tag, $type)
{
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, 'type' => $type),
'<%tag%> must contain <%type%> defining the %type% to be used');
}
 
function _cannotConflictWithAllOs($type)
{
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag),
'%tag% cannot conflict with all OSes');
}
 
function _invalidDepGroupName($name)
{
$this->_stack->push(__FUNCTION__, 'error', array('group' => $name),
'Invalid dependency group name "%name%"');
}
 
function _multipleToplevelDirNotAllowed()
{
$this->_stack->push(__FUNCTION__, 'error', array(),
'Multiple top-level <dir> tags are not allowed. Enclose them ' .
'in a <dir name="/">');
}
 
function _multipleInstallAs($file)
{
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
'Only one <install> tag is allowed for file "%file%"');
}
 
function _ignoreAndInstallAs($file)
{
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
'Cannot have both <ignore> and <install> tags for file "%file%"');
}
 
function _analyzeBundledPackages()
{
if (!$this->_isValid) {
return false;
}
if (!$this->_pf->getPackageType() == 'bundle') {
return false;
}
if (!isset($this->_pf->_packageFile)) {
return false;
}
$dir_prefix = dirname($this->_pf->_packageFile);
$log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') :
array('PEAR_Common', 'log');
$info = $this->_pf->getContents();
$info = $info['bundledpackage'];
if (!is_array($info)) {
$info = array($info);
}
$pkg = &new PEAR_PackageFile($this->_pf->_config);
foreach ($info as $package) {
if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $package)) {
$this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $package);
$this->_isValid = 0;
continue;
}
call_user_func_array($log, array(1, "Analyzing bundled package $package"));
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$ret = $pkg->fromAnyFile($dir_prefix . DIRECTORY_SEPARATOR . $package,
PEAR_VALIDATE_NORMAL);
PEAR::popErrorHandling();
if (PEAR::isError($ret)) {
call_user_func_array($log, array(0, "ERROR: package $package is not a valid " .
'package'));
$inf = $ret->getUserInfo();
if (is_array($inf)) {
foreach ($inf as $err) {
call_user_func_array($log, array(1, $err['message']));
}
}
return false;
}
}
return true;
}
 
function _analyzePhpFiles()
{
if (!$this->_isValid) {
return false;
}
if (!isset($this->_pf->_packageFile)) {
$this->_cannotValidateNoPathSet();
return false;
}
$dir_prefix = dirname($this->_pf->_packageFile);
$common = new PEAR_Common;
$log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') :
array(&$common, 'log');
$info = $this->_pf->getContents();
if (!$info || !isset($info['dir']['file'])) {
$this->_tagCannotBeEmpty('contents><dir');
return false;
}
$info = $info['dir']['file'];
if (isset($info['attribs'])) {
$info = array($info);
}
$provides = array();
foreach ($info as $fa) {
$fa = $fa['attribs'];
$file = $fa['name'];
if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) {
$this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $file);
$this->_isValid = 0;
continue;
}
if (in_array($fa['role'], PEAR_Installer_Role::getPhpRoles()) && $dir_prefix) {
call_user_func_array($log, array(1, "Analyzing $file"));
$srcinfo = $this->analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file);
if ($srcinfo) {
$provides = array_merge($provides, $this->_buildProvidesArray($srcinfo));
}
}
}
$this->_packageName = $pn = $this->_pf->getPackage();
$pnl = strlen($pn);
foreach ($provides as $key => $what) {
if (isset($what['explicit']) || !$what) {
// skip conformance checks if the provides entry is
// specified in the package.xml file
continue;
}
extract($what);
if ($type == 'class') {
if (!strncasecmp($name, $pn, $pnl)) {
continue;
}
$this->_stack->push(__FUNCTION__, 'warning',
array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn),
'in %file%: %type% "%name%" not prefixed with package name "%package%"');
} elseif ($type == 'function') {
if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) {
continue;
}
$this->_stack->push(__FUNCTION__, 'warning',
array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn),
'in %file%: %type% "%name%" not prefixed with package name "%package%"');
}
}
return $this->_isValid;
}
 
/**
* Analyze the source code of the given PHP file
*
* @param string Filename of the PHP file
* @param boolean whether to analyze $file as the file contents
* @return mixed
*/
function analyzeSourceCode($file, $string = false)
{
if (!function_exists("token_get_all")) {
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
'Parser error: token_get_all() function must exist to analyze source code, PHP may have been compiled with --disable-tokenizer');
return false;
}
if (!defined('T_DOC_COMMENT')) {
define('T_DOC_COMMENT', T_COMMENT);
}
if (!defined('T_INTERFACE')) {
define('T_INTERFACE', -1);
}
if (!defined('T_IMPLEMENTS')) {
define('T_IMPLEMENTS', -1);
}
if ($string) {
$contents = $file;
} else {
if (!$fp = @fopen($file, "r")) {
return false;
}
fclose($fp);
$contents = file_get_contents($file);
}
$tokens = token_get_all($contents);
/*
for ($i = 0; $i < sizeof($tokens); $i++) {
@list($token, $data) = $tokens[$i];
if (is_string($token)) {
var_dump($token);
} else {
print token_name($token) . ' ';
var_dump(rtrim($data));
}
}
*/
$look_for = 0;
$paren_level = 0;
$bracket_level = 0;
$brace_level = 0;
$lastphpdoc = '';
$current_class = '';
$current_interface = '';
$current_class_level = -1;
$current_function = '';
$current_function_level = -1;
$declared_classes = array();
$declared_interfaces = array();
$declared_functions = array();
$declared_methods = array();
$used_classes = array();
$used_functions = array();
$extends = array();
$implements = array();
$nodeps = array();
$inquote = false;
$interface = false;
for ($i = 0; $i < sizeof($tokens); $i++) {
if (is_array($tokens[$i])) {
list($token, $data) = $tokens[$i];
} else {
$token = $tokens[$i];
$data = '';
}
if ($inquote) {
if ($token != '"' && $token != T_END_HEREDOC) {
continue;
} else {
$inquote = false;
continue;
}
}
switch ($token) {
case T_WHITESPACE :
continue;
case ';':
if ($interface) {
$current_function = '';
$current_function_level = -1;
}
break;
case '"':
case T_START_HEREDOC:
$inquote = true;
break;
case T_CURLY_OPEN:
case T_DOLLAR_OPEN_CURLY_BRACES:
case '{': $brace_level++; continue 2;
case '}':
$brace_level--;
if ($current_class_level == $brace_level) {
$current_class = '';
$current_class_level = -1;
}
if ($current_function_level == $brace_level) {
$current_function = '';
$current_function_level = -1;
}
continue 2;
case '[': $bracket_level++; continue 2;
case ']': $bracket_level--; continue 2;
case '(': $paren_level++; continue 2;
case ')': $paren_level--; continue 2;
case T_INTERFACE:
$interface = true;
case T_CLASS:
if (($current_class_level != -1) || ($current_function_level != -1)) {
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
'Parser error: invalid PHP found in file "%file%"');
return false;
}
case T_FUNCTION:
case T_NEW:
case T_EXTENDS:
case T_IMPLEMENTS:
$look_for = $token;
continue 2;
case T_STRING:
if (version_compare(zend_version(), '2.0', '<')) {
if (in_array(strtolower($data),
array('public', 'private', 'protected', 'abstract',
'interface', 'implements', 'throw')
)) {
$this->_stack->push(__FUNCTION__, 'warning', array(
'file' => $file),
'Error, PHP5 token encountered in %file%,' .
' analysis should be in PHP5');
}
}
if ($look_for == T_CLASS) {
$current_class = $data;
$current_class_level = $brace_level;
$declared_classes[] = $current_class;
} elseif ($look_for == T_INTERFACE) {
$current_interface = $data;
$current_class_level = $brace_level;
$declared_interfaces[] = $current_interface;
} elseif ($look_for == T_IMPLEMENTS) {
$implements[$current_class] = $data;
} elseif ($look_for == T_EXTENDS) {
$extends[$current_class] = $data;
} elseif ($look_for == T_FUNCTION) {
if ($current_class) {
$current_function = "$current_class::$data";
$declared_methods[$current_class][] = $data;
} elseif ($current_interface) {
$current_function = "$current_interface::$data";
$declared_methods[$current_interface][] = $data;
} else {
$current_function = $data;
$declared_functions[] = $current_function;
}
$current_function_level = $brace_level;
$m = array();
} elseif ($look_for == T_NEW) {
$used_classes[$data] = true;
}
$look_for = 0;
continue 2;
case T_VARIABLE:
$look_for = 0;
continue 2;
case T_DOC_COMMENT:
case T_COMMENT:
if (preg_match('!^/\*\*\s!', $data)) {
$lastphpdoc = $data;
if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
$nodeps = array_merge($nodeps, $m[1]);
}
}
continue 2;
case T_DOUBLE_COLON:
if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
$this->_stack->push(__FUNCTION__, 'warning', array('file' => $file),
'Parser error: invalid PHP found in file "%file%"');
return false;
}
$class = $tokens[$i - 1][1];
if (strtolower($class) != 'parent') {
$used_classes[$class] = true;
}
continue 2;
}
}
return array(
"source_file" => $file,
"declared_classes" => $declared_classes,
"declared_interfaces" => $declared_interfaces,
"declared_methods" => $declared_methods,
"declared_functions" => $declared_functions,
"used_classes" => array_diff(array_keys($used_classes), $nodeps),
"inheritance" => $extends,
"implements" => $implements,
);
}
 
/**
* Build a "provides" array from data returned by
* analyzeSourceCode(). The format of the built array is like
* this:
*
* array(
* 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
* ...
* )
*
*
* @param array $srcinfo array with information about a source file
* as returned by the analyzeSourceCode() method.
*
* @return void
*
* @access private
*
*/
function _buildProvidesArray($srcinfo)
{
if (!$this->_isValid) {
return array();
}
$providesret = array();
$file = basename($srcinfo['source_file']);
$pn = $this->_pf->getPackage();
$pnl = strlen($pn);
foreach ($srcinfo['declared_classes'] as $class) {
$key = "class;$class";
if (isset($providesret[$key])) {
continue;
}
$providesret[$key] =
array('file'=> $file, 'type' => 'class', 'name' => $class);
if (isset($srcinfo['inheritance'][$class])) {
$providesret[$key]['extends'] =
$srcinfo['inheritance'][$class];
}
}
foreach ($srcinfo['declared_methods'] as $class => $methods) {
foreach ($methods as $method) {
$function = "$class::$method";
$key = "function;$function";
if ($method{0} == '_' || !strcasecmp($method, $class) ||
isset($providesret[$key])) {
continue;
}
$providesret[$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
}
 
foreach ($srcinfo['declared_functions'] as $function) {
$key = "function;$function";
if ($function{0} == '_' || isset($providesret[$key])) {
continue;
}
if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
$warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
}
$providesret[$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
return $providesret;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/PackageFile/v2/rw.php
New file
0,0 → 1,1601
<?php
/**
* PEAR_PackageFile_v2, package.xml version 2.0, read/write version
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: rw.php,v 1.19 2006/10/30 04:12:02 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a8
*/
/**
* For base class
*/
require_once 'PEAR/PackageFile/v2.php';
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a8
*/
class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2
{
/**
* @param string Extension name
* @return bool success of operation
*/
function setProvidesExtension($extension)
{
if (in_array($this->getPackageType(),
array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
if (!isset($this->_packageInfo['providesextension'])) {
// ensure that the channel tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease',
'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
'bundle', 'changelog'),
$extension, 'providesextension');
}
$this->_packageInfo['providesextension'] = $extension;
return true;
}
return false;
}
 
function setPackage($package)
{
$this->_isValid = 0;
if (!isset($this->_packageInfo['attribs'])) {
$this->_packageInfo = array_merge(array('attribs' => array(
'version' => '2.0',
'xmlns' => 'http://pear.php.net/dtd/package-2.0',
'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0
http://pear.php.net/dtd/tasks-1.0.xsd
http://pear.php.net/dtd/package-2.0
http://pear.php.net/dtd/package-2.0.xsd',
)), $this->_packageInfo);
}
if (!isset($this->_packageInfo['name'])) {
return $this->_packageInfo = array_merge(array('name' => $package),
$this->_packageInfo);
}
$this->_packageInfo['name'] = $package;
}
 
/**
* set this as a package.xml version 2.1
* @access private
*/
function _setPackageVersion2_1()
{
$info = array(
'version' => '2.1',
'xmlns' => 'http://pear.php.net/dtd/package-2.1',
'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0
http://pear.php.net/dtd/tasks-1.0.xsd
http://pear.php.net/dtd/package-2.1
http://pear.php.net/dtd/package-2.1.xsd',
);
if (!isset($this->_packageInfo['attribs'])) {
$this->_packageInfo = array_merge(array('attribs' => $info), $this->_packageInfo);
} else {
$this->_packageInfo['attribs'] = $info;
}
}
 
function setUri($uri)
{
unset($this->_packageInfo['channel']);
$this->_isValid = 0;
if (!isset($this->_packageInfo['uri'])) {
// ensure that the uri tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('extends', 'summary', 'description', 'lead',
'developer', 'contributor', 'helper', 'date', 'time', 'version',
'stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'), $uri, 'uri');
}
$this->_packageInfo['uri'] = $uri;
}
 
function setChannel($channel)
{
unset($this->_packageInfo['uri']);
$this->_isValid = 0;
if (!isset($this->_packageInfo['channel'])) {
// ensure that the channel tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('extends', 'summary', 'description', 'lead',
'developer', 'contributor', 'helper', 'date', 'time', 'version',
'stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'), $channel, 'channel');
}
$this->_packageInfo['channel'] = $channel;
}
 
function setExtends($extends)
{
$this->_isValid = 0;
if (!isset($this->_packageInfo['extends'])) {
// ensure that the extends tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('summary', 'description', 'lead',
'developer', 'contributor', 'helper', 'date', 'time', 'version',
'stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'), $extends, 'extends');
}
$this->_packageInfo['extends'] = $extends;
}
 
function setSummary($summary)
{
$this->_isValid = 0;
if (!isset($this->_packageInfo['summary'])) {
// ensure that the summary tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('description', 'lead',
'developer', 'contributor', 'helper', 'date', 'time', 'version',
'stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'), $summary, 'summary');
}
$this->_packageInfo['summary'] = $summary;
}
 
function setDescription($desc)
{
$this->_isValid = 0;
if (!isset($this->_packageInfo['description'])) {
// ensure that the description tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('lead',
'developer', 'contributor', 'helper', 'date', 'time', 'version',
'stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'), $desc, 'description');
}
$this->_packageInfo['description'] = $desc;
}
 
/**
* Adds a new maintainer - no checking of duplicates is performed, use
* updatemaintainer for that purpose.
*/
function addMaintainer($role, $handle, $name, $email, $active = 'yes')
{
if (!in_array($role, array('lead', 'developer', 'contributor', 'helper'))) {
return false;
}
if (isset($this->_packageInfo[$role])) {
if (!isset($this->_packageInfo[$role][0])) {
$this->_packageInfo[$role] = array($this->_packageInfo[$role]);
}
$this->_packageInfo[$role][] =
array(
'name' => $name,
'user' => $handle,
'email' => $email,
'active' => $active,
);
} else {
$testarr = array('lead',
'developer', 'contributor', 'helper', 'date', 'time', 'version',
'stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog');
foreach (array('lead', 'developer', 'contributor', 'helper') as $testrole) {
array_shift($testarr);
if ($role == $testrole) {
break;
}
}
if (!isset($this->_packageInfo[$role])) {
// ensure that the extends tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, $testarr,
array(), $role);
}
$this->_packageInfo[$role] =
array(
'name' => $name,
'user' => $handle,
'email' => $email,
'active' => $active,
);
}
$this->_isValid = 0;
}
 
function updateMaintainer($newrole, $handle, $name, $email, $active = 'yes')
{
$found = false;
foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
if (!isset($this->_packageInfo[$role])) {
continue;
}
$info = $this->_packageInfo[$role];
if (!isset($info[0])) {
if ($info['user'] == $handle) {
$found = true;
break;
}
}
foreach ($info as $i => $maintainer) {
if ($maintainer['user'] == $handle) {
$found = $i;
break 2;
}
}
}
if ($found === false) {
return $this->addMaintainer($newrole, $handle, $name, $email, $active);
}
if ($found !== false) {
if ($found === true) {
unset($this->_packageInfo[$role]);
} else {
unset($this->_packageInfo[$role][$found]);
$this->_packageInfo[$role] = array_values($this->_packageInfo[$role]);
}
}
$this->addMaintainer($newrole, $handle, $name, $email, $active);
$this->_isValid = 0;
}
 
function deleteMaintainer($handle)
{
$found = false;
foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
if (!isset($this->_packageInfo[$role])) {
continue;
}
if (!isset($this->_packageInfo[$role][0])) {
$this->_packageInfo[$role] = array($this->_packageInfo[$role]);
}
foreach ($this->_packageInfo[$role] as $i => $maintainer) {
if ($maintainer['user'] == $handle) {
$found = $i;
break;
}
}
if ($found !== false) {
unset($this->_packageInfo[$role][$found]);
if (!count($this->_packageInfo[$role]) && $role == 'lead') {
$this->_isValid = 0;
}
if (!count($this->_packageInfo[$role])) {
unset($this->_packageInfo[$role]);
return true;
}
$this->_packageInfo[$role] =
array_values($this->_packageInfo[$role]);
if (count($this->_packageInfo[$role]) == 1) {
$this->_packageInfo[$role] = $this->_packageInfo[$role][0];
}
return true;
}
if (count($this->_packageInfo[$role]) == 1) {
$this->_packageInfo[$role] = $this->_packageInfo[$role][0];
}
}
return false;
}
 
function setReleaseVersion($version)
{
if (isset($this->_packageInfo['version']) &&
isset($this->_packageInfo['version']['release'])) {
unset($this->_packageInfo['version']['release']);
}
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array(
'version' => array('stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'),
'release' => array('api')));
$this->_isValid = 0;
}
 
function setAPIVersion($version)
{
if (isset($this->_packageInfo['version']) &&
isset($this->_packageInfo['version']['api'])) {
unset($this->_packageInfo['version']['api']);
}
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array(
'version' => array('stability', 'license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'),
'api' => array()));
$this->_isValid = 0;
}
 
/**
* snapshot|devel|alpha|beta|stable
*/
function setReleaseStability($state)
{
if (isset($this->_packageInfo['stability']) &&
isset($this->_packageInfo['stability']['release'])) {
unset($this->_packageInfo['stability']['release']);
}
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array(
'stability' => array('license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'),
'release' => array('api')));
$this->_isValid = 0;
}
 
/**
* @param devel|alpha|beta|stable
*/
function setAPIStability($state)
{
if (isset($this->_packageInfo['stability']) &&
isset($this->_packageInfo['stability']['api'])) {
unset($this->_packageInfo['stability']['api']);
}
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array(
'stability' => array('license', 'notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'),
'api' => array()));
$this->_isValid = 0;
}
 
function setLicense($license, $uri = false, $filesource = false)
{
if (!isset($this->_packageInfo['license'])) {
// ensure that the license tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('notes', 'contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'), 0, 'license');
}
if ($uri || $filesource) {
$attribs = array();
if ($uri) {
$attribs['uri'] = $uri;
}
$uri = true; // for test below
if ($filesource) {
$attribs['filesource'] = $filesource;
}
}
$license = $uri ? array('attribs' => $attribs, '_content' => $license) : $license;
$this->_packageInfo['license'] = $license;
$this->_isValid = 0;
}
 
function setNotes($notes)
{
$this->_isValid = 0;
if (!isset($this->_packageInfo['notes'])) {
// ensure that the notes tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('contents', 'compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
'extbinrelease', 'bundle', 'changelog'), $notes, 'notes');
}
$this->_packageInfo['notes'] = $notes;
}
 
/**
* This is only used at install-time, after all serialization
* is over.
* @param string file name
* @param string installed path
*/
function setInstalledAs($file, $path)
{
if ($path) {
return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
}
unset($this->_packageInfo['filelist'][$file]['installed_as']);
}
 
/**
* This is only used at install-time, after all serialization
* is over.
*/
function installedFile($file, $atts)
{
if (isset($this->_packageInfo['filelist'][$file])) {
$this->_packageInfo['filelist'][$file] =
array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']);
} else {
$this->_packageInfo['filelist'][$file] = $atts['attribs'];
}
}
 
/**
* Reset the listing of package contents
* @param string base installation dir for the whole package, if any
*/
function clearContents($baseinstall = false)
{
$this->_filesValid = false;
$this->_isValid = 0;
if (!isset($this->_packageInfo['contents'])) {
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('compatible',
'dependencies', 'providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
'bundle', 'changelog'), array(), 'contents');
}
if ($this->getPackageType() != 'bundle') {
$this->_packageInfo['contents'] =
array('dir' => array('attribs' => array('name' => '/')));
if ($baseinstall) {
$this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'] = $baseinstall;
}
}
}
 
/**
* @param string relative path of the bundled package.
*/
function addBundledPackage($path)
{
if ($this->getPackageType() != 'bundle') {
return false;
}
$this->_filesValid = false;
$this->_isValid = 0;
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $path, array(
'contents' => array('compatible', 'dependencies', 'providesextension',
'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease',
'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
'bundle', 'changelog'),
'bundledpackage' => array()));
}
 
/**
* @param string file name
* @param PEAR_Task_Common a read/write task
*/
function addTaskToFile($filename, $task)
{
if (!method_exists($task, 'getXml')) {
return false;
}
if (!method_exists($task, 'getName')) {
return false;
}
if (!method_exists($task, 'validate')) {
return false;
}
if (!$task->validate()) {
return false;
}
if (!isset($this->_packageInfo['contents']['dir']['file'])) {
return false;
}
$this->getTasksNs(); // discover the tasks namespace if not done already
$files = $this->_packageInfo['contents']['dir']['file'];
if (!isset($files[0])) {
$files = array($files);
$ind = false;
} else {
$ind = true;
}
foreach ($files as $i => $file) {
if (isset($file['attribs'])) {
if ($file['attribs']['name'] == $filename) {
if ($ind) {
$t = isset($this->_packageInfo['contents']['dir']['file'][$i]
['attribs'][$this->_tasksNs .
':' . $task->getName()]) ?
$this->_packageInfo['contents']['dir']['file'][$i]
['attribs'][$this->_tasksNs .
':' . $task->getName()] : false;
if ($t && !isset($t[0])) {
$this->_packageInfo['contents']['dir']['file'][$i]
[$this->_tasksNs . ':' . $task->getName()] = array($t);
}
$this->_packageInfo['contents']['dir']['file'][$i][$this->_tasksNs .
':' . $task->getName()][] = $task->getXml();
} else {
$t = isset($this->_packageInfo['contents']['dir']['file']
['attribs'][$this->_tasksNs .
':' . $task->getName()]) ? $this->_packageInfo['contents']['dir']['file']
['attribs'][$this->_tasksNs .
':' . $task->getName()] : false;
if ($t && !isset($t[0])) {
$this->_packageInfo['contents']['dir']['file']
[$this->_tasksNs . ':' . $task->getName()] = array($t);
}
$this->_packageInfo['contents']['dir']['file'][$this->_tasksNs .
':' . $task->getName()][] = $task->getXml();
}
return true;
}
}
}
return false;
}
 
/**
* @param string path to the file
* @param string filename
* @param array extra attributes
*/
function addFile($dir, $file, $attrs)
{
if ($this->getPackageType() == 'bundle') {
return false;
}
$this->_filesValid = false;
$this->_isValid = 0;
$dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
if ($dir == '/' || $dir == '') {
$dir = '';
} else {
$dir .= '/';
}
$attrs['name'] = $dir . $file;
if (!isset($this->_packageInfo['contents'])) {
// ensure that the contents tag is set up
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
'bundle', 'changelog'), array(), 'contents');
}
if (isset($this->_packageInfo['contents']['dir']['file'])) {
if (!isset($this->_packageInfo['contents']['dir']['file'][0])) {
$this->_packageInfo['contents']['dir']['file'] =
array($this->_packageInfo['contents']['dir']['file']);
}
$this->_packageInfo['contents']['dir']['file'][]['attribs'] = $attrs;
} else {
$this->_packageInfo['contents']['dir']['file']['attribs'] = $attrs;
}
}
 
/**
* @param string Dependent package name
* @param string Dependent package's channel name
* @param string minimum version of specified package that this release is guaranteed to be
* compatible with
* @param string maximum version of specified package that this release is guaranteed to be
* compatible with
* @param string versions of specified package that this release is not compatible with
*/
function addCompatiblePackage($name, $channel, $min, $max, $exclude = false)
{
$this->_isValid = 0;
$set = array(
'name' => $name,
'channel' => $channel,
'min' => $min,
'max' => $max,
);
if ($exclude) {
$set['exclude'] = $exclude;
}
$this->_isValid = 0;
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
'compatible' => array('dependencies', 'providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
));
}
 
/**
* Removes the <usesrole> tag entirely
*/
function resetUsesrole()
{
if (isset($this->_packageInfo['usesrole'])) {
unset($this->_packageInfo['usesrole']);
}
}
 
/**
* @param string
* @param string package name or uri
* @param string channel name if non-uri
*/
function addUsesrole($role, $packageOrUri, $channel = false) {
$set = array('role' => $role);
if ($channel) {
$set['package'] = $packageOrUri;
$set['channel'] = $channel;
} else {
$set['uri'] = $packageOrUri;
}
$this->_isValid = 0;
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
'usesrole' => array('usestask', 'srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
));
}
 
/**
* Removes the <usestask> tag entirely
*/
function resetUsestask()
{
if (isset($this->_packageInfo['usestask'])) {
unset($this->_packageInfo['usestask']);
}
}
 
 
/**
* @param string
* @param string package name or uri
* @param string channel name if non-uri
*/
function addUsestask($task, $packageOrUri, $channel = false) {
$set = array('task' => $task);
if ($channel) {
$set['package'] = $packageOrUri;
$set['channel'] = $channel;
} else {
$set['uri'] = $packageOrUri;
}
$this->_isValid = 0;
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
'usestask' => array('srcpackage', 'srcuri',
'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
));
}
 
/**
* Remove all compatible tags
*/
function clearCompatible()
{
unset($this->_packageInfo['compatible']);
}
 
/**
* Reset dependencies prior to adding new ones
*/
function clearDeps()
{
if (!isset($this->_packageInfo['dependencies'])) {
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(),
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')));
}
$this->_packageInfo['dependencies'] = array();
}
 
/**
* @param string minimum PHP version allowed
* @param string maximum PHP version allowed
* @param array $exclude incompatible PHP versions
*/
function setPhpDep($min, $max = false, $exclude = false)
{
$this->_isValid = 0;
$dep =
array(
'min' => $min,
);
if ($max) {
$dep['max'] = $max;
}
if ($exclude) {
if (count($exclude) == 1) {
$exclude = $exclude[0];
}
$dep['exclude'] = $exclude;
}
if (isset($this->_packageInfo['dependencies']['required']['php'])) {
$this->_stack->push(__FUNCTION__, 'warning', array('dep' =>
$this->_packageInfo['dependencies']['required']['php']),
'warning: PHP dependency already exists, overwriting');
unset($this->_packageInfo['dependencies']['required']['php']);
}
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
'required' => array('optional', 'group'),
'php' => array('pearinstaller', 'package', 'subpackage', 'extension', 'os', 'arch')
));
return true;
}
 
/**
* @param string minimum allowed PEAR installer version
* @param string maximum allowed PEAR installer version
* @param string recommended PEAR installer version
* @param array incompatible version of the PEAR installer
*/
function setPearinstallerDep($min, $max = false, $recommended = false, $exclude = false)
{
$this->_isValid = 0;
$dep =
array(
'min' => $min,
);
if ($max) {
$dep['max'] = $max;
}
if ($recommended) {
$dep['recommended'] = $recommended;
}
if ($exclude) {
if (count($exclude) == 1) {
$exclude = $exclude[0];
}
$dep['exclude'] = $exclude;
}
if (isset($this->_packageInfo['dependencies']['required']['pearinstaller'])) {
$this->_stack->push(__FUNCTION__, 'warning', array('dep' =>
$this->_packageInfo['dependencies']['required']['pearinstaller']),
'warning: PEAR Installer dependency already exists, overwriting');
unset($this->_packageInfo['dependencies']['required']['pearinstaller']);
}
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
'required' => array('optional', 'group'),
'pearinstaller' => array('package', 'subpackage', 'extension', 'os', 'arch')
));
}
 
/**
* Mark a package as conflicting with this package
* @param string package name
* @param string package channel
* @param string extension this package provides, if any
* @param string|false minimum version required
* @param string|false maximum version allowed
* @param array|false versions to exclude from installation
*/
function addConflictingPackageDepWithChannel($name, $channel,
$providesextension = false, $min = false, $max = false, $exclude = false)
{
$this->_isValid = 0;
$dep = $this->_constructDep($name, $channel, false, $min, $max, false,
$exclude, $providesextension, false, true);
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
'required' => array('optional', 'group'),
'package' => array('subpackage', 'extension', 'os', 'arch')
));
}
 
/**
* Mark a package as conflicting with this package
* @param string package name
* @param string package channel
* @param string extension this package provides, if any
*/
function addConflictingPackageDepWithUri($name, $uri, $providesextension = false)
{
$this->_isValid = 0;
$dep =
array(
'name' => $name,
'uri' => $uri,
'conflicts' => '',
);
if ($providesextension) {
$dep['providesextension'] = $providesextension;
}
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
'required' => array('optional', 'group'),
'package' => array('subpackage', 'extension', 'os', 'arch')
));
}
 
function addDependencyGroup($name, $hint)
{
$this->_isValid = 0;
$this->_packageInfo = $this->_mergeTag($this->_packageInfo,
array('attribs' => array('name' => $name, 'hint' => $hint)),
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
'group' => array(),
));
}
 
/**
* @param string package name
* @param string|false channel name, false if this is a uri
* @param string|false uri name, false if this is a channel
* @param string|false minimum version required
* @param string|false maximum version allowed
* @param string|false recommended installation version
* @param array|false versions to exclude from installation
* @param string extension this package provides, if any
* @param bool if true, tells the installer to ignore the default optional dependency group
* when installing this package
* @param bool if true, tells the installer to negate this dependency (conflicts)
* @return array
* @access private
*/
function _constructDep($name, $channel, $uri, $min, $max, $recommended, $exclude,
$providesextension = false, $nodefault = false,
$conflicts = false)
{
$dep =
array(
'name' => $name,
);
if ($channel) {
$dep['channel'] = $channel;
} elseif ($uri) {
$dep['uri'] = $uri;
}
if ($min) {
$dep['min'] = $min;
}
if ($max) {
$dep['max'] = $max;
}
if ($recommended) {
$dep['recommended'] = $recommended;
}
if ($exclude) {
if (is_array($exclude) && count($exclude) == 1) {
$exclude = $exclude[0];
}
$dep['exclude'] = $exclude;
}
if ($conflicts) {
$dep['conflicts'] = '';
}
if ($nodefault) {
$dep['nodefault'] = '';
}
if ($providesextension) {
$dep['providesextension'] = $providesextension;
}
return $dep;
}
 
/**
* @param package|subpackage
* @param string group name
* @param string package name
* @param string package channel
* @param string minimum version
* @param string maximum version
* @param string recommended version
* @param array|false optional excluded versions
* @param string extension this package provides, if any
* @param bool if true, tells the installer to ignore the default optional dependency group
* when installing this package
* @return bool false if the dependency group has not been initialized with
* {@link addDependencyGroup()}, or a subpackage is added with
* a providesextension
*/
function addGroupPackageDepWithChannel($type, $groupname, $name, $channel, $min = false,
$max = false, $recommended = false, $exclude = false,
$providesextension = false, $nodefault = false)
{
if ($type == 'subpackage' && $providesextension) {
return false; // subpackages must be php packages
}
$dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
$providesextension, $nodefault);
return $this->_addGroupDependency($type, $dep, $groupname);
}
 
/**
* @param package|subpackage
* @param string group name
* @param string package name
* @param string package uri
* @param string extension this package provides, if any
* @param bool if true, tells the installer to ignore the default optional dependency group
* when installing this package
* @return bool false if the dependency group has not been initialized with
* {@link addDependencyGroup()}
*/
function addGroupPackageDepWithURI($type, $groupname, $name, $uri, $providesextension = false,
$nodefault = false)
{
if ($type == 'subpackage' && $providesextension) {
return false; // subpackages must be php packages
}
$dep = $this->_constructDep($name, false, $uri, false, false, false, false,
$providesextension, $nodefault);
return $this->_addGroupDependency($type, $dep, $groupname);
}
 
/**
* @param string group name (must be pre-existing)
* @param string extension name
* @param string minimum version allowed
* @param string maximum version allowed
* @param string recommended version
* @param array incompatible versions
*/
function addGroupExtensionDep($groupname, $name, $min = false, $max = false,
$recommended = false, $exclude = false)
{
$this->_isValid = 0;
$dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
return $this->_addGroupDependency('extension', $dep, $groupname);
}
 
/**
* @param package|subpackage|extension
* @param array dependency contents
* @param string name of the dependency group to add this to
* @return boolean
* @access private
*/
function _addGroupDependency($type, $dep, $groupname)
{
$arr = array('subpackage', 'extension');
if ($type != 'package') {
array_shift($arr);
}
if ($type == 'extension') {
array_shift($arr);
}
if (!isset($this->_packageInfo['dependencies']['group'])) {
return false;
} else {
if (!isset($this->_packageInfo['dependencies']['group'][0])) {
if ($this->_packageInfo['dependencies']['group']['attribs']['name'] == $groupname) {
$this->_packageInfo['dependencies']['group'] = $this->_mergeTag(
$this->_packageInfo['dependencies']['group'], $dep,
array(
$type => $arr
));
$this->_isValid = 0;
return true;
} else {
return false;
}
} else {
foreach ($this->_packageInfo['dependencies']['group'] as $i => $group) {
if ($group['attribs']['name'] == $groupname) {
$this->_packageInfo['dependencies']['group'][$i] = $this->_mergeTag(
$this->_packageInfo['dependencies']['group'][$i], $dep,
array(
$type => $arr
));
$this->_isValid = 0;
return true;
}
}
return false;
}
}
}
 
/**
* @param optional|required
* @param string package name
* @param string package channel
* @param string minimum version
* @param string maximum version
* @param string recommended version
* @param string extension this package provides, if any
* @param bool if true, tells the installer to ignore the default optional dependency group
* when installing this package
* @param array|false optional excluded versions
*/
function addPackageDepWithChannel($type, $name, $channel, $min = false, $max = false,
$recommended = false, $exclude = false,
$providesextension = false, $nodefault = false)
{
if (!in_array($type, array('optional', 'required'), true)) {
$type = 'required';
}
$this->_isValid = 0;
$arr = array('optional', 'group');
if ($type != 'required') {
array_shift($arr);
}
$dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
$providesextension, $nodefault);
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
$type => $arr,
'package' => array('subpackage', 'extension', 'os', 'arch')
));
}
 
/**
* @param optional|required
* @param string name of the package
* @param string uri of the package
* @param string extension this package provides, if any
* @param bool if true, tells the installer to ignore the default optional dependency group
* when installing this package
*/
function addPackageDepWithUri($type, $name, $uri, $providesextension = false,
$nodefault = false)
{
$this->_isValid = 0;
$arr = array('optional', 'group');
if ($type != 'required') {
array_shift($arr);
}
$dep = $this->_constructDep($name, false, $uri, false, false, false, false,
$providesextension, $nodefault);
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
$type => $arr,
'package' => array('subpackage', 'extension', 'os', 'arch')
));
}
 
/**
* @param optional|required optional, required
* @param string package name
* @param string package channel
* @param string minimum version
* @param string maximum version
* @param string recommended version
* @param array incompatible versions
* @param bool if true, tells the installer to ignore the default optional dependency group
* when installing this package
*/
function addSubpackageDepWithChannel($type, $name, $channel, $min = false, $max = false,
$recommended = false, $exclude = false,
$nodefault = false)
{
$this->_isValid = 0;
$arr = array('optional', 'group');
if ($type != 'required') {
array_shift($arr);
}
$dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
$nodefault);
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
$type => $arr,
'subpackage' => array('extension', 'os', 'arch')
));
}
 
/**
* @param optional|required optional, required
* @param string package name
* @param string package uri for download
* @param bool if true, tells the installer to ignore the default optional dependency group
* when installing this package
*/
function addSubpackageDepWithUri($type, $name, $uri, $nodefault = false)
{
$this->_isValid = 0;
$arr = array('optional', 'group');
if ($type != 'required') {
array_shift($arr);
}
$dep = $this->_constructDep($name, false, $uri, false, false, false, false, $nodefault);
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
$type => $arr,
'subpackage' => array('extension', 'os', 'arch')
));
}
 
/**
* @param optional|required optional, required
* @param string extension name
* @param string minimum version
* @param string maximum version
* @param string recommended version
* @param array incompatible versions
*/
function addExtensionDep($type, $name, $min = false, $max = false, $recommended = false,
$exclude = false)
{
$this->_isValid = 0;
$arr = array('optional', 'group');
if ($type != 'required') {
array_shift($arr);
}
$dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
$type => $arr,
'extension' => array('os', 'arch')
));
}
 
/**
* @param string Operating system name
* @param boolean true if this package cannot be installed on this OS
*/
function addOsDep($name, $conflicts = false)
{
$this->_isValid = 0;
$dep = array('name' => $name);
if ($conflicts) {
$dep['conflicts'] = '';
}
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
'required' => array('optional', 'group'),
'os' => array('arch')
));
}
 
/**
* @param string Architecture matching pattern
* @param boolean true if this package cannot be installed on this architecture
*/
function addArchDep($pattern, $conflicts = false)
{
$this->_isValid = 0;
$dep = array('pattern' => $pattern);
if ($conflicts) {
$dep['conflicts'] = '';
}
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
array(
'dependencies' => array('providesextension', 'usesrole', 'usestask',
'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
'required' => array('optional', 'group'),
'arch' => array()
));
}
 
/**
* Set the kind of package, and erase all release tags
*
* - a php package is a PEAR-style package
* - an extbin package is a PECL-style extension binary
* - an extsrc package is a PECL-style source for a binary
* - an zendextbin package is a PECL-style zend extension binary
* - an zendextsrc package is a PECL-style source for a zend extension binary
* - a bundle package is a collection of other pre-packaged packages
* @param php|extbin|extsrc|zendextsrc|zendextbin|bundle
* @return bool success
*/
function setPackageType($type)
{
$this->_isValid = 0;
if (!in_array($type, array('php', 'extbin', 'extsrc', 'zendextsrc',
'zendextbin', 'bundle'))) {
return false;
}
if (in_array($type, array('zendextsrc', 'zendextbin'))) {
$this->_setPackageVersion2_1();
}
if ($type != 'bundle') {
$type .= 'release';
}
foreach (array('phprelease', 'extbinrelease', 'extsrcrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle') as $test) {
unset($this->_packageInfo[$test]);
}
if (!isset($this->_packageInfo[$type])) {
// ensure that the release tag is set up
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('changelog'),
array(), $type);
}
$this->_packageInfo[$type] = array();
return true;
}
 
/**
* @return bool true if package type is set up
*/
function addRelease()
{
if ($type = $this->getPackageType()) {
if ($type != 'bundle') {
$type .= 'release';
}
$this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(),
array($type => array('changelog')));
return true;
}
return false;
}
 
/**
* Get the current release tag in order to add to it
* @param bool returns only releases that have installcondition if true
* @return array|null
*/
function &_getCurrentRelease($strict = true)
{
if ($p = $this->getPackageType()) {
if ($strict) {
if ($p == 'extsrc' || $p == 'zendextsrc') {
$a = null;
return $a;
}
}
if ($p != 'bundle') {
$p .= 'release';
}
if (isset($this->_packageInfo[$p][0])) {
return $this->_packageInfo[$p][count($this->_packageInfo[$p]) - 1];
} else {
return $this->_packageInfo[$p];
}
} else {
$a = null;
return $a;
}
}
 
/**
* Add a file to the current release that should be installed under a different name
* @param string <contents> path to file
* @param string name the file should be installed as
*/
function addInstallAs($path, $as)
{
$r = &$this->_getCurrentRelease();
if ($r === null) {
return false;
}
$this->_isValid = 0;
$r = $this->_mergeTag($r, array('attribs' => array('name' => $path, 'as' => $as)),
array(
'filelist' => array(),
'install' => array('ignore')
));
}
 
/**
* Add a file to the current release that should be ignored
* @param string <contents> path to file
* @return bool success of operation
*/
function addIgnore($path)
{
$r = &$this->_getCurrentRelease();
if ($r === null) {
return false;
}
$this->_isValid = 0;
$r = $this->_mergeTag($r, array('attribs' => array('name' => $path)),
array(
'filelist' => array(),
'ignore' => array()
));
}
 
/**
* Add an extension binary package for this extension source code release
*
* Note that the package must be from the same channel as the extension source package
* @param string
*/
function addBinarypackage($package)
{
if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
return false;
}
$r = &$this->_getCurrentRelease(false);
if ($r === null) {
return false;
}
$this->_isValid = 0;
$r = $this->_mergeTag($r, $package,
array(
'binarypackage' => array('filelist'),
));
}
 
/**
* Add a configureoption to an extension source package
* @param string
* @param string
* @param string
*/
function addConfigureOption($name, $prompt, $default = null)
{
if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
return false;
}
$r = &$this->_getCurrentRelease(false);
if ($r === null) {
return false;
}
$opt = array('attribs' => array('name' => $name, 'prompt' => $prompt));
if ($default !== null) {
$opt['default'] = $default;
}
$this->_isValid = 0;
$r = $this->_mergeTag($r, $opt,
array(
'configureoption' => array('binarypackage', 'filelist'),
));
}
 
/**
* Set an installation condition based on php version for the current release set
* @param string minimum version
* @param string maximum version
* @param false|array incompatible versions of PHP
*/
function setPhpInstallCondition($min, $max, $exclude = false)
{
$r = &$this->_getCurrentRelease();
if ($r === null) {
return false;
}
$this->_isValid = 0;
if (isset($r['installconditions']['php'])) {
unset($r['installconditions']['php']);
}
$dep = array('min' => $min, 'max' => $max);
if ($exclude) {
if (is_array($exclude) && count($exclude) == 1) {
$exclude = $exclude[0];
}
$dep['exclude'] = $exclude;
}
if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
$r = $this->_mergeTag($r, $dep,
array(
'installconditions' => array('configureoption', 'binarypackage',
'filelist'),
'php' => array('extension', 'os', 'arch')
));
} else {
$r = $this->_mergeTag($r, $dep,
array(
'installconditions' => array('filelist'),
'php' => array('extension', 'os', 'arch')
));
}
}
 
/**
* @param optional|required optional, required
* @param string extension name
* @param string minimum version
* @param string maximum version
* @param string recommended version
* @param array incompatible versions
*/
function addExtensionInstallCondition($name, $min = false, $max = false, $recommended = false,
$exclude = false)
{
$r = &$this->_getCurrentRelease();
if ($r === null) {
return false;
}
$this->_isValid = 0;
$dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
$r = $this->_mergeTag($r, $dep,
array(
'installconditions' => array('configureoption', 'binarypackage',
'filelist'),
'extension' => array('os', 'arch')
));
} else {
$r = $this->_mergeTag($r, $dep,
array(
'installconditions' => array('filelist'),
'extension' => array('os', 'arch')
));
}
}
 
/**
* Set an installation condition based on operating system for the current release set
* @param string OS name
* @param bool whether this OS is incompatible with the current release
*/
function setOsInstallCondition($name, $conflicts = false)
{
$r = &$this->_getCurrentRelease();
if ($r === null) {
return false;
}
$this->_isValid = 0;
if (isset($r['installconditions']['os'])) {
unset($r['installconditions']['os']);
}
$dep = array('name' => $name);
if ($conflicts) {
$dep['conflicts'] = '';
}
if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
$r = $this->_mergeTag($r, $dep,
array(
'installconditions' => array('configureoption', 'binarypackage',
'filelist'),
'os' => array('arch')
));
} else {
$r = $this->_mergeTag($r, $dep,
array(
'installconditions' => array('filelist'),
'os' => array('arch')
));
}
}
 
/**
* Set an installation condition based on architecture for the current release set
* @param string architecture pattern
* @param bool whether this arch is incompatible with the current release
*/
function setArchInstallCondition($pattern, $conflicts = false)
{
$r = &$this->_getCurrentRelease();
if ($r === null) {
return false;
}
$this->_isValid = 0;
if (isset($r['installconditions']['arch'])) {
unset($r['installconditions']['arch']);
}
$dep = array('pattern' => $pattern);
if ($conflicts) {
$dep['conflicts'] = '';
}
if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
$r = $this->_mergeTag($r, $dep,
array(
'installconditions' => array('configureoption', 'binarypackage',
'filelist'),
'arch' => array()
));
} else {
$r = $this->_mergeTag($r, $dep,
array(
'installconditions' => array('filelist'),
'arch' => array()
));
}
}
 
/**
* For extension binary releases, this is used to specify either the
* static URI to a source package, or the package name and channel of the extsrc/zendextsrc
* package it is based on.
* @param string Package name, or full URI to source package (extsrc/zendextsrc type)
*/
function setSourcePackage($packageOrUri)
{
$this->_isValid = 0;
if (isset($this->_packageInfo['channel'])) {
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease',
'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
'bundle', 'changelog'),
$packageOrUri, 'srcpackage');
} else {
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease',
'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
'bundle', 'changelog'), $packageOrUri, 'srcuri');
}
}
 
/**
* Generate a valid change log entry from the current package.xml
* @param string|false
*/
function generateChangeLogEntry($notes = false)
{
return array(
'version' =>
array(
'release' => $this->getVersion('release'),
'api' => $this->getVersion('api'),
),
'stability' =>
$this->getStability(),
'date' => $this->getDate(),
'license' => $this->getLicense(true),
'notes' => $notes ? $notes : $this->getNotes()
);
}
 
/**
* @param string release version to set change log notes for
* @param array output of {@link generateChangeLogEntry()}
*/
function setChangelogEntry($releaseversion, $contents)
{
if (!isset($this->_packageInfo['changelog'])) {
$this->_packageInfo['changelog']['release'] = $contents;
return;
}
if (!isset($this->_packageInfo['changelog']['release'][0])) {
if ($this->_packageInfo['changelog']['release']['version']['release'] == $releaseversion) {
$this->_packageInfo['changelog']['release'] = array(
$this->_packageInfo['changelog']['release']);
} else {
$this->_packageInfo['changelog']['release'] = array(
$this->_packageInfo['changelog']['release']);
return $this->_packageInfo['changelog']['release'][] = $contents;
}
}
foreach($this->_packageInfo['changelog']['release'] as $index => $changelog) {
if (isset($changelog['version']) &&
strnatcasecmp($changelog['version']['release'], $releaseversion) == 0) {
$curlog = $index;
}
}
if (isset($curlog)) {
$this->_packageInfo['changelog']['release'][$curlog] = $contents;
} else {
$this->_packageInfo['changelog']['release'][] = $contents;
}
}
 
/**
* Remove the changelog entirely
*/
function clearChangeLog()
{
unset($this->_packageInfo['changelog']);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Script.xml
New file
0,0 → 1,15
<role version="1.0">
<releasetypes>php</releasetypes>
<releasetypes>extsrc</releasetypes>
<releasetypes>extbin</releasetypes>
<releasetypes>zendextsrc</releasetypes>
<releasetypes>zendextbin</releasetypes>
<installable>1</installable>
<locationconfig>bin_dir</locationconfig>
<honorsbaseinstall>1</honorsbaseinstall>
<unusualbaseinstall />
<phpfile />
<executable>1</executable>
<phpextension />
<config_vars />
</role>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Doc.xml
New file
0,0 → 1,15
<role version="1.0">
<releasetypes>php</releasetypes>
<releasetypes>extsrc</releasetypes>
<releasetypes>extbin</releasetypes>
<releasetypes>zendextsrc</releasetypes>
<releasetypes>zendextbin</releasetypes>
<installable>1</installable>
<locationconfig>doc_dir</locationconfig>
<honorsbaseinstall />
<unusualbaseinstall />
<phpfile />
<executable />
<phpextension />
<config_vars />
</role>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Test.php
New file
0,0 → 1,34
<?php
/**
* PEAR_Installer_Role_Test
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Test.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Ext.php
New file
0,0 → 1,34
<?php
/**
* PEAR_Installer_Role_Ext
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Ext.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Php.xml
New file
0,0 → 1,15
<role version="1.0">
<releasetypes>php</releasetypes>
<releasetypes>extsrc</releasetypes>
<releasetypes>extbin</releasetypes>
<releasetypes>zendextsrc</releasetypes>
<releasetypes>zendextbin</releasetypes>
<installable>1</installable>
<locationconfig>php_dir</locationconfig>
<honorsbaseinstall>1</honorsbaseinstall>
<unusualbaseinstall />
<phpfile>1</phpfile>
<executable />
<phpextension />
<config_vars />
</role>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Src.xml
New file
0,0 → 1,12
<role version="1.0">
<releasetypes>extsrc</releasetypes>
<releasetypes>zendextsrc</releasetypes>
<installable />
<locationconfig />
<honorsbaseinstall />
<unusualbaseinstall />
<phpfile />
<executable />
<phpextension />
<config_vars />
</role>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Data.xml
New file
0,0 → 1,15
<role version="1.0">
<releasetypes>php</releasetypes>
<releasetypes>extsrc</releasetypes>
<releasetypes>extbin</releasetypes>
<releasetypes>zendextsrc</releasetypes>
<releasetypes>zendextbin</releasetypes>
<installable>1</installable>
<locationconfig>data_dir</locationconfig>
<honorsbaseinstall />
<unusualbaseinstall />
<phpfile />
<executable />
<phpextension />
<config_vars />
</role>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Script.php
New file
0,0 → 1,34
<?php
/**
* PEAR_Installer_Role_Script
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Script.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Doc.php
New file
0,0 → 1,34
<?php
/**
* PEAR_Installer_Role_Doc
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Doc.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Php.php
New file
0,0 → 1,34
<?php
/**
* PEAR_Installer_Role_Php
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Php.php,v 1.7 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Src.php
New file
0,0 → 1,40
<?php
/**
* PEAR_Installer_Role_Src
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Src.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common
{
function setup(&$installer, $pkg, $atts, $file)
{
$installer->source_files++;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Common.php
New file
0,0 → 1,180
<?php
/**
* Base class for all installation roles.
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Common.php,v 1.12 2006/10/19 23:55:32 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Base class for all installation roles.
*
* This class allows extensibility of file roles. Packages with complex
* customization can now provide custom file roles along with the possibility of
* adding configuration values to match.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Installer_Role_Common
{
/**
* @var PEAR_Config
* @access protected
*/
var $config;
 
/**
* @param PEAR_Config
*/
function PEAR_Installer_Role_Common(&$config)
{
$this->config = $config;
}
 
/**
* Retrieve configuration information about a file role from its XML info
*
* @param string $role Role Classname, as in "PEAR_Installer_Role_Data"
* @return array
*/
function getInfo($role)
{
if (empty($GLOBALS['_PEAR_INSTALLER_ROLES'][$role])) {
return PEAR::raiseError('Unknown Role class: "' . $role . '"');
}
return $GLOBALS['_PEAR_INSTALLER_ROLES'][$role];
}
 
/**
* This is called for each file to set up the directories and files
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param array attributes from the <file> tag
* @param string file name
* @return array an array consisting of:
*
* 1 the original, pre-baseinstalldir installation directory
* 2 the final installation directory
* 3 the full path to the final location of the file
* 4 the location of the pre-installation file
*/
function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null)
{
$roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
if (PEAR::isError($roleInfo)) {
return $roleInfo;
}
if (!$roleInfo['locationconfig']) {
return false;
}
if ($roleInfo['honorsbaseinstall']) {
$dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], $layer,
$pkg->getChannel());
if (!empty($atts['baseinstalldir'])) {
$dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
}
} elseif ($roleInfo['unusualbaseinstall']) {
$dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'],
$layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage();
if (!empty($atts['baseinstalldir'])) {
$dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
}
} else {
$dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'],
$layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage();
}
if (dirname($file) != '.' && empty($atts['install-as'])) {
$dest_dir .= DIRECTORY_SEPARATOR . dirname($file);
}
if (empty($atts['install-as'])) {
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file);
} else {
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as'];
}
$orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file;
 
// Clean up the DIRECTORY_SEPARATOR mess
$ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
list($dest_dir, $dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"),
array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR,
DIRECTORY_SEPARATOR),
array($dest_dir, $dest_file, $orig_file));
return array($save_destdir, $dest_dir, $dest_file, $orig_file);
}
 
/**
* Get the name of the configuration variable that specifies the location of this file
* @return string|false
*/
function getLocationConfig()
{
$roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
if (PEAR::isError($roleInfo)) {
return $roleInfo;
}
return $roleInfo['locationconfig'];
}
 
/**
* Do any unusual setup here
* @param PEAR_Installer
* @param PEAR_PackageFile_v2
* @param array file attributes
* @param string file name
*/
function setup(&$installer, $pkg, $atts, $file)
{
}
 
function isExecutable()
{
$roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
if (PEAR::isError($roleInfo)) {
return $roleInfo;
}
return $roleInfo['executable'];
}
 
function isInstallable()
{
$roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
if (PEAR::isError($roleInfo)) {
return $roleInfo;
}
return $roleInfo['installable'];
}
 
function isExtension()
{
$roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
if (PEAR::isError($roleInfo)) {
return $roleInfo;
}
return $roleInfo['phpextension'];
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Test.xml
New file
0,0 → 1,15
<role version="1.0">
<releasetypes>php</releasetypes>
<releasetypes>extsrc</releasetypes>
<releasetypes>extbin</releasetypes>
<releasetypes>zendextsrc</releasetypes>
<releasetypes>zendextbin</releasetypes>
<installable>1</installable>
<locationconfig>test_dir</locationconfig>
<honorsbaseinstall />
<unusualbaseinstall />
<phpfile />
<executable />
<phpextension />
<config_vars />
</role>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Data.php
New file
0,0 → 1,34
<?php
/**
* PEAR_Installer_Role_Data
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Data.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role/Ext.xml
New file
0,0 → 1,12
<role version="1.0">
<releasetypes>extbin</releasetypes>
<releasetypes>zendextbin</releasetypes>
<installable>1</installable>
<locationconfig>ext_dir</locationconfig>
<honorsbaseinstall>1</honorsbaseinstall>
<unusualbaseinstall />
<phpfile />
<executable />
<phpextension>1</phpextension>
<config_vars />
</role>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Installer/Role.php
New file
0,0 → 1,253
<?php
/**
* PEAR_Installer_Role
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Role.php,v 1.16 2006/10/31 02:54:41 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* base class for installer roles
*/
require_once 'PEAR/Installer/Role/Common.php';
require_once 'PEAR/XMLParser.php';
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Installer_Role
{
/**
* Set up any additional configuration variables that file roles require
*
* Never call this directly, it is called by the PEAR_Config constructor
* @param PEAR_Config
* @access private
* @static
*/
function initializeConfig(&$config)
{
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
PEAR_Installer_Role::registerRoles();
}
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) {
if (!$info['config_vars']) {
continue;
}
$config->_addConfigVars($info['config_vars']);
}
}
 
/**
* @param PEAR_PackageFile_v2
* @param string role name
* @param PEAR_Config
* @return PEAR_Installer_Role_Common
* @static
*/
function &factory($pkg, $role, &$config)
{
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
PEAR_Installer_Role::registerRoles();
}
if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) {
$a = false;
return $a;
}
$a = 'PEAR_Installer_Role_' . ucfirst($role);
if (!class_exists($a)) {
require_once str_replace('_', '/', $a) . '.php';
}
$b = new $a($config);
return $b;
}
 
/**
* Get a list of file roles that are valid for the particular release type.
*
* For instance, src files serve no purpose in regular php releases.
* @param string
* @param bool clear cache
* @return array
* @static
*/
function getValidRoles($release, $clear = false)
{
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
PEAR_Installer_Role::registerRoles();
}
static $ret = array();
if ($clear) {
$ret = array();
}
if (isset($ret[$release])) {
return $ret[$release];
}
$ret[$release] = array();
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
if (in_array($release, $okreleases['releasetypes'])) {
$ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
}
}
return $ret[$release];
}
 
/**
* Get a list of roles that require their files to be installed
*
* Most roles must be installed, but src and package roles, for instance
* are pseudo-roles. src files are compiled into a new extension. Package
* roles are actually fully bundled releases of a package
* @param bool clear cache
* @return array
* @static
*/
function getInstallableRoles($clear = false)
{
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
PEAR_Installer_Role::registerRoles();
}
static $ret;
if ($clear) {
unset($ret);
}
if (!isset($ret)) {
$ret = array();
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
if ($okreleases['installable']) {
$ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
}
}
}
return $ret;
}
 
/**
* Return an array of roles that are affected by the baseinstalldir attribute
*
* Most roles ignore this attribute, and instead install directly into:
* PackageName/filepath
* so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php
* @param bool clear cache
* @return array
* @static
*/
function getBaseinstallRoles($clear = false)
{
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
PEAR_Installer_Role::registerRoles();
}
static $ret;
if ($clear) {
unset($ret);
}
if (!isset($ret)) {
$ret = array();
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
if ($okreleases['honorsbaseinstall']) {
$ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
}
}
}
return $ret;
}
 
/**
* Return an array of file roles that should be analyzed for PHP content at package time,
* like the "php" role.
* @param bool clear cache
* @return array
* @static
*/
function getPhpRoles($clear = false)
{
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
PEAR_Installer_Role::registerRoles();
}
static $ret;
if ($clear) {
unset($ret);
}
if (!isset($ret)) {
$ret = array();
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
if ($okreleases['phpfile']) {
$ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
}
}
}
return $ret;
}
 
/**
* Scan through the Command directory looking for classes
* and see what commands they implement.
* @param string which directory to look for classes, defaults to
* the Installer/Roles subdirectory of
* the directory from where this file (__FILE__) is
* included.
*
* @return bool TRUE on success, a PEAR error on failure
* @access public
* @static
*/
function registerRoles($dir = null)
{
$GLOBALS['_PEAR_INSTALLER_ROLES'] = array();
$parser = new PEAR_XMLParser;
if ($dir === null) {
$dir = dirname(__FILE__) . '/Role';
}
if (!file_exists($dir) || !is_dir($dir)) {
return PEAR::raiseError("registerRoles: opendir($dir) failed");
}
$dp = @opendir($dir);
if (empty($dp)) {
return PEAR::raiseError("registerRoles: opendir($dir) failed");
}
while ($entry = readdir($dp)) {
if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
continue;
}
$class = "PEAR_Installer_Role_".substr($entry, 0, -4);
// List of roles
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) {
$file = "$dir/$entry";
$parser->parse(file_get_contents($file));
$data = $parser->getData();
if (!is_array($data['releasetypes'])) {
$data['releasetypes'] = array($data['releasetypes']);
}
$GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data;
}
}
closedir($dp);
ksort($GLOBALS['_PEAR_INSTALLER_ROLES']);
PEAR_Installer_Role::getBaseinstallRoles(true);
PEAR_Installer_Role::getInstallableRoles(true);
PEAR_Installer_Role::getPhpRoles(true);
PEAR_Installer_Role::getValidRoles('****', true);
return true;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/ChannelFile.php
New file
0,0 → 1,1622
<?php
/**
* PEAR_ChannelFile, the channel handling class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: ChannelFile.php,v 1.78 2006/10/31 02:54:40 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* Needed for error handling
*/
require_once 'PEAR/ErrorStack.php';
require_once 'PEAR/XMLParser.php';
require_once 'PEAR/Common.php';
 
/**
* Error code if the channel.xml <channel> tag does not contain a valid version
*/
define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1);
/**
* Error code if the channel.xml <channel> tag version is not supported (version 1.0 is the only supported version,
* currently
*/
define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2);
 
/**
* Error code if parsing is attempted with no xml extension
*/
define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3);
 
/**
* Error code if creating the xml parser resource fails
*/
define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4);
 
/**
* Error code used for all sax xml parsing errors
*/
define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5);
 
/**#@+
* Validation errors
*/
/**
* Error code when channel name is missing
*/
define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6);
/**
* Error code when channel name is invalid
*/
define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7);
/**
* Error code when channel summary is missing
*/
define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8);
/**
* Error code when channel summary is multi-line
*/
define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9);
/**
* Error code when channel server is missing for xmlrpc or soap protocol
*/
define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10);
/**
* Error code when channel server is invalid for xmlrpc or soap protocol
*/
define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11);
/**
* Error code when a mirror name is invalid
*/
define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21);
/**
* Error code when a mirror type is invalid
*/
define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22);
/**
* Error code when an attempt is made to generate xml, but the parsed content is invalid
*/
define('PEAR_CHANNELFILE_ERROR_INVALID', 23);
/**
* Error code when an empty package name validate regex is passed in
*/
define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24);
/**
* Error code when a <function> tag has no version
*/
define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25);
/**
* Error code when a <function> tag has no name
*/
define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26);
/**
* Error code when a <validatepackage> tag has no name
*/
define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27);
/**
* Error code when a <validatepackage> tag has no version attribute
*/
define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28);
/**
* Error code when a mirror does not exist but is called for in one of the set*
* methods.
*/
define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32);
/**
* Error code when a server port is not numeric
*/
define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33);
/**
* Error code when <static> contains no version attribute
*/
define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34);
/**
* Error code when <baseurl> contains no type attribute in a <rest> protocol definition
*/
define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35);
/**
* Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel
*/
define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36);
/**
* Error code when ssl attribute is present and is not "yes"
*/
define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37);
/**#@-*/
 
/**
* Mirror types allowed. Currently only internet servers are recognized.
*/
$GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] = array('server');
 
 
/**
* The Channel handling class
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_ChannelFile {
/**
* @access private
* @var PEAR_ErrorStack
* @access private
*/
var $_stack;
/**
* Supported channel.xml versions, for parsing
* @var array
* @access private
*/
var $_supportedVersions = array('1.0');
 
/**
* Parsed channel information
* @var array
* @access private
*/
var $_channelInfo;
 
/**
* index into the subchannels array, used for parsing xml
* @var int
* @access private
*/
var $_subchannelIndex;
 
/**
* index into the mirrors array, used for parsing xml
* @var int
* @access private
*/
var $_mirrorIndex;
/**
* Flag used to determine the validity of parsed content
* @var boolean
* @access private
*/
var $_isValid = false;
 
function PEAR_ChannelFile()
{
$this->_stack = &new PEAR_ErrorStack('PEAR_ChannelFile');
$this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
$this->_isValid = false;
}
/**
* @return array
* @access protected
*/
function _getErrorMessage()
{
return
array(
PEAR_CHANNELFILE_ERROR_INVALID_VERSION =>
'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%',
PEAR_CHANNELFILE_ERROR_NO_VERSION =>
'No version number found in <channel> tag',
PEAR_CHANNELFILE_ERROR_NO_XML_EXT =>
'%error%',
PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER =>
'Unable to create XML parser',
PEAR_CHANNELFILE_ERROR_PARSER_ERROR =>
'%error%',
PEAR_CHANNELFILE_ERROR_NO_NAME =>
'Missing channel name',
PEAR_CHANNELFILE_ERROR_INVALID_NAME =>
'Invalid channel %tag% "%name%"',
PEAR_CHANNELFILE_ERROR_NO_SUMMARY =>
'Missing channel summary',
PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY =>
'Channel summary should be on one line, but is multi-line',
PEAR_CHANNELFILE_ERROR_NO_HOST =>
'Missing channel server for %type% server',
PEAR_CHANNELFILE_ERROR_INVALID_HOST =>
'Server name "%server%" is invalid for %type% server',
PEAR_CHANNELFILE_ERROR_INVALID_MIRROR =>
'Invalid mirror name "%name%", mirror type %type%',
PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE =>
'Invalid mirror type "%type%"',
PEAR_CHANNELFILE_ERROR_INVALID =>
'Cannot generate xml, contents are invalid',
PEAR_CHANNELFILE_ERROR_EMPTY_REGEX =>
'packagenameregex cannot be empty',
PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION =>
'%parent% %protocol% function has no version',
PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME =>
'%parent% %protocol% function has no name',
PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE =>
'%parent% rest baseurl has no type',
PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME =>
'Validation package has no name in <validatepackage> tag',
PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION =>
'Validation package "%package%" has no version',
PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND =>
'Mirror "%mirror%" does not exist',
PEAR_CHANNELFILE_ERROR_INVALID_PORT =>
'Port "%port%" must be numeric',
PEAR_CHANNELFILE_ERROR_NO_STATICVERSION =>
'<static> tag must contain version attribute',
PEAR_CHANNELFILE_URI_CANT_MIRROR =>
'The __uri pseudo-channel cannot have mirrors',
PEAR_CHANNELFILE_ERROR_INVALID_SSL =>
'%server% has invalid ssl attribute "%ssl%" can only be yes or not present',
);
}
 
/**
* @param string contents of package.xml file
* @return bool success of parsing
*/
function fromXmlString($data)
{
if (preg_match('/<channel\s+version="([0-9]+\.[0-9]+)"/', $data, $channelversion)) {
if (!in_array($channelversion[1], $this->_supportedVersions)) {
$this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error',
array('version' => $channelversion[1]));
return false;
}
$parser = new PEAR_XMLParser;
$result = $parser->parse($data);
if ($result !== true) {
if ($result->getCode() == 1) {
$this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error',
array('error' => $error));
} else {
$this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error');
}
return false;
}
$this->_channelInfo = $parser->getData();
return true;
} else {
$this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data));
return false;
}
}
/**
* @return array
*/
function toArray()
{
if (!$this->_isValid && !$this->validate()) {
return false;
}
return $this->_channelInfo;
}
/**
* @param array
* @static
* @return PEAR_ChannelFile|false false if invalid
*/
function &fromArray($data, $compatibility = false, $stackClass = 'PEAR_ErrorStack')
{
$a = new PEAR_ChannelFile($compatibility, $stackClass);
$a->_fromArray($data);
if (!$a->validate()) {
$a = false;
return $a;
}
return $a;
}
 
/**
* Unlike {@link fromArray()} this does not do any validation
* @param array
* @static
* @return PEAR_ChannelFile
*/
function &fromArrayWithErrors($data, $compatibility = false,
$stackClass = 'PEAR_ErrorStack')
{
$a = new PEAR_ChannelFile($compatibility, $stackClass);
$a->_fromArray($data);
return $a;
}
/**
* @param array
* @access private
*/
function _fromArray($data)
{
$this->_channelInfo = $data;
}
/**
* Wrapper to {@link PEAR_ErrorStack::getErrors()}
* @param boolean determines whether to purge the error stack after retrieving
* @return array
*/
function getErrors($purge = false)
{
return $this->_stack->getErrors($purge);
}
 
/**
* Unindent given string (?)
*
* @param string $str The string that has to be unindented.
* @return string
* @access private
*/
function _unIndent($str)
{
// remove leading newlines
$str = preg_replace('/^[\r\n]+/', '', $str);
// find whitespace at the beginning of the first line
$indent_len = strspn($str, " \t");
$indent = substr($str, 0, $indent_len);
$data = '';
// remove the same amount of whitespace from following lines
foreach (explode("\n", $str) as $line) {
if (substr($line, 0, $indent_len) == $indent) {
$data .= substr($line, $indent_len) . "\n";
}
}
return $data;
}
 
/**
* Parse a channel.xml file. Expects the name of
* a channel xml file as input.
*
* @param string $descfile name of channel xml file
* @return bool success of parsing
*/
function fromXmlFile($descfile)
{
if (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) ||
(!$fp = fopen($descfile, 'r'))) {
require_once 'PEAR.php';
return PEAR::raiseError("Unable to open $descfile");
}
 
// read the whole thing so we only get one cdata callback
// for each block of cdata
fclose($fp);
$data = file_get_contents($descfile);
return $this->fromXmlString($data);
}
 
/**
* Parse channel information from different sources
*
* This method is able to extract information about a channel
* from an .xml file or a string
*
* @access public
* @param string Filename of the source or the source itself
* @return bool
*/
function fromAny($info)
{
if (is_string($info) && file_exists($info) && strlen($info) < 255) {
$tmp = substr($info, -4);
if ($tmp == '.xml') {
$info = $this->fromXmlFile($info);
} else {
$fp = fopen($info, "r");
$test = fread($fp, 5);
fclose($fp);
if ($test == "<?xml") {
$info = $this->fromXmlFile($info);
}
}
if (PEAR::isError($info)) {
require_once 'PEAR.php';
return PEAR::raiseError($info);
}
}
if (is_string($info)) {
$info = $this->fromXmlString($info);
}
return $info;
}
 
/**
* Return an XML document based on previous parsing and modifications
*
* @return string XML data
*
* @access public
*/
function toXml()
{
if (!$this->_isValid && !$this->validate()) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID);
return false;
}
if (!isset($this->_channelInfo['attribs']['version'])) {
$this->_channelInfo['attribs']['version'] = '1.0';
}
$channelInfo = $this->_channelInfo;
$ret = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n";
$ret .= "<channel version=\"" .
$channelInfo['attribs']['version'] . "\" xmlns=\"http://pear.php.net/channel-1.0\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"http://pear.php.net/dtd/channel-"
. $channelInfo['attribs']['version'] . " http://pear.php.net/dtd/channel-" .
$channelInfo['attribs']['version'] . ".xsd\">
<name>$channelInfo[name]</name>
<summary>" . htmlspecialchars($channelInfo['summary'])."</summary>
";
if (isset($channelInfo['suggestedalias'])) {
$ret .= ' <suggestedalias>' . $channelInfo['suggestedalias'] . "</suggestedalias>\n";
}
if (isset($channelInfo['validatepackage'])) {
$ret .= ' <validatepackage version="' .
$channelInfo['validatepackage']['attribs']['version']. '">' .
htmlspecialchars($channelInfo['validatepackage']['_content']) .
"</validatepackage>\n";
}
$ret .= " <servers>\n";
$ret .= ' <primary';
if (isset($channelInfo['servers']['primary']['attribs']['ssl'])) {
$ret .= ' ssl="' . $channelInfo['servers']['primary']['attribs']['ssl'] . '"';
}
if (isset($channelInfo['servers']['primary']['attribs']['port'])) {
$ret .= ' port="' . $channelInfo['servers']['primary']['attribs']['port'] . '"';
}
$ret .= ">\n";
if (isset($channelInfo['servers']['primary']['xmlrpc'])) {
$ret .= $this->_makeXmlrpcXml($channelInfo['servers']['primary']['xmlrpc'], ' ');
}
if (isset($channelInfo['servers']['primary']['rest'])) {
$ret .= $this->_makeRestXml($channelInfo['servers']['primary']['rest'], ' ');
}
if (isset($channelInfo['servers']['primary']['soap'])) {
$ret .= $this->_makeSoapXml($channelInfo['servers']['primary']['soap'], ' ');
}
$ret .= " </primary>\n";
if (isset($channelInfo['servers']['mirror'])) {
$ret .= $this->_makeMirrorsXml($channelInfo);
}
$ret .= " </servers>\n";
$ret .= "</channel>";
return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret));
}
 
/**
* Generate the <xmlrpc> tag
* @access private
*/
function _makeXmlrpcXml($info, $indent)
{
$ret = $indent . "<xmlrpc";
if (isset($info['attribs']['path'])) {
$ret .= ' path="' . htmlspecialchars($info['attribs']['path']) . '"';
}
$ret .= ">\n";
$ret .= $this->_makeFunctionsXml($info['function'], "$indent ");
$ret .= $indent . "</xmlrpc>\n";
return $ret;
}
 
/**
* Generate the <soap> tag
* @access private
*/
function _makeSoapXml($info, $indent)
{
$ret = $indent . "<soap";
if (isset($info['attribs']['path'])) {
$ret .= ' path="' . htmlspecialchars($info['attribs']['path']) . '"';
}
$ret .= ">\n";
$ret .= $this->_makeFunctionsXml($info['function'], "$indent ");
$ret .= $indent . "</soap>\n";
return $ret;
}
 
/**
* Generate the <rest> tag
* @access private
*/
function _makeRestXml($info, $indent)
{
$ret = $indent . "<rest>\n";
if (!isset($info['baseurl'][0])) {
$info['baseurl'] = array($info['baseurl']);
}
foreach ($info['baseurl'] as $url) {
$ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\"";
$ret .= ">" . $url['_content'] . "</baseurl>\n";
}
$ret .= $indent . "</rest>\n";
return $ret;
}
 
/**
* Generate the <mirrors> tag
* @access private
*/
function _makeMirrorsXml($channelInfo)
{
$ret = "";
if (!isset($channelInfo['servers']['mirror'][0])) {
$channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']);
}
foreach ($channelInfo['servers']['mirror'] as $mirror) {
$ret .= ' <mirror host="' . $mirror['attribs']['host'] . '"';
if (isset($mirror['attribs']['port'])) {
$ret .= ' port="' . $mirror['attribs']['port'] . '"';
}
if (isset($mirror['attribs']['ssl'])) {
$ret .= ' ssl="' . $mirror['attribs']['ssl'] . '"';
}
$ret .= ">\n";
if (isset($mirror['xmlrpc']) || isset($mirror['soap'])) {
if (isset($mirror['xmlrpc'])) {
$ret .= $this->_makeXmlrpcXml($mirror['xmlrpc'], ' ');
}
if (isset($mirror['rest'])) {
$ret .= $this->_makeRestXml($mirror['rest'], ' ');
}
if (isset($mirror['soap'])) {
$ret .= $this->_makeSoapXml($mirror['soap'], ' ');
}
$ret .= " </mirror>\n";
} else {
$ret .= "/>\n";
}
}
return $ret;
}
 
/**
* Generate the <functions> tag
* @access private
*/
function _makeFunctionsXml($functions, $indent, $rest = false)
{
$ret = '';
if (!isset($functions[0])) {
$functions = array($functions);
}
foreach ($functions as $function) {
$ret .= "$indent<function version=\"" . $function['attribs']['version'] . "\"";
if ($rest) {
$ret .= ' uri="' . $function['attribs']['uri'] . '"';
}
$ret .= ">" . $function['_content'] . "</function>\n";
}
return $ret;
}
 
/**
* Validation error. Also marks the object contents as invalid
* @param error code
* @param array error information
* @access private
*/
function _validateError($code, $params = array())
{
$this->_stack->push($code, 'error', $params);
$this->_isValid = false;
}
 
/**
* Validation warning. Does not mark the object contents invalid.
* @param error code
* @param array error information
* @access private
*/
function _validateWarning($code, $params = array())
{
$this->_stack->push($code, 'warning', $params);
}
 
/**
* Validate parsed file.
*
* @access public
* @return boolean
*/
function validate()
{
$this->_isValid = true;
$info = $this->_channelInfo;
if (empty($info['name'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME);
} elseif (!$this->validChannelServer($info['name'])) {
if ($info['name'] != '__uri') {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name',
'name' => $info['name']));
}
}
if (empty($info['summary'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
} elseif (strpos(trim($info['summary']), "\n") !== false) {
$this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
array('summary' => $info['summary']));
}
if (isset($info['suggestedalias'])) {
if (!$this->validChannelServer($info['suggestedalias'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias']));
}
}
if (isset($info['localalias'])) {
if (!$this->validChannelServer($info['localalias'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
array('tag' => 'localalias', 'name' =>$info['localalias']));
}
}
if (isset($info['validatepackage'])) {
if (!isset($info['validatepackage']['_content'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME);
}
if (!isset($info['validatepackage']['attribs']['version'])) {
$content = isset($info['validatepackage']['_content']) ?
$info['validatepackage']['_content'] :
null;
$this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION,
array('package' => $content));
}
}
if (isset($info['servers']['primary']['attribs']['port']) &&
!is_numeric($info['servers']['primary']['attribs']['port'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT,
array('port' => $info['servers']['primary']['attribs']['port']));
}
if (isset($info['servers']['primary']['attribs']['ssl']) &&
$info['servers']['primary']['attribs']['ssl'] != 'yes') {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
array('ssl' => $info['servers']['primary']['attribs']['ssl'],
'server' => $info['name']));
}
 
if (isset($info['servers']['primary']['xmlrpc']) &&
isset($info['servers']['primary']['xmlrpc']['function'])) {
$this->_validateFunctions('xmlrpc', $info['servers']['primary']['xmlrpc']['function']);
}
if (isset($info['servers']['primary']['soap']) &&
isset($info['servers']['primary']['soap']['function'])) {
$this->_validateFunctions('soap', $info['servers']['primary']['soap']['function']);
}
if (isset($info['servers']['primary']['rest']) &&
isset($info['servers']['primary']['rest']['baseurl'])) {
$this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']);
}
if (isset($info['servers']['mirror'])) {
if ($this->_channelInfo['name'] == '__uri') {
$this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR);
}
if (!isset($info['servers']['mirror'][0])) {
$info['servers']['mirror'] = array($info['servers']['mirror']);
}
$i = 0;
foreach ($info['servers']['mirror'] as $mirror) {
if (!isset($mirror['attribs']['host'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST,
array('type' => 'mirror'));
} elseif (!$this->validChannelServer($mirror['attribs']['host'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST,
array('server' => $mirror['attribs']['host'], 'type' => 'mirror'));
}
if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host']));
}
if (isset($mirror['xmlrpc'])) {
$this->_validateFunctions('xmlrpc',
$mirror['xmlrpc']['function'], $mirror['attribs']['host']);
}
if (isset($mirror['soap'])) {
$this->_validateFunctions('soap', $mirror['soap']['function'],
$mirror['attribs']['host']);
}
if (isset($mirror['rest'])) {
$this->_validateFunctions('rest', $mirror['rest']['baseurl'],
$mirror['attribs']['host']);
}
}
}
return $this->_isValid;
}
 
/**
* @param string xmlrpc or soap - protocol name this function applies to
* @param array the functions
* @param string the name of the parent element (mirror name, for instance)
*/
function _validateFunctions($protocol, $functions, $parent = '')
{
if (!isset($functions[0])) {
$functions = array($functions);
}
foreach ($functions as $function) {
if (!isset($function['_content']) || empty($function['_content'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME,
array('parent' => $parent, 'protocol' => $protocol));
}
if ($protocol == 'rest') {
if (!isset($function['attribs']['type']) ||
empty($function['attribs']['type'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_BASEURLTYPE,
array('parent' => $parent, 'protocol' => $protocol));
}
} else {
if (!isset($function['attribs']['version']) ||
empty($function['attribs']['version'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION,
array('parent' => $parent, 'protocol' => $protocol));
}
}
}
}
 
/**
* Test whether a string contains a valid channel server.
* @param string $ver the package version to test
* @return bool
*/
function validChannelServer($server)
{
if ($server == '__uri') {
return true;
}
return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server);
}
 
/**
* @return string|false
*/
function getName()
{
if (isset($this->_channelInfo['name'])) {
return $this->_channelInfo['name'];
} else {
return false;
}
}
 
/**
* @return string|false
*/
function getServer()
{
if (isset($this->_channelInfo['name'])) {
return $this->_channelInfo['name'];
} else {
return false;
}
}
 
/**
* @return int|80 port number to connect to
*/
function getPort($mirror = false)
{
if ($mirror) {
if ($mir = $this->getMirror($mirror)) {
if (isset($mir['attribs']['port'])) {
return $mir['attribs']['port'];
} else {
if ($this->getSSL($mirror)) {
return 443;
}
return 80;
}
}
return false;
}
if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) {
return $this->_channelInfo['servers']['primary']['attribs']['port'];
}
if ($this->getSSL()) {
return 443;
}
return 80;
}
 
/**
* @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel
*/
function getSSL($mirror = false)
{
if ($mirror) {
if ($mir = $this->getMirror($mirror)) {
if (isset($mir['attribs']['ssl'])) {
return true;
} else {
return false;
}
}
return false;
}
if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
return true;
}
return false;
}
 
/**
* @return string|false
*/
function getSummary()
{
if (isset($this->_channelInfo['summary'])) {
return $this->_channelInfo['summary'];
} else {
return false;
}
}
 
/**
* @param string xmlrpc or soap
* @param string|false mirror name or false for primary server
*/
function getPath($protocol, $mirror = false)
{
if (!in_array($protocol, array('xmlrpc', 'soap'))) {
return false;
}
if ($mirror) {
if (!($mir = $this->getMirror($mirror))) {
return false;
}
if (isset($mir[$protocol]['attribs']['path'])) {
return $mir[$protocol]['attribs']['path'];
} else {
return $protocol . '.php';
}
} elseif (isset($this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'])) {
return $this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'];
}
return $protocol . '.php';
}
 
/**
* @param string protocol type (xmlrpc, soap)
* @param string Mirror name
* @return array|false
*/
function getFunctions($protocol, $mirror = false)
{
if ($this->getName() == '__uri') {
return false;
}
if ($protocol == 'rest') {
$function = 'baseurl';
} else {
$function = 'function';
}
if ($mirror) {
if ($mir = $this->getMirror($mirror)) {
if (isset($mir[$protocol][$function])) {
return $mir[$protocol][$function];
}
}
return false;
}
if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) {
return $this->_channelInfo['servers']['primary'][$protocol][$function];
} else {
return false;
}
}
 
/**
* @param string Protocol type
* @param string Function name (null to return the
* first protocol of the type requested)
* @param string Mirror name, if any
* @return array
*/
function getFunction($type, $name = null, $mirror = false)
{
$protocols = $this->getFunctions($type, $mirror);
if (!$protocols) {
return false;
}
foreach ($protocols as $protocol) {
if ($name === null) {
return $protocol;
}
if ($protocol['_content'] != $name) {
continue;
}
return $protocol;
}
return false;
}
 
/**
* @param string protocol type
* @param string protocol name
* @param string version
* @param string mirror name
* @return boolean
*/
function supports($type, $name = null, $mirror = false, $version = '1.0')
{
$protocols = $this->getFunctions($type, $mirror);
if (!$protocols) {
return false;
}
foreach ($protocols as $protocol) {
if ($protocol['attribs']['version'] != $version) {
continue;
}
if ($name === null) {
return true;
}
if ($protocol['_content'] != $name) {
continue;
}
return true;
}
return false;
}
 
/**
* Determines whether a channel supports Representational State Transfer (REST) protocols
* for retrieving channel information
* @param string
* @return bool
*/
function supportsREST($mirror = false)
{
if ($mirror == $this->_channelInfo['name']) {
$mirror = false;
}
if ($mirror) {
if ($mir = $this->getMirror($mirror)) {
return isset($mir['rest']);
}
return false;
}
return isset($this->_channelInfo['servers']['primary']['rest']);
}
 
/**
* Get the URL to access a base resource.
*
* Hyperlinks in the returned xml will be used to retrieve the proper information
* needed. This allows extreme extensibility and flexibility in implementation
* @param string Resource Type to retrieve
*/
function getBaseURL($resourceType, $mirror = false)
{
if ($mirror == $this->_channelInfo['name']) {
$mirror = false;
}
if ($mirror) {
if ($mir = $this->getMirror($mirror)) {
$rest = $mir['rest'];
} else {
return false;
}
$server = $mirror;
} else {
$rest = $this->_channelInfo['servers']['primary']['rest'];
$server = $this->getServer();
}
if (!isset($rest['baseurl'][0])) {
$rest['baseurl'] = array($rest['baseurl']);
}
foreach ($rest['baseurl'] as $baseurl) {
if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) {
return $baseurl['_content'];
}
}
return false;
}
 
/**
* Since REST does not implement RPC, provide this as a logical wrapper around
* resetFunctions for REST
* @param string|false mirror name, if any
*/
function resetREST($mirror = false)
{
return $this->resetFunctions('rest', $mirror);
}
 
/**
* Empty all protocol definitions
* @param string protocol type (xmlrpc, soap)
* @param string|false mirror name, if any
*/
function resetFunctions($type, $mirror = false)
{
if ($mirror) {
if (isset($this->_channelInfo['servers']['mirror'])) {
$mirrors = $this->_channelInfo['servers']['mirror'];
if (!isset($mirrors[0])) {
$mirrors = array($mirrors);
}
foreach ($mirrors as $i => $mir) {
if ($mir['attribs']['host'] == $mirror) {
if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) {
unset($this->_channelInfo['servers']['mirror'][$i][$type]);
}
return true;
}
}
return false;
} else {
return false;
}
} else {
if (isset($this->_channelInfo['servers']['primary'][$type])) {
unset($this->_channelInfo['servers']['primary'][$type]);
}
return true;
}
}
 
/**
* Set a channel's protocols to the protocols supported by pearweb
*/
function setDefaultPEARProtocols($version = '1.0', $mirror = false)
{
switch ($version) {
case '1.0' :
$this->resetFunctions('xmlrpc', $mirror);
$this->resetFunctions('soap', $mirror);
$this->resetREST($mirror);
$this->addFunction('xmlrpc', '1.0', 'logintest', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.listLatestReleases', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.listAll', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.info', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.getDownloadURL', $mirror);
$this->addFunction('xmlrpc', '1.1', 'package.getDownloadURL', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.getDepDownloadURL', $mirror);
$this->addFunction('xmlrpc', '1.1', 'package.getDepDownloadURL', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.search', $mirror);
$this->addFunction('xmlrpc', '1.0', 'channel.listAll', $mirror);
return true;
break;
default :
return false;
break;
}
}
/**
* @return array
*/
function getMirrors()
{
if (isset($this->_channelInfo['servers']['mirror'])) {
$mirrors = $this->_channelInfo['servers']['mirror'];
if (!isset($mirrors[0])) {
$mirrors = array($mirrors);
}
return $mirrors;
} else {
return array();
}
}
 
/**
* Get the unserialized XML representing a mirror
* @return array|false
*/
function getMirror($server)
{
foreach ($this->getMirrors() as $mirror) {
if ($mirror['attribs']['host'] == $server) {
return $mirror;
}
}
return false;
}
 
/**
* @param string
* @return string|false
* @error PEAR_CHANNELFILE_ERROR_NO_NAME
* @error PEAR_CHANNELFILE_ERROR_INVALID_NAME
*/
function setName($name)
{
return $this->setServer($name);
}
 
/**
* Set the socket number (port) that is used to connect to this channel
* @param integer
* @param string|false name of the mirror server, or false for the primary
*/
function setPort($port, $mirror = false)
{
if ($mirror) {
if (!isset($this->_channelInfo['servers']['mirror'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
$setmirror = false;
if (isset($this->_channelInfo['servers']['mirror'][0])) {
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
if ($mirror == $mir['attribs']['host']) {
$this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port;
return true;
}
}
return false;
} elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
$this->_channelInfo['servers']['mirror']['attribs']['port'] = $port;
$this->_isValid = false;
return true;
}
}
$this->_channelInfo['servers']['primary']['attribs']['port'] = $port;
$this->_isValid = false;
return true;
}
 
/**
* Set the socket number (port) that is used to connect to this channel
* @param bool Determines whether to turn on SSL support or turn it off
* @param string|false name of the mirror server, or false for the primary
*/
function setSSL($ssl = true, $mirror = false)
{
if ($mirror) {
if (!isset($this->_channelInfo['servers']['mirror'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
$setmirror = false;
if (isset($this->_channelInfo['servers']['mirror'][0])) {
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
if ($mirror == $mir['attribs']['host']) {
if (!$ssl) {
if (isset($this->_channelInfo['servers']['mirror'][$i]
['attribs']['ssl'])) {
unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']);
}
} else {
$this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes';
}
return true;
}
}
return false;
} elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
if (!$ssl) {
if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) {
unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']);
}
} else {
$this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes';
}
$this->_isValid = false;
return true;
}
}
if ($ssl) {
$this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes';
} else {
if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
unset($this->_channelInfo['servers']['primary']['attribs']['ssl']);
}
}
$this->_isValid = false;
return true;
}
 
/**
* Set the socket number (port) that is used to connect to this channel
* @param integer
* @param string|false name of the mirror server, or false for the primary
*/
function setPath($protocol, $path, $mirror = false)
{
if (!in_array($protocol, array('xmlrpc', 'soap'))) {
return false;
}
if ($mirror) {
if (!isset($this->_channelInfo['servers']['mirror'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
$setmirror = false;
if (isset($this->_channelInfo['servers']['mirror'][0])) {
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
if ($mirror == $mir['attribs']['host']) {
$this->_channelInfo['servers']['mirror'][$i][$protocol]['attribs']['path'] =
$path;
return true;
}
}
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
} elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
$this->_channelInfo['servers']['mirror'][$protocol]['attribs']['path'] = $path;
$this->_isValid = false;
return true;
}
}
$this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'] = $path;
$this->_isValid = false;
return true;
}
 
/**
* @param string
* @return string|false
* @error PEAR_CHANNELFILE_ERROR_NO_SERVER
* @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER
*/
function setServer($server, $mirror = false)
{
if (empty($server)) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER);
return false;
} elseif (!$this->validChannelServer($server)) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
array('tag' => 'name', 'name' => $server));
return false;
}
if ($mirror) {
$found = false;
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
if ($mirror == $mir['attribs']['host']) {
$found = true;
break;
}
}
if (!$found) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
$this->_channelInfo['mirror'][$i]['attribs']['host'] = $server;
return true;
}
$this->_channelInfo['name'] = $server;
return true;
}
 
/**
* @param string
* @return boolean success
* @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY
* @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY
*/
function setSummary($summary)
{
if (empty($summary)) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
return false;
} elseif (strpos(trim($summary), "\n") !== false) {
$this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
array('summary' => $summary));
}
$this->_channelInfo['summary'] = $summary;
return true;
}
 
/**
* @param string
* @param boolean determines whether the alias is in channel.xml or local
* @return boolean success
*/
function setAlias($alias, $local = false)
{
if (!$this->validChannelServer($alias)) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
array('tag' => 'suggestedalias', 'name' => $alias));
return false;
}
if ($local) {
$this->_channelInfo['localalias'] = $alias;
} else {
$this->_channelInfo['suggestedalias'] = $alias;
}
return true;
}
 
/**
* @return string
*/
function getAlias()
{
if (isset($this->_channelInfo['localalias'])) {
return $this->_channelInfo['localalias'];
}
if (isset($this->_channelInfo['suggestedalias'])) {
return $this->_channelInfo['suggestedalias'];
}
if (isset($this->_channelInfo['name'])) {
return $this->_channelInfo['name'];
}
}
 
/**
* Set the package validation object if it differs from PEAR's default
* The class must be includeable via changing _ in the classname to path separator,
* but no checking of this is made.
* @param string|false pass in false to reset to the default packagename regex
* @return boolean success
*/
function setValidationPackage($validateclass, $version)
{
if (empty($validateclass)) {
unset($this->_channelInfo['validatepackage']);
}
$this->_channelInfo['validatepackage'] = array('_content' => $validateclass);
$this->_channelInfo['validatepackage']['attribs'] = array('version' => $version);
}
 
/**
* Add a protocol to the provides section
* @param string protocol type
* @param string protocol version
* @param string protocol name, if any
* @param string mirror name, if this is a mirror's protocol
* @return bool
*/
function addFunction($type, $version, $name = '', $mirror = false)
{
if ($mirror) {
return $this->addMirrorFunction($mirror, $type, $version, $name);
}
$set = array('attribs' => array('version' => $version), '_content' => $name);
if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) {
if (!isset($this->_channelInfo['servers'])) {
$this->_channelInfo['servers'] = array('primary' =>
array($type => array()));
} elseif (!isset($this->_channelInfo['servers']['primary'])) {
$this->_channelInfo['servers']['primary'] = array($type => array());
}
$this->_channelInfo['servers']['primary'][$type]['function'] = $set;
$this->_isValid = false;
return true;
} elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) {
$this->_channelInfo['servers']['primary'][$type]['function'] = array(
$this->_channelInfo['servers']['primary'][$type]['function']);
}
$this->_channelInfo['servers']['primary'][$type]['function'][] = $set;
return true;
}
/**
* Add a protocol to a mirror's provides section
* @param string mirror name (server)
* @param string protocol type
* @param string protocol version
* @param string protocol name, if any
*/
function addMirrorFunction($mirror, $type, $version, $name = '')
{
$found = false;
if (!isset($this->_channelInfo['servers']['mirror'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
$setmirror = false;
if (isset($this->_channelInfo['servers']['mirror'][0])) {
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
if ($mirror == $mir['attribs']['host']) {
$setmirror = &$this->_channelInfo['servers']['mirror'][$i];
break;
}
}
} else {
if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
$setmirror = &$this->_channelInfo['servers']['mirror'];
}
}
if (!$setmirror) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
$set = array('attribs' => array('version' => $version), '_content' => $name);
if (!isset($setmirror[$type]['function'])) {
$setmirror[$type]['function'] = $set;
$this->_isValid = false;
return true;
} elseif (!isset($setmirror[$type]['function'][0])) {
$setmirror[$type]['function'] = array($setmirror[$type]['function']);
}
$setmirror[$type]['function'][] = $set;
$this->_isValid = false;
return true;
}
 
/**
* @param string Resource Type this url links to
* @param string URL
* @param string|false mirror name, if this is not a primary server REST base URL
*/
function setBaseURL($resourceType, $url, $mirror = false)
{
if ($mirror) {
$found = false;
if (!isset($this->_channelInfo['servers']['mirror'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
$setmirror = false;
if (isset($this->_channelInfo['servers']['mirror'][0])) {
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
if ($mirror == $mir['attribs']['host']) {
$setmirror = &$this->_channelInfo['servers']['mirror'][$i];
break;
}
}
} else {
if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
$setmirror = &$this->_channelInfo['servers']['mirror'];
}
}
} else {
$setmirror = &$this->_channelInfo['servers']['primary'];
}
$set = array('attribs' => array('type' => $resourceType), '_content' => $url);
if (!isset($setmirror['rest'])) {
$setmirror['rest'] = array();
}
if (!isset($setmirror['rest']['baseurl'])) {
$setmirror['rest']['baseurl'] = $set;
$this->_isValid = false;
return true;
} elseif (!isset($setmirror['rest']['baseurl'][0])) {
$setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']);
}
foreach ($setmirror['rest']['baseurl'] as $i => $url) {
if ($url['attribs']['type'] == $resourceType) {
$this->_isValid = false;
$setmirror['rest']['baseurl'][$i] = $set;
return true;
}
}
$setmirror['rest']['baseurl'][] = $set;
$this->_isValid = false;
return true;
}
 
/**
* @param string mirror server
* @param int mirror http port
* @return boolean
*/
function addMirror($server, $port = null)
{
if ($this->_channelInfo['name'] == '__uri') {
return false; // the __uri channel cannot have mirrors by definition
}
$set = array('attribs' => array('host' => $server));
if (is_numeric($port)) {
$set['attribs']['port'] = $port;
}
if (!isset($this->_channelInfo['servers']['mirror'])) {
$this->_channelInfo['servers']['mirror'] = $set;
return true;
} else {
if (!isset($this->_channelInfo['servers']['mirror'][0])) {
$this->_channelInfo['servers']['mirror'] =
array($this->_channelInfo['servers']['mirror']);
}
}
$this->_channelInfo['servers']['mirror'][] = $set;
return true;
}
 
/**
* Retrieve the name of the validation package for this channel
* @return string|false
*/
function getValidationPackage()
{
if (!$this->_isValid && !$this->validate()) {
return false;
}
if (!isset($this->_channelInfo['validatepackage'])) {
return array('attribs' => array('version' => 'default'),
'_content' => 'PEAR_Validate');
}
return $this->_channelInfo['validatepackage'];
}
 
/**
* Retrieve the object that can be used for custom validation
* @param string|false the name of the package to validate. If the package is
* the channel validation package, PEAR_Validate is returned
* @return PEAR_Validate|false false is returned if the validation package
* cannot be located
*/
function &getValidationObject($package = false)
{
if (!class_exists('PEAR_Validate')) {
require_once 'PEAR/Validate.php';
}
if (!$this->_isValid) {
if (!$this->validate()) {
$a = false;
return $a;
}
}
if (isset($this->_channelInfo['validatepackage'])) {
if ($package == $this->_channelInfo['validatepackage']) {
// channel validation packages are always validated by PEAR_Validate
$val = &new PEAR_Validate;
return $val;
}
if (!class_exists(str_replace('.', '_',
$this->_channelInfo['validatepackage']['_content']))) {
if ($this->isIncludeable(str_replace('_', '/',
$this->_channelInfo['validatepackage']['_content']) . '.php')) {
include_once str_replace('_', '/',
$this->_channelInfo['validatepackage']['_content']) . '.php';
$vclass = str_replace('.', '_',
$this->_channelInfo['validatepackage']['_content']);
$val = &new $vclass;
} else {
$a = false;
return $a;
}
} else {
$vclass = str_replace('.', '_',
$this->_channelInfo['validatepackage']['_content']);
$val = &new $vclass;
}
} else {
$val = &new PEAR_Validate;
}
return $val;
}
 
function isIncludeable($path)
{
$possibilities = explode(PATH_SEPARATOR, ini_get('include_path'));
foreach ($possibilities as $dir) {
if (file_exists($dir . DIRECTORY_SEPARATOR . $path)
&& is_readable($dir . DIRECTORY_SEPARATOR . $path)) {
return true;
}
}
return false;
}
 
/**
* This function is used by the channel updater and retrieves a value set by
* the registry, or the current time if it has not been set
* @return string
*/
function lastModified()
{
if (isset($this->_channelInfo['_lastmodified'])) {
return $this->_channelInfo['_lastmodified'];
}
return time();
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Downloader/Package.php
New file
0,0 → 1,1790
<?php
/**
* PEAR_Downloader_Package
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Package.php,v 1.104 2007/01/14 21:11:54 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Error code when parameter initialization fails because no releases
* exist within preferred_state, but releases do exist
*/
define('PEAR_DOWNLOADER_PACKAGE_STATE', -1003);
/**
* Coordinates download parameters and manages their dependencies
* prior to downloading them.
*
* Input can come from three sources:
*
* - local files (archives or package.xml)
* - remote files (downloadable urls)
* - abstract package names
*
* The first two elements are handled cleanly by PEAR_PackageFile, but the third requires
* accessing pearweb's xml-rpc interface to determine necessary dependencies, and the
* format returned of dependencies is slightly different from that used in package.xml.
*
* This class hides the differences between these elements, and makes automatic
* dependency resolution a piece of cake. It also manages conflicts when
* two classes depend on incompatible dependencies, or differing versions of the same
* package dependency. In addition, download will not be attempted if the php version is
* not supported, PEAR installer version is not supported, or non-PECL extensions are not
* installed.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Downloader_Package
{
/**
* @var PEAR_Downloader
*/
var $_downloader;
/**
* @var PEAR_Config
*/
var $_config;
/**
* @var PEAR_Registry
*/
var $_registry;
/**
* Used to implement packagingroot properly
* @var PEAR_Registry
*/
var $_installRegistry;
/**
* @var PEAR_PackageFile_v1|PEAR_PackageFile|v2
*/
var $_packagefile;
/**
* @var array
*/
var $_parsedname;
/**
* @var array
*/
var $_downloadURL;
/**
* @var array
*/
var $_downloadDeps = array();
/**
* @var boolean
*/
var $_valid = false;
/**
* @var boolean
*/
var $_analyzed = false;
/**
* if this or a parent package was invoked with Package-state, this is set to the
* state variable.
*
* This allows temporary reassignment of preferred_state for a parent package and all of
* its dependencies.
* @var string|false
*/
var $_explicitState = false;
/**
* If this package is invoked with Package#group, this variable will be true
*/
var $_explicitGroup = false;
/**
* Package type local|url|xmlrpc
* @var string
*/
var $_type;
/**
* Contents of package.xml, if downloaded from a remote channel
* @var string|false
* @access private
*/
var $_rawpackagefile;
/**
* @var boolean
* @access private
*/
var $_validated = false;
 
/**
* @param PEAR_Downloader
*/
function PEAR_Downloader_Package(&$downloader)
{
$this->_downloader = &$downloader;
$this->_config = &$this->_downloader->config;
$this->_registry = &$this->_config->getRegistry();
$options = $downloader->getOptions();
if (isset($options['packagingroot'])) {
$this->_config->setInstallRoot($options['packagingroot']);
$this->_installRegistry = &$this->_config->getRegistry();
$this->_config->setInstallRoot(false);
} else {
$this->_installRegistry = &$this->_registry;
}
$this->_valid = $this->_analyzed = false;
}
 
/**
* Parse the input and determine whether this is a local file, a remote uri, or an
* abstract package name.
*
* This is the heart of the PEAR_Downloader_Package(), and is used in
* {@link PEAR_Downloader::download()}
* @param string
* @return bool|PEAR_Error
*/
function initialize($param)
{
$origErr = $this->_fromFile($param);
if (!$this->_valid) {
$options = $this->_downloader->getOptions();
if (isset($options['offline'])) {
if (PEAR::isError($origErr)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $origErr->getMessage());
}
}
return PEAR::raiseError('Cannot download non-local package "' . $param . '"');
}
$err = $this->_fromUrl($param);
if (PEAR::isError($err) || !$this->_valid) {
if ($this->_type == 'url') {
if (PEAR::isError($err)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $err->getMessage());
}
}
return PEAR::raiseError("Invalid or missing remote package file");
}
$err = $this->_fromString($param);
if (PEAR::isError($err) || !$this->_valid) {
if (PEAR::isError($err) &&
$err->getCode() == PEAR_DOWNLOADER_PACKAGE_STATE) {
return false; // instruct the downloader to silently skip
}
if (isset($this->_type) && $this->_type == 'local' &&
PEAR::isError($origErr)) {
if (is_array($origErr->getUserInfo())) {
foreach ($origErr->getUserInfo() as $err) {
if (is_array($err)) {
$err = $err['message'];
}
if (!isset($options['soft'])) {
$this->_downloader->log(0, $err);
}
}
}
if (!isset($options['soft'])) {
$this->_downloader->log(0, $origErr->getMessage());
}
if (is_array($param)) {
$param = $this->_registry->parsedPackageNameToString($param,
true);
}
return PEAR::raiseError(
"Cannot initialize '$param', invalid or missing package file");
}
if (PEAR::isError($err)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $err->getMessage());
}
}
if (is_array($param)) {
$param = $this->_registry->parsedPackageNameToString($param, true);
}
return PEAR::raiseError(
"Cannot initialize '$param', invalid or missing package file");
}
}
}
return true;
}
 
/**
* Retrieve any non-local packages
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|PEAR_Error
*/
function &download()
{
if (isset($this->_packagefile)) {
return $this->_packagefile;
}
if (isset($this->_downloadURL['url'])) {
$this->_isvalid = false;
$info = $this->getParsedPackage();
foreach ($info as $i => $p) {
$info[$i] = strtolower($p);
}
$err = $this->_fromUrl($this->_downloadURL['url'],
$this->_registry->parsedPackageNameToString($this->_parsedname, true));
$newinfo = $this->getParsedPackage();
foreach ($newinfo as $i => $p) {
$newinfo[$i] = strtolower($p);
}
if ($info != $newinfo) {
do {
if ($info['package'] == 'pecl.php.net' && $newinfo['package'] == 'pear.php.net') {
$info['package'] = 'pear.php.net';
if ($info == $newinfo) {
// skip the channel check if a pecl package says it's a PEAR package
break;
}
}
return PEAR::raiseError('CRITICAL ERROR: We are ' .
$this->_registry->parsedPackageNameToString($info) . ', but the file ' .
'downloaded claims to be ' .
$this->_registry->parsedPackageNameToString($this->getParsedPackage()));
} while (false);
}
if (PEAR::isError($err) || !$this->_valid) {
return $err;
}
}
$this->_type = 'local';
return $this->_packagefile;
}
 
function &getPackageFile()
{
return $this->_packagefile;
}
 
function &getDownloader()
{
return $this->_downloader;
}
 
function getType()
{
return $this->_type;
}
 
/**
* Like {@link initialize()}, but operates on a dependency
*/
function fromDepURL($dep)
{
$this->_downloadURL = $dep;
if (isset($dep['uri'])) {
$options = $this->_downloader->getOptions();
if (!extension_loaded("zlib") || isset($options['nocompress'])) {
$ext = '.tar';
} else {
$ext = '.tgz';
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->_fromUrl($dep['uri'] . $ext);
PEAR::popErrorHandling();
if (PEAR::isError($err)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $err->getMessage());
}
return PEAR::raiseError('Invalid uri dependency "' . $dep['uri'] . $ext . '", ' .
'cannot download');
}
} else {
$this->_parsedname =
array(
'package' => $dep['info']->getPackage(),
'channel' => $dep['info']->getChannel(),
'version' => $dep['version']
);
if (!isset($dep['nodefault'])) {
$this->_parsedname['group'] = 'default'; // download the default dependency group
$this->_explicitGroup = false;
}
$this->_rawpackagefile = $dep['raw'];
}
}
 
function detectDependencies($params)
{
$options = $this->_downloader->getOptions();
if (isset($options['downloadonly'])) {
return;
}
if (isset($options['offline'])) {
$this->_downloader->log(3, 'Skipping dependency download check, --offline specified');
return;
}
$pname = $this->getParsedPackage();
if (!$pname) {
return;
}
$deps = $this->getDeps();
if (!$deps) {
return;
}
if (isset($deps['required'])) { // package.xml 2.0
return $this->_detect2($deps, $pname, $options, $params);
} else {
return $this->_detect1($deps, $pname, $options, $params);
}
}
 
function setValidated()
{
$this->_validated = true;
}
 
function alreadyValidated()
{
return $this->_validated;
}
 
/**
* Remove packages to be downloaded that are already installed
* @param array of PEAR_Downloader_Package objects
* @static
*/
function removeInstalled(&$params)
{
if (!isset($params[0])) {
return;
}
$options = $params[0]->_downloader->getOptions();
if (!isset($options['downloadonly'])) {
foreach ($params as $i => $param) {
// remove self if already installed with this version
// this does not need any pecl magic - we only remove exact matches
if ($param->_installRegistry->packageExists($param->getPackage(), $param->getChannel())) {
if (version_compare($param->_installRegistry->packageInfo($param->getPackage(), 'version',
$param->getChannel()), $param->getVersion(), '==')) {
if (!isset($options['force'])) {
$info = $param->getParsedPackage();
unset($info['version']);
unset($info['state']);
if (!isset($options['soft'])) {
$param->_downloader->log(1, 'Skipping package "' .
$param->getShortName() .
'", already installed as version ' .
$param->_installRegistry->packageInfo($param->getPackage(),
'version', $param->getChannel()));
}
$params[$i] = false;
}
} elseif (!isset($options['force']) && !isset($options['upgrade']) &&
!isset($options['soft'])) {
$info = $param->getParsedPackage();
$param->_downloader->log(1, 'Skipping package "' .
$param->getShortName() .
'", already installed as version ' .
$param->_installRegistry->packageInfo($param->getPackage(), 'version',
$param->getChannel()));
$params[$i] = false;
}
}
}
}
PEAR_Downloader_Package::removeDuplicates($params);
}
 
function _detect2($deps, $pname, $options, $params)
{
$this->_downloadDeps = array();
$groupnotfound = false;
foreach (array('package', 'subpackage') as $packagetype) {
// get required dependency group
if (isset($deps['required'][$packagetype])) {
if (isset($deps['required'][$packagetype][0])) {
foreach ($deps['required'][$packagetype] as $dep) {
if (isset($dep['conflicts'])) {
// skip any package that this package conflicts with
continue;
}
$ret = $this->_detect2Dep($dep, $pname, 'required', $params);
if (is_array($ret)) {
$this->_downloadDeps[] = $ret;
}
}
} else {
$dep = $deps['required'][$packagetype];
if (!isset($dep['conflicts'])) {
// skip any package that this package conflicts with
$ret = $this->_detect2Dep($dep, $pname, 'required', $params);
if (is_array($ret)) {
$this->_downloadDeps[] = $ret;
}
}
}
}
// get optional dependency group, if any
if (isset($deps['optional'][$packagetype])) {
$skipnames = array();
if (!isset($deps['optional'][$packagetype][0])) {
$deps['optional'][$packagetype] = array($deps['optional'][$packagetype]);
}
foreach ($deps['optional'][$packagetype] as $dep) {
$skip = false;
if (!isset($options['alldeps'])) {
$dep['package'] = $dep['name'];
if (!isset($options['soft'])) {
$this->_downloader->log(3, 'Notice: package "' .
$this->_registry->parsedPackageNameToString($this->getParsedPackage(),
true) . '" optional dependency "' .
$this->_registry->parsedPackageNameToString(array('package' =>
$dep['name'], 'channel' => 'pear.php.net'), true) .
'" will not be automatically downloaded');
}
$skipnames[] = $this->_registry->parsedPackageNameToString($dep, true);
$skip = true;
unset($dep['package']);
}
if (!($ret = $this->_detect2Dep($dep, $pname, 'optional', $params))) {
$dep['package'] = $dep['name'];
$skip = count($skipnames) ?
$skipnames[count($skipnames) - 1] : '';
if ($skip ==
$this->_registry->parsedPackageNameToString($dep, true)) {
array_pop($skipnames);
}
}
if (!$skip && is_array($ret)) {
$this->_downloadDeps[] = $ret;
}
}
if (count($skipnames)) {
if (!isset($options['soft'])) {
$this->_downloader->log(1, 'Did not download optional dependencies: ' .
implode(', ', $skipnames) .
', use --alldeps to download automatically');
}
}
}
// get requested dependency group, if any
$groupname = $this->getGroup();
$explicit = $this->_explicitGroup;
if (!$groupname) {
if ($this->canDefault()) {
$groupname = 'default'; // try the default dependency group
} else {
continue;
}
}
if ($groupnotfound) {
continue;
}
if (isset($deps['group'])) {
if (isset($deps['group']['attribs'])) {
if (strtolower($deps['group']['attribs']['name']) == strtolower($groupname)) {
$group = $deps['group'];
} elseif ($explicit) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, 'Warning: package "' .
$this->_registry->parsedPackageNameToString($pname, true) .
'" has no dependency ' . 'group named "' . $groupname . '"');
}
$groupnotfound = true;
continue;
}
} else {
$found = false;
foreach ($deps['group'] as $group) {
if (strtolower($group['attribs']['name']) == strtolower($groupname)) {
$found = true;
break;
}
}
if (!$found) {
if ($explicit) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, 'Warning: package "' .
$this->_registry->parsedPackageNameToString($pname, true) .
'" has no dependency ' . 'group named "' . $groupname . '"');
}
}
$groupnotfound = true;
continue;
}
}
}
if (isset($group)) {
if (isset($group[$packagetype])) {
if (isset($group[$packagetype][0])) {
foreach ($group[$packagetype] as $dep) {
$ret = $this->_detect2Dep($dep, $pname, 'dependency group "' .
$group['attribs']['name'] . '"', $params);
if (is_array($ret)) {
$this->_downloadDeps[] = $ret;
}
}
} else {
$ret = $this->_detect2Dep($group[$packagetype], $pname,
'dependency group "' .
$group['attribs']['name'] . '"', $params);
if (is_array($ret)) {
$this->_downloadDeps[] = $ret;
}
}
}
}
}
}
 
function _detect2Dep($dep, $pname, $group, $params)
{
if (isset($dep['conflicts'])) {
return true;
}
$options = $this->_downloader->getOptions();
if (isset($dep['uri'])) {
return array('uri' => $dep['uri'], 'dep' => $dep);;
}
$testdep = $dep;
$testdep['package'] = $dep['name'];
if (PEAR_Downloader_Package::willDownload($testdep, $params)) {
$dep['package'] = $dep['name'];
if (!isset($options['soft'])) {
$this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group .
' dependency "' .
$this->_registry->parsedPackageNameToString($dep, true) .
'", will be installed');
}
return false;
}
$options = $this->_downloader->getOptions();
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
if ($this->_explicitState) {
$pname['state'] = $this->_explicitState;
}
$url =
$this->_downloader->_getDepPackageDownloadUrl($dep, $pname);
if (PEAR::isError($url)) {
PEAR::popErrorHandling();
return $url;
}
$dep['package'] = $dep['name'];
$ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, $group == 'optional' &&
!isset($options['alldeps']), true);
PEAR::popErrorHandling();
if (PEAR::isError($ret)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
return false;
} else {
// check to see if a dep is already installed and is the same or newer
if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['recommended'])) {
$oper = 'has';
} else {
$oper = 'gt';
}
// do not try to move this before getDepPackageDownloadURL
// we can't determine whether upgrade is necessary until we know what
// version would be downloaded
if (!isset($options['force']) && $this->isInstalled($ret, $oper)) {
$version = $this->_installRegistry->packageInfo($dep['name'], 'version',
$dep['channel']);
$dep['package'] = $dep['name'];
if (!isset($options['soft'])) {
$this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group .
' dependency "' .
$this->_registry->parsedPackageNameToString($dep, true) .
'" version ' . $url['version'] . ', already installed as version ' .
$version);
}
return false;
}
}
if (isset($dep['nodefault'])) {
$ret['nodefault'] = true;
}
return $ret;
}
 
function _detect1($deps, $pname, $options, $params)
{
$this->_downloadDeps = array();
$skipnames = array();
foreach ($deps as $dep) {
$nodownload = false;
if ($dep['type'] == 'pkg') {
$dep['channel'] = 'pear.php.net';
$dep['package'] = $dep['name'];
switch ($dep['rel']) {
case 'not' :
continue 2;
case 'ge' :
case 'eq' :
case 'gt' :
case 'has' :
$group = (!isset($dep['optional']) || $dep['optional'] == 'no') ?
'required' :
'optional';
if (PEAR_Downloader_Package::willDownload($dep, $params)) {
$this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group
. ' dependency "' .
$this->_registry->parsedPackageNameToString($dep, true) .
'", will be installed');
continue 2;
}
$fakedp = new PEAR_PackageFile_v1;
$fakedp->setPackage($dep['name']);
// skip internet check if we are not upgrading (bug #5810)
if (!isset($options['upgrade']) && $this->isInstalled(
$fakedp, $dep['rel'])) {
$this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group
. ' dependency "' .
$this->_registry->parsedPackageNameToString($dep, true) .
'", is already installed');
continue 2;
}
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
if ($this->_explicitState) {
$pname['state'] = $this->_explicitState;
}
$url =
$this->_downloader->_getDepPackageDownloadUrl($dep, $pname);
$chan = 'pear.php.net';
if (PEAR::isError($url)) {
// check to see if this is a pecl package that has jumped
// from pear.php.net to pecl.php.net channel
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
$newdep = PEAR_Dependency2::normalizeDep($dep);
$newdep = $newdep[0];
$newdep['channel'] = 'pecl.php.net';
$chan = 'pecl.php.net';
$url =
$this->_downloader->_getDepPackageDownloadUrl($newdep, $pname);
$obj = &$this->_installRegistry->getPackage($dep['name']);
if (PEAR::isError($url)) {
PEAR::popErrorHandling();
if ($obj !== null && $this->isInstalled($obj, $dep['rel'])) {
$group = (!isset($dep['optional']) || $dep['optional'] == 'no') ?
'required' :
'optional';
$dep['package'] = $dep['name'];
if (!isset($options['soft'])) {
$this->_downloader->log(3, $this->getShortName() .
': Skipping ' . $group . ' dependency "' .
$this->_registry->parsedPackageNameToString($dep, true) .
'", already installed as version ' . $obj->getVersion());
}
$skip = count($skipnames) ?
$skipnames[count($skipnames) - 1] : '';
if ($skip ==
$this->_registry->parsedPackageNameToString($dep, true)) {
array_pop($skipnames);
}
continue;
} else {
if (isset($dep['optional']) && $dep['optional'] == 'yes') {
$this->_downloader->log(2, $this->getShortName() .
': Skipping ' . $group
. ' dependency "' .
$this->_registry->parsedPackageNameToString($dep, true) .
'", no releases exist');
continue;
} else {
return $url;
}
}
}
}
PEAR::popErrorHandling();
if (!isset($options['alldeps'])) {
if (isset($dep['optional']) && $dep['optional'] == 'yes') {
if (!isset($options['soft'])) {
$this->_downloader->log(3, 'Notice: package "' .
$this->getShortName() .
'" optional dependency "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $chan, 'package' =>
$dep['name']), true) .
'" will not be automatically downloaded');
}
$skipnames[] = $this->_registry->parsedPackageNameToString(
array('channel' => $chan, 'package' =>
$dep['name']), true);
$nodownload = true;
}
}
if (!isset($options['alldeps']) && !isset($options['onlyreqdeps'])) {
if (!isset($dep['optional']) || $dep['optional'] == 'no') {
if (!isset($options['soft'])) {
$this->_downloader->log(3, 'Notice: package "' .
$this->getShortName() .
'" required dependency "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $chan, 'package' =>
$dep['name']), true) .
'" will not be automatically downloaded');
}
$skipnames[] = $this->_registry->parsedPackageNameToString(
array('channel' => $chan, 'package' =>
$dep['name']), true);
$nodownload = true;
}
}
// check to see if a dep is already installed
// do not try to move this before getDepPackageDownloadURL
// we can't determine whether upgrade is necessary until we know what
// version would be downloaded
if (!isset($options['force']) && $this->isInstalled(
$url, $dep['rel'])) {
$group = (!isset($dep['optional']) || $dep['optional'] == 'no') ?
'required' :
'optional';
$dep['package'] = $dep['name'];
if (isset($newdep)) {
$version = $this->_installRegistry->packageInfo($newdep['name'], 'version',
$newdep['channel']);
} else {
$version = $this->_installRegistry->packageInfo($dep['name'], 'version');
}
$dep['version'] = $url['version'];
if (!isset($options['soft'])) {
$this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group .
' dependency "' .
$this->_registry->parsedPackageNameToString($dep, true) .
'", already installed as version ' . $version);
}
$skip = count($skipnames) ?
$skipnames[count($skipnames) - 1] : '';
if ($skip ==
$this->_registry->parsedPackageNameToString($dep, true)) {
array_pop($skipnames);
}
continue;
}
if ($nodownload) {
continue;
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
if (isset($newdep)) {
$dep = $newdep;
}
$dep['package'] = $dep['name'];
$ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params,
isset($dep['optional']) && $dep['optional'] == 'yes' &&
!isset($options['alldeps']), true);
PEAR::popErrorHandling();
if (PEAR::isError($ret)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
continue;
}
$this->_downloadDeps[] = $ret;
}
}
if (count($skipnames)) {
if (!isset($options['soft'])) {
$this->_downloader->log(1, 'Did not download dependencies: ' .
implode(', ', $skipnames) .
', use --alldeps or --onlyreqdeps to download automatically');
}
}
}
 
function setDownloadURL($pkg)
{
$this->_downloadURL = $pkg;
}
 
/**
* Set the package.xml object for this downloaded package
*
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 $pkg
*/
function setPackageFile(&$pkg)
{
$this->_packagefile = &$pkg;
}
 
function getShortName()
{
return $this->_registry->parsedPackageNameToString(array('channel' => $this->getChannel(),
'package' => $this->getPackage()), true);
}
 
function getParsedPackage()
{
if (isset($this->_packagefile) || isset($this->_parsedname)) {
return array('channel' => $this->getChannel(),
'package' => $this->getPackage(),
'version' => $this->getVersion());
}
return false;
}
 
function getDownloadURL()
{
return $this->_downloadURL;
}
 
function canDefault()
{
if (isset($this->_downloadURL)) {
if (isset($this->_downloadURL['nodefault'])) {
return false;
}
}
return true;
}
 
function getPackage()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getPackage();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getPackage();
} else {
return false;
}
}
 
/**
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
*/
function isSubpackage(&$pf)
{
if (isset($this->_packagefile)) {
return $this->_packagefile->isSubpackage($pf);
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->isSubpackage($pf);
} else {
return false;
}
}
 
function getPackageType()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getPackageType();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getPackageType();
} else {
return false;
}
}
 
function isBundle()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getPackageType() == 'bundle';
} else {
return false;
}
}
 
function getPackageXmlVersion()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getPackagexmlVersion();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getPackagexmlVersion();
} else {
return '1.0';
}
}
 
function getChannel()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getChannel();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getChannel();
} else {
return false;
}
}
 
function getURI()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getURI();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getURI();
} else {
return false;
}
}
 
function getVersion()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getVersion();
} elseif (isset($this->_downloadURL['version'])) {
return $this->_downloadURL['version'];
} else {
return false;
}
}
 
function isCompatible($pf)
{
if (isset($this->_packagefile)) {
return $this->_packagefile->isCompatible($pf);
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->isCompatible($pf);
} else {
return true;
}
}
 
function setGroup($group)
{
$this->_parsedname['group'] = $group;
}
 
function getGroup()
{
if (isset($this->_parsedname['group'])) {
return $this->_parsedname['group'];
} else {
return '';
}
}
 
function isExtension($name)
{
if (isset($this->_packagefile)) {
return $this->_packagefile->isExtension($name);
} elseif (isset($this->_downloadURL['info'])) {
if ($this->_downloadURL['info']->getPackagexmlVersion() == '2.0') {
return $this->_downloadURL['info']->getProvidesExtension() == $name;
} else {
return false;
}
} else {
return false;
}
}
 
function getDeps()
{
if (isset($this->_packagefile)) {
$ver = $this->_packagefile->getPackagexmlVersion();
if (version_compare($ver, '2.0', '>=')) {
return $this->_packagefile->getDeps(true);
} else {
return $this->_packagefile->getDeps();
}
} elseif (isset($this->_downloadURL['info'])) {
$ver = $this->_downloadURL['info']->getPackagexmlVersion();
if (version_compare($ver, '2.0', '>=')) {
return $this->_downloadURL['info']->getDeps(true);
} else {
return $this->_downloadURL['info']->getDeps();
}
} else {
return array();
}
}
 
/**
* @param array Parsed array from {@link PEAR_Registry::parsePackageName()} or a dependency
* returned from getDepDownloadURL()
*/
function isEqual($param)
{
if (is_object($param)) {
$channel = $param->getChannel();
$package = $param->getPackage();
if ($param->getURI()) {
$param = array(
'channel' => $param->getChannel(),
'package' => $param->getPackage(),
'version' => $param->getVersion(),
'uri' => $param->getURI(),
);
} else {
$param = array(
'channel' => $param->getChannel(),
'package' => $param->getPackage(),
'version' => $param->getVersion(),
);
}
} else {
if (isset($param['uri'])) {
if ($this->getChannel() != '__uri') {
return false;
}
return $param['uri'] == $this->getURI();
}
$package = isset($param['package']) ? $param['package'] :
$param['info']->getPackage();
$channel = isset($param['channel']) ? $param['channel'] :
$param['info']->getChannel();
if (isset($param['rel'])) {
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
$newdep = PEAR_Dependency2::normalizeDep($param);
$newdep = $newdep[0];
} elseif (isset($param['min'])) {
$newdep = $param;
}
}
if (isset($newdep)) {
if (!isset($newdep['min'])) {
$newdep['min'] = '0';
}
if (!isset($newdep['max'])) {
$newdep['max'] = '100000000000000000000';
}
// use magic to support pecl packages suddenly jumping to the pecl channel
// we need to support both dependency possibilities
if ($channel == 'pear.php.net' && $this->getChannel() == 'pecl.php.net') {
if ($package == $this->getPackage()) {
$channel = 'pecl.php.net';
}
}
if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') {
if ($package == $this->getPackage()) {
$channel = 'pear.php.net';
}
}
return (strtolower($package) == strtolower($this->getPackage()) &&
$channel == $this->getChannel() &&
version_compare($newdep['min'], $this->getVersion(), '<=') &&
version_compare($newdep['max'], $this->getVersion(), '>='));
}
// use magic to support pecl packages suddenly jumping to the pecl channel
if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') {
if (strtolower($package) == strtolower($this->getPackage())) {
$channel = 'pear.php.net';
}
}
if (isset($param['version'])) {
return (strtolower($package) == strtolower($this->getPackage()) &&
$channel == $this->getChannel() &&
$param['version'] == $this->getVersion());
} else {
return strtolower($package) == strtolower($this->getPackage()) &&
$channel == $this->getChannel();
}
}
 
function isInstalled($dep, $oper = '==')
{
if (!$dep) {
return false;
}
if ($oper != 'ge' && $oper != 'gt' && $oper != 'has' && $oper != '==') {
return false;
}
if (is_object($dep)) {
$package = $dep->getPackage();
$channel = $dep->getChannel();
if ($dep->getURI()) {
$dep = array(
'uri' => $dep->getURI(),
'version' => $dep->getVersion(),
);
} else {
$dep = array(
'version' => $dep->getVersion(),
);
}
} else {
if (isset($dep['uri'])) {
$channel = '__uri';
$package = $dep['dep']['name'];
} else {
$channel = $dep['info']->getChannel();
$package = $dep['info']->getPackage();
}
}
$options = $this->_downloader->getOptions();
$test = $this->_installRegistry->packageExists($package, $channel);
if (!$test && $channel == 'pecl.php.net') {
// do magic to allow upgrading from old pecl packages to new ones
$test = $this->_installRegistry->packageExists($package, 'pear.php.net');
$channel = 'pear.php.net';
}
if ($test) {
if (isset($dep['uri'])) {
if ($this->_installRegistry->packageInfo($package, 'uri', '__uri') == $dep['uri']) {
return true;
}
}
if (isset($options['upgrade'])) {
if ($oper == 'has') {
if (version_compare($this->_installRegistry->packageInfo(
$package, 'version', $channel),
$dep['version'], '>=')) {
return true;
} else {
return false;
}
} else {
if (version_compare($this->_installRegistry->packageInfo(
$package, 'version', $channel),
$dep['version'], '>=')) {
return true;
}
return false;
}
}
return true;
}
return false;
}
 
/**
* @param array
* @param bool ignore install groups - for final removal of dupe packages
* @static
*/
function removeDuplicates(&$params, $ignoreGroups = false)
{
$pnames = array();
foreach ($params as $i => $param) {
if (!$param) {
continue;
}
if ($param->getPackage()) {
if ($ignoreGroups) {
$group = '';
} else {
$group = $param->getGroup();
}
$pnames[$i] = $param->getChannel() . '/' .
$param->getPackage() . '-' . $param->getVersion() . '#' . $group;
}
}
$pnames = array_unique($pnames);
$unset = array_diff(array_keys($params), array_keys($pnames));
$testp = array_flip($pnames);
foreach ($params as $i => $param) {
if (!$param) {
$unset[] = $i;
continue;
}
if (!is_a($param, 'PEAR_Downloader_Package')) {
$unset[] = $i;
continue;
}
if ($ignoreGroups) {
$group = '';
} else {
$group = $param->getGroup();
}
if (!isset($testp[$param->getChannel() . '/' . $param->getPackage() . '-' .
$param->getVersion() . '#' . $group])) {
$unset[] = $i;
}
}
foreach ($unset as $i) {
unset($params[$i]);
}
$ret = array();
foreach ($params as $i => $param) {
$ret[] = &$params[$i];
}
$params = array();
foreach ($ret as $i => $param) {
$params[] = &$ret[$i];
}
}
 
function explicitState()
{
return $this->_explicitState;
}
 
function setExplicitState($s)
{
$this->_explicitState = $s;
}
 
/**
* @static
*/
function mergeDependencies(&$params)
{
$newparams = array();
$bundles = array();
foreach ($params as $i => $param) {
if (!$param->isBundle()) {
continue;
}
$bundles[] = $i;
$pf = &$param->getPackageFile();
$newdeps = array();
$contents = $pf->getBundledPackages();
if (!is_array($contents)) {
$contents = array($contents);
}
foreach ($contents as $file) {
$filecontents = $pf->getFileContents($file);
$dl = &$param->getDownloader();
$options = $dl->getOptions();
if (PEAR::isError($dir = $dl->getDownloadDir())) {
return $dir;
}
$fp = @fopen($dir . DIRECTORY_SEPARATOR . $file, 'wb');
if (!$fp) {
continue;
}
fwrite($fp, $filecontents, strlen($filecontents));
fclose($fp);
if ($s = $params[$i]->explicitState()) {
$obj->setExplicitState($s);
}
$obj = &new PEAR_Downloader_Package($params[$i]->getDownloader());
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
if (PEAR::isError($dir = $dl->getDownloadDir())) {
PEAR::popErrorHandling();
return $dir;
}
$e = $obj->_fromFile($a = $dir . DIRECTORY_SEPARATOR . $file);
PEAR::popErrorHandling();
if (PEAR::isError($e)) {
if (!isset($options['soft'])) {
$dl->log(0, $e->getMessage());
}
continue;
}
$j = &$obj;
if (!PEAR_Downloader_Package::willDownload($j,
array_merge($params, $newparams)) && !$param->isInstalled($j)) {
$newparams[] = &$j;
}
}
}
foreach ($bundles as $i) {
unset($params[$i]); // remove bundles - only their contents matter for installation
}
PEAR_Downloader_Package::removeDuplicates($params); // strip any unset indices
if (count($newparams)) { // add in bundled packages for install
foreach ($newparams as $i => $unused) {
$params[] = &$newparams[$i];
}
$newparams = array();
}
foreach ($params as $i => $param) {
$newdeps = array();
foreach ($param->_downloadDeps as $dep) {
if (!PEAR_Downloader_Package::willDownload($dep,
array_merge($params, $newparams)) && !$param->isInstalled($dep)) {
$newdeps[] = $dep;
} else {
// detect versioning conflicts here
}
}
// convert the dependencies into PEAR_Downloader_Package objects for the next time
// around
$params[$i]->_downloadDeps = array();
foreach ($newdeps as $dep) {
$obj = &new PEAR_Downloader_Package($params[$i]->getDownloader());
if ($s = $params[$i]->explicitState()) {
$obj->setExplicitState($s);
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$e = $obj->fromDepURL($dep);
PEAR::popErrorHandling();
if (PEAR::isError($e)) {
if (!isset($options['soft'])) {
$obj->_downloader->log(0, $e->getMessage());
}
continue;
}
$e = $obj->detectDependencies($params);
if (PEAR::isError($e)) {
if (!isset($options['soft'])) {
$obj->_downloader->log(0, $e->getMessage());
}
}
$j = &$obj;
$newparams[] = &$j;
}
}
if (count($newparams)) {
foreach ($newparams as $i => $unused) {
$params[] = &$newparams[$i];
}
return true;
} else {
return false;
}
}
 
 
/**
* @static
*/
function willDownload($param, $params)
{
if (!is_array($params)) {
return false;
}
foreach ($params as $obj) {
if ($obj->isEqual($param)) {
return true;
}
}
return false;
}
 
/**
* For simpler unit-testing
* @param PEAR_Config
* @param int
* @param string
*/
function &getPackagefileObject(&$c, $d, $t = false)
{
$a = &new PEAR_PackageFile($c, $d, $t);
return $a;
}
 
 
/**
* This will retrieve from a local file if possible, and parse out
* a group name as well. The original parameter will be modified to reflect this.
* @param string|array can be a parsed package name as well
* @access private
*/
function _fromFile(&$param)
{
$saveparam = $param;
if (is_string($param)) {
if (!@file_exists($param)) {
$test = explode('#', $param);
$group = array_pop($test);
if (file_exists(implode('#', $test))) {
$this->setGroup($group);
$param = implode('#', $test);
$this->_explicitGroup = true;
}
}
if (@is_file($param)) {
$this->_type = 'local';
$options = $this->_downloader->getOptions();
if (isset($options['downloadonly'])) {
$pkg = &$this->getPackagefileObject($this->_config,
$this->_downloader->_debug);
} else {
if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) {
return $dir;
}
$pkg = &$this->getPackagefileObject($this->_config,
$this->_downloader->_debug, $dir);
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pf = &$pkg->fromAnyFile($param, PEAR_VALIDATE_INSTALLING);
PEAR::popErrorHandling();
if (PEAR::isError($pf)) {
$this->_valid = false;
$param = $saveparam;
return $pf;
}
$this->_packagefile = &$pf;
if (!$this->getGroup()) {
$this->setGroup('default'); // install the default dependency group
}
return $this->_valid = true;
}
}
$param = $saveparam;
return $this->_valid = false;
}
 
function _fromUrl($param, $saveparam = '')
{
if (!is_array($param) &&
(preg_match('#^(http|ftp)://#', $param))) {
$options = $this->_downloader->getOptions();
$this->_type = 'url';
$callback = $this->_downloader->ui ?
array(&$this->_downloader, '_downloadCallback') : null;
$this->_downloader->pushErrorHandling(PEAR_ERROR_RETURN);
if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) {
$this->_downloader->popErrorHandling();
return $dir;
}
$file = $this->_downloader->downloadHttp($param, $this->_downloader->ui,
$dir, $callback);
$this->_downloader->popErrorHandling();
if (PEAR::isError($file)) {
if (!empty($saveparam)) {
$saveparam = ", cannot download \"$saveparam\"";
}
$err = PEAR::raiseError('Could not download from "' . $param .
'"' . $saveparam . ' (' . $file->getMessage() . ')');
return $err;
}
if ($this->_rawpackagefile) {
require_once 'Archive/Tar.php';
$tar = &new Archive_Tar($file);
$packagexml = $tar->extractInString('package2.xml');
if (!$packagexml) {
$packagexml = $tar->extractInString('package.xml');
}
if (str_replace(array("\n", "\r"), array('',''), $packagexml) !=
str_replace(array("\n", "\r"), array('',''), $this->_rawpackagefile)) {
if ($this->getChannel() == 'pear.php.net') {
// be more lax for the existing PEAR packages that have not-ok
// characters in their package.xml
$this->_downloader->log(0, 'CRITICAL WARNING: The "' .
$this->getPackage() . '" package has invalid characters in its ' .
'package.xml. The next version of PEAR may not be able to install ' .
'this package for security reasons. Please open a bug report at ' .
'http://pear.php.net/package/' . $this->getPackage() . '/bugs');
} else {
return PEAR::raiseError('CRITICAL ERROR: package.xml downloaded does ' .
'not match value returned from xml-rpc');
}
}
}
// whew, download worked!
if (isset($options['downloadonly'])) {
$pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug);
} else {
if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) {
return $dir;
}
$pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug,
$dir);
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pf = &$pkg->fromAnyFile($file, PEAR_VALIDATE_INSTALLING);
PEAR::popErrorHandling();
if (PEAR::isError($pf)) {
if (is_array($pf->getUserInfo())) {
foreach ($pf->getUserInfo() as $err) {
if (is_array($err)) {
$err = $err['message'];
}
if (!isset($options['soft'])) {
$this->_downloader->log(0, "Validation Error: $err");
}
}
}
if (!isset($options['soft'])) {
$this->_downloader->log(0, $pf->getMessage());
}
$err = PEAR::raiseError('Download of "' . ($saveparam ? $saveparam :
$param) . '" succeeded, but it is not a valid package archive');
$this->_valid = false;
return $err;
}
$this->_packagefile = &$pf;
$this->setGroup('default'); // install the default dependency group
return $this->_valid = true;
}
return $this->_valid = false;
}
 
/**
*
* @param string|array pass in an array of format
* array(
* 'package' => 'pname',
* ['channel' => 'channame',]
* ['version' => 'version',]
* ['state' => 'state',])
* or a string of format [channame/]pname[-version|-state]
*/
function _fromString($param)
{
$options = $this->_downloader->getOptions();
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pname = $this->_registry->parsePackageName($param,
$this->_config->get('default_channel'));
PEAR::popErrorHandling();
if (PEAR::isError($pname)) {
if ($pname->getCode() == 'invalid') {
$this->_valid = false;
return false;
}
if ($pname->getCode() == 'channel') {
$parsed = $pname->getUserInfo();
if ($this->_downloader->discover($parsed['channel'])) {
if ($this->_config->get('auto_discover')) {
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pname = $this->_registry->parsePackageName($param,
$this->_config->get('default_channel'));
PEAR::popErrorHandling();
} else {
if (!isset($options['soft'])) {
$this->_downloader->log(0, 'Channel "' . $parsed['channel'] .
'" is not initialized, use ' .
'"pear channel-discover ' . $parsed['channel'] . '" to initialize' .
'or pear config-set auto_discover 1');
}
}
}
if (PEAR::isError($pname)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $pname->getMessage());
}
if (is_array($param)) {
$param = $this->_registry->parsedPackageNameToString($param);
}
$err = PEAR::raiseError('invalid package name/package file "' .
$param . '"');
$this->_valid = false;
return $err;
}
} else {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $pname->getMessage());
}
$err = PEAR::raiseError('invalid package name/package file "' .
$param . '"');
$this->_valid = false;
return $err;
}
}
if (!isset($this->_type)) {
$this->_type = 'xmlrpc';
}
$this->_parsedname = $pname;
if (isset($pname['state'])) {
$this->_explicitState = $pname['state'];
} else {
$this->_explicitState = false;
}
if (isset($pname['group'])) {
$this->_explicitGroup = true;
} else {
$this->_explicitGroup = false;
}
$info = $this->_downloader->_getPackageDownloadUrl($pname);
if (PEAR::isError($info)) {
if ($info->getCode() != -976 && $pname['channel'] == 'pear.php.net') {
// try pecl
$pname['channel'] = 'pecl.php.net';
if ($test = $this->_downloader->_getPackageDownloadUrl($pname)) {
if (!PEAR::isError($test)) {
$info = PEAR::raiseError($info->getMessage() . ' - package ' .
$this->_registry->parsedPackageNameToString($pname, true) .
' can be installed with "pecl install ' . $pname['package'] .
'"');
} else {
$pname['channel'] = 'pear.php.net';
}
} else {
$pname['channel'] = 'pear.php.net';
}
}
return $info;
}
$this->_rawpackagefile = $info['raw'];
$ret = $this->_analyzeDownloadURL($info, $param, $pname);
if (PEAR::isError($ret)) {
return $ret;
}
if ($ret) {
$this->_downloadURL = $ret;
return $this->_valid = (bool) $ret;
}
}
 
/**
* @param array output of package.getDownloadURL
* @param string|array|object information for detecting packages to be downloaded, and
* for errors
* @param array name information of the package
* @param array|null packages to be downloaded
* @param bool is this an optional dependency?
* @param bool is this any kind of dependency?
* @access private
*/
function _analyzeDownloadURL($info, $param, $pname, $params = null, $optional = false,
$isdependency = false)
{
if (!is_string($param) && PEAR_Downloader_Package::willDownload($param, $params)) {
return false;
}
if (!$info) {
if (!is_string($param)) {
$saveparam = ", cannot download \"$param\"";
} else {
$saveparam = '';
}
// no releases exist
return PEAR::raiseError('No releases for package "' .
$this->_registry->parsedPackageNameToString($pname, true) . '" exist' . $saveparam);
}
if (strtolower($info['info']->getChannel()) != strtolower($pname['channel'])) {
$err = false;
if ($pname['channel'] == 'pecl.php.net') {
if ($info['info']->getChannel() != 'pear.php.net') {
$err = true;
}
} elseif ($info['info']->getChannel() == 'pecl.php.net') {
if ($pname['channel'] != 'pear.php.net') {
$err = true;
}
} else {
$err = true;
}
if ($err) {
return PEAR::raiseError('SECURITY ERROR: package in channel "' . $pname['channel'] .
'" retrieved another channel\'s name for download! ("' .
$info['info']->getChannel() . '")');
}
}
if (!isset($info['url'])) {
if ($this->isInstalled($info)) {
if ($isdependency && version_compare($info['version'],
$this->_registry->packageInfo($info['info']->getPackage(),
'version', $info['info']->getChannel()), '<=')) {
// ignore bogus errors of "failed to download dependency"
// if it is already installed and the one that would be
// downloaded is older or the same version (Bug #7219)
return false;
}
}
$instead = ', will instead download version ' . $info['version'] .
', stability "' . $info['info']->getState() . '"';
// releases exist, but we failed to get any
if (isset($this->_downloader->_options['force'])) {
if (isset($pname['version'])) {
$vs = ', version "' . $pname['version'] . '"';
} elseif (isset($pname['state'])) {
$vs = ', stability "' . $pname['state'] . '"';
} elseif ($param == 'dependency') {
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
if (!in_array($info['info']->getState(),
PEAR_Common::betterStates($this->_config->get('preferred_state'), true))) {
if ($optional) {
// don't spit out confusing error message
return $this->_downloader->_getPackageDownloadUrl(
array('package' => $pname['package'],
'channel' => $pname['channel'],
'version' => $info['version']));
}
$vs = ' within preferred state "' . $this->_config->get('preferred_state') .
'"';
} else {
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
if ($optional) {
// don't spit out confusing error message
return $this->_downloader->_getPackageDownloadUrl(
array('package' => $pname['package'],
'channel' => $pname['channel'],
'version' => $info['version']));
}
$vs = PEAR_Dependency2::_getExtraString($pname);
$instead = '';
}
} else {
$vs = ' within preferred state "' . $this->_config->get(
'preferred_state') . '"';
}
if (!isset($options['soft'])) {
$this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] .
'/' . $pname['package'] . $vs . $instead);
}
// download the latest release
return $this->_downloader->_getPackageDownloadUrl(
array('package' => $pname['package'],
'channel' => $pname['channel'],
'version' => $info['version']));
} else {
// construct helpful error message
if (isset($pname['version'])) {
$vs = ', version "' . $pname['version'] . '"';
} elseif (isset($pname['state'])) {
$vs = ', stability "' . $pname['state'] . '"';
} elseif ($param == 'dependency') {
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
if (!in_array($info['info']->getState(),
PEAR_Common::betterStates($this->_config->get('preferred_state'), true))) {
if ($optional) {
// don't spit out confusing error message, and don't die on
// optional dep failure!
return $this->_downloader->_getPackageDownloadUrl(
array('package' => $pname['package'],
'channel' => $pname['channel'],
'version' => $info['version']));
}
$vs = ' within preferred state "' . $this->_config->get('preferred_state') .
'"';
} else {
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
if ($optional) {
// don't spit out confusing error message, and don't die on
// optional dep failure!
return $this->_downloader->_getPackageDownloadUrl(
array('package' => $pname['package'],
'channel' => $pname['channel'],
'version' => $info['version']));
}
$vs = PEAR_Dependency2::_getExtraString($pname);
}
} else {
$vs = ' within preferred state "' . $this->_downloader->config->get(
'preferred_state') . '"';
}
$options = $this->_downloader->getOptions();
// this is only set by the "download-all" command
if (isset($options['ignorepreferred_state'])) {
$err = PEAR::raiseError(
'Failed to download ' . $this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'], 'package' => $pname['package']),
true)
. $vs .
', latest release is version ' . $info['version'] .
', stability "' . $info['info']->getState() . '", use "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'], 'package' => $pname['package'],
'version' => $info['version'])) . '" to install',
PEAR_DOWNLOADER_PACKAGE_STATE);
return $err;
}
$err = PEAR::raiseError(
'Failed to download ' . $this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'], 'package' => $pname['package']),
true)
. $vs .
', latest release is version ' . $info['version'] .
', stability "' . $info['info']->getState() . '", use "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'], 'package' => $pname['package'],
'version' => $info['version'])) . '" to install');
return $err;
}
}
if (isset($info['deprecated']) && $info['deprecated']) {
$this->_downloader->log(0,
'WARNING: "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $info['info']->getChannel(),
'package' => $info['info']->getPackage()), true) .
'" is deprecated in favor of "' .
$this->_registry->parsedPackageNameToString($info['deprecated'], true) .
'"');
}
return $info;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/tests/pear_info.php
New file
0,0 → 1,38
<?php
/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Davey Shafik <davey@pixelated-dreams.com> |
// +----------------------------------------------------------------------+
//
// $Id: pear_info.php,v 1.5 2003/05/12 11:40:57 davey Exp $
 
/* May be required on slower (dial-up) connections
ini_set('default_socket_timeout',600);
ini_set('max_execution_time',600);
ini_set('max_input_time',600); */
 
// require the PEAR_Info file
require_once 'PEAR/Info.php';
 
// If you need to set a http_proxy uncomment the line below
// PEAR_Info::setProxy('your.proxy.here');
 
// Create PEAR_Info object
$info = new PEAR_Info();
 
// Display PEAR_Info output
$info->show();
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Task/Postinstallscript.php
New file
0,0 → 1,329
<?php
/**
* <tasks:postinstallscript>
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Postinstallscript.php,v 1.18 2006/02/08 01:21:47 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Base class
*/
require_once 'PEAR/Task/Common.php';
/**
* Implements the postinstallscript file task.
*
* Note that post-install scripts are handled separately from installation, by the
* "pear run-scripts" command
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Postinstallscript extends PEAR_Task_Common
{
var $type = 'script';
var $_class;
var $_params;
var $_obj;
/**
*
* @var PEAR_PackageFile_v2
*/
var $_pkg;
var $_contents;
var $phase = PEAR_TASK_INSTALL;
 
/**
* Validate the raw xml at parsing-time.
*
* This also attempts to validate the script to make sure it meets the criteria
* for a post-install script
* @param PEAR_PackageFile_v2
* @param array The XML contents of the <postinstallscript> tag
* @param PEAR_Config
* @param array the entire parsed <file> tag
* @static
*/
function validateXml($pkg, $xml, &$config, $fileXml)
{
if ($fileXml['role'] != 'php') {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" must be role="php"');
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$file = $pkg->getFileContents($fileXml['name']);
if (PEAR::isError($file)) {
PEAR::popErrorHandling();
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" is not valid: ' .
$file->getMessage());
} elseif ($file === null) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" could not be retrieved for processing!');
} else {
$analysis = $pkg->analyzeSourceCode($file, true);
if (!$analysis) {
PEAR::popErrorHandling();
$warnings = '';
foreach ($pkg->getValidationWarnings() as $warn) {
$warnings .= $warn['message'] . "\n";
}
return array(PEAR_TASK_ERROR_INVALID, 'Analysis of post-install script "' .
$fileXml['name'] . '" failed: ' . $warnings);
}
if (count($analysis['declared_classes']) != 1) {
PEAR::popErrorHandling();
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" must declare exactly 1 class');
}
$class = $analysis['declared_classes'][0];
if ($class != str_replace(array('/', '.php'), array('_', ''),
$fileXml['name']) . '_postinstall') {
PEAR::popErrorHandling();
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" class "' . $class . '" must be named "' .
str_replace(array('/', '.php'), array('_', ''),
$fileXml['name']) . '_postinstall"');
}
if (!isset($analysis['declared_methods'][$class])) {
PEAR::popErrorHandling();
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" must declare methods init() and run()');
}
$methods = array('init' => 0, 'run' => 1);
foreach ($analysis['declared_methods'][$class] as $method) {
if (isset($methods[$method])) {
unset($methods[$method]);
}
}
if (count($methods)) {
PEAR::popErrorHandling();
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" must declare methods init() and run()');
}
}
PEAR::popErrorHandling();
$definedparams = array();
$tasksNamespace = $pkg->getTasksNs() . ':';
if (!isset($xml[$tasksNamespace . 'paramgroup']) && isset($xml['paramgroup'])) {
// in order to support the older betas, which did not expect internal tags
// to also use the namespace
$tasksNamespace = '';
}
if (isset($xml[$tasksNamespace . 'paramgroup'])) {
$params = $xml[$tasksNamespace . 'paramgroup'];
if (!is_array($params) || !isset($params[0])) {
$params = array($params);
}
foreach ($params as $param) {
if (!isset($param[$tasksNamespace . 'id'])) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" <paramgroup> must have ' .
'an ' . $tasksNamespace . 'id> tag');
}
if (isset($param[$tasksNamespace . 'name'])) {
if (!in_array($param[$tasksNamespace . 'name'], $definedparams)) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" ' . $tasksNamespace .
'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
'" parameter "' . $param[$tasksNamespace . 'name'] .
'" has not been previously defined');
}
if (!isset($param[$tasksNamespace . 'conditiontype'])) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" ' . $tasksNamespace .
'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
'" must have a ' . $tasksNamespace .
'conditiontype> tag containing either "=", ' .
'"!=", or "preg_match"');
}
if (!in_array($param[$tasksNamespace . 'conditiontype'],
array('=', '!=', 'preg_match'))) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" ' . $tasksNamespace .
'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
'" must have a ' . $tasksNamespace .
'conditiontype> tag containing either "=", ' .
'"!=", or "preg_match"');
}
if (!isset($param[$tasksNamespace . 'value'])) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" ' . $tasksNamespace .
'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
'" must have a ' . $tasksNamespace .
'value> tag containing expected parameter value');
}
}
if (isset($param[$tasksNamespace . 'instructions'])) {
if (!is_string($param[$tasksNamespace . 'instructions'])) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" ' . $tasksNamespace .
'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
'" ' . $tasksNamespace . 'instructions> must be simple text');
}
}
if (!isset($param[$tasksNamespace . 'param'])) {
continue; // <param> is no longer required
}
$subparams = $param[$tasksNamespace . 'param'];
if (!is_array($subparams) || !isset($subparams[0])) {
$subparams = array($subparams);
}
foreach ($subparams as $subparam) {
if (!isset($subparam[$tasksNamespace . 'name'])) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" parameter for ' .
$tasksNamespace . 'paramgroup> id "' .
$param[$tasksNamespace . 'id'] . '" must have ' .
'a ' . $tasksNamespace . 'name> tag');
}
if (!preg_match('/[a-zA-Z0-9]+/',
$subparam[$tasksNamespace . 'name'])) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" parameter "' .
$subparam[$tasksNamespace . 'name'] .
'" for ' . $tasksNamespace . 'paramgroup> id "' .
$param[$tasksNamespace . 'id'] .
'" is not a valid name. Must contain only alphanumeric characters');
}
if (!isset($subparam[$tasksNamespace . 'prompt'])) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" parameter "' .
$subparam[$tasksNamespace . 'name'] .
'" for ' . $tasksNamespace . 'paramgroup> id "' .
$param[$tasksNamespace . 'id'] .
'" must have a ' . $tasksNamespace . 'prompt> tag');
}
if (!isset($subparam[$tasksNamespace . 'type'])) {
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
$fileXml['name'] . '" parameter "' .
$subparam[$tasksNamespace . 'name'] .
'" for ' . $tasksNamespace . 'paramgroup> id "' .
$param[$tasksNamespace . 'id'] .
'" must have a ' . $tasksNamespace . 'type> tag');
}
$definedparams[] = $param[$tasksNamespace . 'id'] . '::' .
$subparam[$tasksNamespace . 'name'];
}
}
}
return true;
}
 
/**
* Initialize a task instance with the parameters
* @param array raw, parsed xml
* @param array attributes from the <file> tag containing this task
* @param string|null last installed version of this package, if any (useful for upgrades)
*/
function init($xml, $fileattribs, $lastversion)
{
$this->_class = str_replace('/', '_', $fileattribs['name']);
$this->_filename = $fileattribs['name'];
$this->_class = str_replace ('.php', '', $this->_class) . '_postinstall';
$this->_params = $xml;
$this->_lastversion = $lastversion;
}
 
/**
* Strip the tasks: namespace from internal params
*
* @access private
*/
function _stripNamespace($params = null)
{
if ($params === null) {
$params = array();
if (!is_array($this->_params)) {
return;
}
foreach ($this->_params as $i => $param) {
if (is_array($param)) {
$param = $this->_stripNamespace($param);
}
$params[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param;
}
$this->_params = $params;
} else {
$newparams = array();
foreach ($params as $i => $param) {
if (is_array($param)) {
$param = $this->_stripNamespace($param);
}
$newparams[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param;
}
return $newparams;
}
}
 
/**
* Unlike other tasks, the installed file name is passed in instead of the file contents,
* because this task is handled post-installation
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param string file name
* @return bool|PEAR_Error false to skip this file, PEAR_Error to fail
* (use $this->throwError)
*/
function startSession($pkg, $contents)
{
if ($this->installphase != PEAR_TASK_INSTALL) {
return false;
}
// remove the tasks: namespace if present
$this->_pkg = $pkg;
$this->_stripNamespace();
$this->logger->log(0, 'Including external post-installation script "' .
$contents . '" - any errors are in this script');
include_once $contents;
if (class_exists($this->_class)) {
$this->logger->log(0, 'Inclusion succeeded');
} else {
return $this->throwError('init of post-install script class "' . $this->_class
. '" failed');
}
$this->_obj = new $this->_class;
$this->logger->log(1, 'running post-install script "' . $this->_class . '->init()"');
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$res = $this->_obj->init($this->config, $pkg, $this->_lastversion);
PEAR::popErrorHandling();
if ($res) {
$this->logger->log(0, 'init succeeded');
} else {
return $this->throwError('init of post-install script "' . $this->_class .
'->init()" failed');
}
$this->_contents = $contents;
return true;
}
 
/**
* No longer used
* @see PEAR_PackageFile_v2::runPostinstallScripts()
* @param array an array of tasks
* @param string install or upgrade
* @access protected
* @static
*/
function run()
{
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Task/Unixeol.php
New file
0,0 → 1,83
<?php
/**
* <tasks:unixeol>
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Unixeol.php,v 1.8 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Base class
*/
require_once 'PEAR/Task/Common.php';
/**
* Implements the unix line endings file task.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Unixeol extends PEAR_Task_Common
{
var $type = 'simple';
var $phase = PEAR_TASK_PACKAGE;
var $_replacements;
 
/**
* Validate the raw xml at parsing-time.
* @param PEAR_PackageFile_v2
* @param array raw, parsed xml
* @param PEAR_Config
* @static
*/
function validateXml($pkg, $xml, &$config, $fileXml)
{
if ($xml != '') {
return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed');
}
return true;
}
 
/**
* Initialize a task instance with the parameters
* @param array raw, parsed xml
* @param unused
*/
function init($xml, $attribs)
{
}
 
/**
* Replace all line endings with line endings customized for the current OS
*
* See validateXml() source for the complete list of allowed fields
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param string file contents
* @param string the eventual final file location (informational only)
* @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
* (use $this->throwError), otherwise return the new contents
*/
function startSession($pkg, $contents, $dest)
{
$this->logger->log(3, "replacing all line endings with \\n in $dest");
return preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Task/Windowseol/rw.php
New file
0,0 → 1,62
<?php
/**
* <tasks:windowseol> - read/write version
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: rw.php,v 1.4 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
*/
/**
* Base class
*/
require_once 'PEAR/Task/Windowseol.php';
/**
* Abstracts the windowseol task xml.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
*/
class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol
{
function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml)
{
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
function validate()
{
return true;
}
 
function getName()
{
return 'windowseol';
}
 
function getXml()
{
return '';
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Task/Replace/rw.php
New file
0,0 → 1,67
<?php
/**
* <tasks:replace> - read/write version
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: rw.php,v 1.3 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
*/
/**
* Base class
*/
require_once 'PEAR/Task/Replace.php';
/**
* Abstracts the replace task xml.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
*/
class PEAR_Task_Replace_rw extends PEAR_Task_Replace
{
function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml)
{
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
function validate()
{
return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
}
 
function setInfo($from, $to, $type)
{
$this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type));
}
 
function getName()
{
return 'replace';
}
 
function getXml()
{
return $this->_params;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Task/Common.php
New file
0,0 → 1,208
<?php
/**
* PEAR_Task_Common, base class for installer tasks
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Common.php,v 1.16 2006/11/12 05:02:41 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**#@+
* Error codes for task validation routines
*/
define('PEAR_TASK_ERROR_NOATTRIBS', 1);
define('PEAR_TASK_ERROR_MISSING_ATTRIB', 2);
define('PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE', 3);
define('PEAR_TASK_ERROR_INVALID', 4);
/**#@-*/
define('PEAR_TASK_PACKAGE', 1);
define('PEAR_TASK_INSTALL', 2);
define('PEAR_TASK_PACKAGEANDINSTALL', 3);
/**
* A task is an operation that manipulates the contents of a file.
*
* Simple tasks operate on 1 file. Multiple tasks are executed after all files have been
* processed and installed, and are designed to operate on all files containing the task.
* The Post-install script task simply takes advantage of the fact that it will be run
* after installation, replace is a simple task.
*
* Combining tasks is possible, but ordering is significant.
*
* <file name="test.php" role="php">
* <tasks:replace from="@data-dir@" to="data_dir" type="pear-config"/>
* <tasks:postinstallscript/>
* </file>
*
* This will first replace any instance of @data-dir@ in the test.php file
* with the path to the current data directory. Then, it will include the
* test.php file and run the script it contains to configure the package post-installation.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @abstract
*/
class PEAR_Task_Common
{
/**
* Valid types for this version are 'simple' and 'multiple'
*
* - simple tasks operate on the contents of a file and write out changes to disk
* - multiple tasks operate on the contents of many files and write out the
* changes directly to disk
*
* Child task classes must override this property.
* @access protected
*/
var $type = 'simple';
/**
* Determines which install phase this task is executed under
*/
var $phase = PEAR_TASK_INSTALL;
/**
* @access protected
*/
var $config;
/**
* @access protected
*/
var $registry;
/**
* @access protected
*/
var $logger;
/**
* @access protected
*/
var $installphase;
/**
* @param PEAR_Config
* @param PEAR_Common
*/
function PEAR_Task_Common(&$config, &$logger, $phase)
{
$this->config = &$config;
$this->registry = &$config->getRegistry();
$this->logger = &$logger;
$this->installphase = $phase;
if ($this->type == 'multiple') {
$GLOBALS['_PEAR_TASK_POSTINSTANCES'][get_class($this)][] = &$this;
}
}
 
/**
* Validate the basic contents of a task tag.
* @param PEAR_PackageFile_v2
* @param array
* @param PEAR_Config
* @param array the entire parsed <file> tag
* @return true|array On error, return an array in format:
* array(PEAR_TASK_ERROR_???[, param1][, param2][, ...])
*
* For PEAR_TASK_ERROR_MISSING_ATTRIB, pass the attribute name in
* For PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, pass the attribute name and an array
* of legal values in
* @static
* @abstract
*/
function validateXml($pkg, $xml, &$config, $fileXml)
{
}
 
/**
* Initialize a task instance with the parameters
* @param array raw, parsed xml
* @param array attributes from the <file> tag containing this task
* @param string|null last installed version of this package
* @abstract
*/
function init($xml, $fileAttributes, $lastVersion)
{
}
 
/**
* Begin a task processing session. All multiple tasks will be processed after each file
* has been successfully installed, all simple tasks should perform their task here and
* return any errors using the custom throwError() method to allow forward compatibility
*
* This method MUST NOT write out any changes to disk
* @param PEAR_PackageFile_v2
* @param string file contents
* @param string the eventual final file location (informational only)
* @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
* (use $this->throwError), otherwise return the new contents
* @abstract
*/
function startSession($pkg, $contents, $dest)
{
}
 
/**
* This method is used to process each of the tasks for a particular multiple class
* type. Simple tasks need not implement this method.
* @param array an array of tasks
* @access protected
* @static
* @abstract
*/
function run($tasks)
{
}
 
/**
* @static
* @final
*/
function hasPostinstallTasks()
{
return isset($GLOBALS['_PEAR_TASK_POSTINSTANCES']);
}
 
/**
* @static
* @final
*/
function runPostinstallTasks()
{
foreach ($GLOBALS['_PEAR_TASK_POSTINSTANCES'] as $class => $tasks) {
$err = call_user_func(array($class, 'run'),
$GLOBALS['_PEAR_TASK_POSTINSTANCES'][$class]);
if ($err) {
return PEAR_Task_Common::throwError($err);
}
}
unset($GLOBALS['_PEAR_TASK_POSTINSTANCES']);
}
 
/**
* Determines whether a role is a script
* @return bool
*/
function isScript()
{
return $this->type == 'script';
}
 
function throwError($msg, $code = -1)
{
include_once 'PEAR.php';
return PEAR::raiseError($msg, $code);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Task/Windowseol.php
New file
0,0 → 1,83
<?php
/**
* <tasks:windowseol>
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Windowseol.php,v 1.7 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Base class
*/
require_once 'PEAR/Task/Common.php';
/**
* Implements the windows line endsings file task.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Windowseol extends PEAR_Task_Common
{
var $type = 'simple';
var $phase = PEAR_TASK_PACKAGE;
var $_replacements;
 
/**
* Validate the raw xml at parsing-time.
* @param PEAR_PackageFile_v2
* @param array raw, parsed xml
* @param PEAR_Config
* @static
*/
function validateXml($pkg, $xml, &$config, $fileXml)
{
if ($xml != '') {
return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed');
}
return true;
}
 
/**
* Initialize a task instance with the parameters
* @param array raw, parsed xml
* @param unused
*/
function init($xml, $attribs)
{
}
 
/**
* Replace all line endings with windows line endings
*
* See validateXml() source for the complete list of allowed fields
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param string file contents
* @param string the eventual final file location (informational only)
* @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
* (use $this->throwError), otherwise return the new contents
*/
function startSession($pkg, $contents, $dest)
{
$this->logger->log(3, "replacing all line endings with \\r\\n in $dest");
return preg_replace("/\r\n|\n\r|\r|\n/", "\r\n", $contents);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Task/Postinstallscript/rw.php
New file
0,0 → 1,176
<?php
/**
* <tasks:postinstallscript> - read/write version
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: rw.php,v 1.11 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
*/
/**
* Base class
*/
require_once 'PEAR/Task/Postinstallscript.php';
/**
* Abstracts the postinstallscript file task xml.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
*/
class PEAR_Task_Postinstallscript_rw extends PEAR_Task_Postinstallscript
{
/**
* parent package file object
*
* @var PEAR_PackageFile_v2_rw
*/
var $_pkg;
/**
* Enter description here...
*
* @param PEAR_PackageFile_v2_rw $pkg
* @param PEAR_Config $config
* @param PEAR_Frontend $logger
* @param array $fileXml
* @return PEAR_Task_Postinstallscript_rw
*/
function PEAR_Task_Postinstallscript_rw(&$pkg, &$config, &$logger, $fileXml)
{
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
function validate()
{
return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
}
 
function getName()
{
return 'postinstallscript';
}
 
/**
* add a simple <paramgroup> to the post-install script
*
* Order is significant, so call this method in the same
* sequence the users should see the paramgroups. The $params
* parameter should either be the result of a call to {@link getParam()}
* or an array of calls to getParam().
*
* Use {@link addConditionTypeGroup()} to add a <paramgroup> containing
* a <conditiontype> tag
* @param string $id <paramgroup> id as seen by the script
* @param array|false $params array of getParam() calls, or false for no params
* @param string|false $instructions
*/
function addParamGroup($id, $params = false, $instructions = false)
{
if ($params && isset($params[0]) && !isset($params[1])) {
$params = $params[0];
}
$stuff =
array(
$this->_pkg->getTasksNs() . ':id' => $id,
);
if ($instructions) {
$stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions;
}
if ($params) {
$stuff[$this->_pkg->getTasksNs() . ':param'] = $params;
}
$this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff;
}
 
/**
* add a complex <paramgroup> to the post-install script with conditions
*
* This inserts a <paramgroup> with
*
* Order is significant, so call this method in the same
* sequence the users should see the paramgroups. The $params
* parameter should either be the result of a call to {@link getParam()}
* or an array of calls to getParam().
*
* Use {@link addParamGroup()} to add a simple <paramgroup>
*
* @param string $id <paramgroup> id as seen by the script
* @param string $oldgroup <paramgroup> id of the section referenced by
* <conditiontype>
* @param string $param name of the <param> from the older section referenced
* by <contitiontype>
* @param string $value value to match of the parameter
* @param string $conditiontype one of '=', '!=', 'preg_match'
* @param array|false $params array of getParam() calls, or false for no params
* @param string|false $instructions
*/
function addConditionTypeGroup($id, $oldgroup, $param, $value, $conditiontype = '=',
$params = false, $instructions = false)
{
if ($params && isset($params[0]) && !isset($params[1])) {
$params = $params[0];
}
$stuff =
array(
$this->_pkg->getTasksNs() . ':id' => $id,
);
if ($instructions) {
$stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions;
}
$stuff[$this->_pkg->getTasksNs() . ':name'] = $oldgroup . '::' . $param;
$stuff[$this->_pkg->getTasksNs() . ':conditiontype'] = $conditiontype;
$stuff[$this->_pkg->getTasksNs() . ':value'] = $value;
if ($params) {
$stuff[$this->_pkg->getTasksNs() . ':param'] = $params;
}
$this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff;
}
 
function getXml()
{
return $this->_params;
}
 
/**
* Use to set up a param tag for use in creating a paramgroup
* @static
*/
function getParam($name, $prompt, $type = 'string', $default = null)
{
if ($default !== null) {
return
array(
$this->_pkg->getTasksNs() . ':name' => $name,
$this->_pkg->getTasksNs() . ':prompt' => $prompt,
$this->_pkg->getTasksNs() . ':type' => $type,
$this->_pkg->getTasksNs() . ':default' => $default
);
}
return
array(
$this->_pkg->getTasksNs() . ':name' => $name,
$this->_pkg->getTasksNs() . ':prompt' => $prompt,
$this->_pkg->getTasksNs() . ':type' => $type,
);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Task/Replace.php
New file
0,0 → 1,182
<?php
/**
* <tasks:replace>
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Replace.php,v 1.15 2006/03/02 18:14:13 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Base class
*/
require_once 'PEAR/Task/Common.php';
/**
* Implements the replace file task.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Replace extends PEAR_Task_Common
{
var $type = 'simple';
var $phase = PEAR_TASK_PACKAGEANDINSTALL;
var $_replacements;
 
/**
* Validate the raw xml at parsing-time.
* @param PEAR_PackageFile_v2
* @param array raw, parsed xml
* @param PEAR_Config
* @static
*/
function validateXml($pkg, $xml, &$config, $fileXml)
{
if (!isset($xml['attribs'])) {
return array(PEAR_TASK_ERROR_NOATTRIBS);
}
if (!isset($xml['attribs']['type'])) {
return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'type');
}
if (!isset($xml['attribs']['to'])) {
return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'to');
}
if (!isset($xml['attribs']['from'])) {
return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'from');
}
if ($xml['attribs']['type'] == 'pear-config') {
if (!in_array($xml['attribs']['to'], $config->getKeys())) {
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
$config->getKeys());
}
} elseif ($xml['attribs']['type'] == 'php-const') {
if (defined($xml['attribs']['to'])) {
return true;
} else {
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
array('valid PHP constant'));
}
} elseif ($xml['attribs']['type'] == 'package-info') {
if (in_array($xml['attribs']['to'],
array('name', 'summary', 'channel', 'notes', 'extends', 'description',
'release_notes', 'license', 'release-license', 'license-uri',
'version', 'api-version', 'state', 'api-state', 'release_date',
'date', 'time'))) {
return true;
} else {
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
array('name', 'summary', 'channel', 'notes', 'extends', 'description',
'release_notes', 'license', 'release-license', 'license-uri',
'version', 'api-version', 'state', 'api-state', 'release_date',
'date', 'time'));
}
} else {
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'type', $xml['attribs']['type'],
array('pear-config', 'package-info', 'php-const'));
}
return true;
}
 
/**
* Initialize a task instance with the parameters
* @param array raw, parsed xml
* @param unused
*/
function init($xml, $attribs)
{
$this->_replacements = isset($xml['attribs']) ? array($xml) : $xml;
}
 
/**
* Do a package.xml 1.0 replacement, with additional package-info fields available
*
* See validateXml() source for the complete list of allowed fields
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param string file contents
* @param string the eventual final file location (informational only)
* @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
* (use $this->throwError), otherwise return the new contents
*/
function startSession($pkg, $contents, $dest)
{
$subst_from = $subst_to = array();
foreach ($this->_replacements as $a) {
$a = $a['attribs'];
$to = '';
if ($a['type'] == 'pear-config') {
if ($this->installphase == PEAR_TASK_PACKAGE) {
return false;
}
if ($a['to'] == 'master_server') {
$chan = $this->registry->getChannel($pkg->getChannel());
if (!PEAR::isError($chan)) {
$to = $chan->getServer();
} else {
$this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]");
return false;
}
} else {
if ($this->config->isDefinedLayer('ftp')) {
// try the remote config file first
$to = $this->config->get($a['to'], 'ftp', $pkg->getChannel());
if (is_null($to)) {
// then default to local
$to = $this->config->get($a['to'], null, $pkg->getChannel());
}
} else {
$to = $this->config->get($a['to'], null, $pkg->getChannel());
}
}
if (is_null($to)) {
$this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]");
return false;
}
} elseif ($a['type'] == 'php-const') {
if ($this->installphase == PEAR_TASK_PACKAGE) {
return false;
}
if (defined($a['to'])) {
$to = constant($a['to']);
} else {
$this->logger->log(0, "$dest: invalid php-const replacement: $a[to]");
return false;
}
} else {
if ($t = $pkg->packageInfo($a['to'])) {
$to = $t;
} else {
$this->logger->log(0, "$dest: invalid package-info replacement: $a[to]");
return false;
}
}
if (!is_null($to)) {
$subst_from[] = $a['from'];
$subst_to[] = $to;
}
}
$this->logger->log(3, "doing " . sizeof($subst_from) .
" substitution(s) for $dest");
if (sizeof($subst_from)) {
$contents = str_replace($subst_from, $subst_to, $contents);
}
return $contents;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Task/Unixeol/rw.php
New file
0,0 → 1,62
<?php
/**
* <tasks:unixeol> - read/write version
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: rw.php,v 1.4 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
*/
/**
* Base class
*/
require_once 'PEAR/Task/Unixeol.php';
/**
* Abstracts the unixeol task xml.
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
*/
class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol
{
function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml)
{
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
function validate()
{
return true;
}
 
function getName()
{
return 'unixeol';
}
 
function getXml()
{
return '';
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/XMLParser.php
New file
0,0 → 1,261
<?php
/**
* PEAR_FTP
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Stephan Schmidt (original XML_Unserializer code)
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: XMLParser.php,v 1.12 2006/03/27 04:39:03 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* Parser for any xml file
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Stephan Schmidt (original XML_Unserializer code)
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_XMLParser
{
/**
* unserilialized data
* @var string $_serializedData
*/
var $_unserializedData = null;
 
/**
* name of the root tag
* @var string $_root
*/
var $_root = null;
 
/**
* stack for all data that is found
* @var array $_dataStack
*/
var $_dataStack = array();
 
/**
* stack for all values that are generated
* @var array $_valStack
*/
var $_valStack = array();
 
/**
* current tag depth
* @var int $_depth
*/
var $_depth = 0;
 
/**
* @return array
*/
function getData()
{
return $this->_unserializedData;
}
 
/**
* @param string xml content
* @return true|PEAR_Error
*/
function parse($data)
{
if (!extension_loaded('xml')) {
include_once 'PEAR.php';
return PEAR::raiseError("XML Extension not found", 1);
}
$this->_valStack = array();
$this->_dataStack = array();
$this->_depth = 0;
 
if (version_compare(phpversion(), '5.0.0', 'lt')) {
if (strpos($data, 'encoding="UTF-8"')) {
$data = utf8_decode($data);
}
$xp = xml_parser_create('ISO-8859-1');
} else {
if (strpos($data, 'encoding="UTF-8"')) {
$xp = xml_parser_create('UTF-8');
} else {
$xp = xml_parser_create('ISO-8859-1');
}
}
xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, 0);
xml_set_object($xp, $this);
xml_set_element_handler($xp, 'startHandler', 'endHandler');
xml_set_character_data_handler($xp, 'cdataHandler');
if (!xml_parse($xp, $data)) {
$msg = xml_error_string(xml_get_error_code($xp));
$line = xml_get_current_line_number($xp);
xml_parser_free($xp);
include_once 'PEAR.php';
return PEAR::raiseError("XML Error: '$msg' on line '$line'", 2);
}
xml_parser_free($xp);
return true;
}
 
/**
* Start element handler for XML parser
*
* @access private
* @param object $parser XML parser object
* @param string $element XML element
* @param array $attribs attributes of XML tag
* @return void
*/
function startHandler($parser, $element, $attribs)
{
$type = 'string';
 
$this->_depth++;
$this->_dataStack[$this->_depth] = null;
 
$val = array(
'name' => $element,
'value' => null,
'type' => $type,
'childrenKeys' => array(),
'aggregKeys' => array()
);
 
if (count($attribs) > 0) {
$val['children'] = array();
$val['type'] = 'array';
 
$val['children']['attribs'] = $attribs;
 
}
 
array_push($this->_valStack, $val);
}
 
/**
* post-process data
*
* @param string $data
* @param string $element element name
*/
function postProcess($data, $element)
{
return trim($data);
}
 
/**
* End element handler for XML parser
*
* @access private
* @param object XML parser object
* @param string
* @return void
*/
function endHandler($parser, $element)
{
$value = array_pop($this->_valStack);
$data = $this->postProcess($this->_dataStack[$this->_depth], $element);
 
// adjust type of the value
switch(strtolower($value['type'])) {
 
/*
* unserialize an array
*/
case 'array':
if ($data !== '') {
$value['children']['_content'] = $data;
}
if (isset($value['children'])) {
$value['value'] = $value['children'];
} else {
$value['value'] = array();
}
break;
 
/*
* unserialize a null value
*/
case 'null':
$data = null;
break;
 
/*
* unserialize any scalar value
*/
default:
settype($data, $value['type']);
$value['value'] = $data;
break;
}
$parent = array_pop($this->_valStack);
if ($parent === null) {
$this->_unserializedData = &$value['value'];
$this->_root = &$value['name'];
return true;
} else {
// parent has to be an array
if (!isset($parent['children']) || !is_array($parent['children'])) {
$parent['children'] = array();
if ($parent['type'] != 'array') {
$parent['type'] = 'array';
}
}
 
if (!empty($value['name'])) {
// there already has been a tag with this name
if (in_array($value['name'], $parent['childrenKeys'])) {
// no aggregate has been created for this tag
if (!in_array($value['name'], $parent['aggregKeys'])) {
if (isset($parent['children'][$value['name']])) {
$parent['children'][$value['name']] = array($parent['children'][$value['name']]);
} else {
$parent['children'][$value['name']] = array();
}
array_push($parent['aggregKeys'], $value['name']);
}
array_push($parent['children'][$value['name']], $value['value']);
} else {
$parent['children'][$value['name']] = &$value['value'];
array_push($parent['childrenKeys'], $value['name']);
}
} else {
array_push($parent['children'],$value['value']);
}
array_push($this->_valStack, $parent);
}
 
$this->_depth--;
}
 
/**
* Handler for character data
*
* @access private
* @param object XML parser object
* @param string CDATA
* @return void
*/
function cdataHandler($parser, $cdata)
{
$this->_dataStack[$this->_depth] .= $cdata;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Packager.php
New file
0,0 → 1,199
<?php
/**
* PEAR_Packager for generating releases
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Packager.php,v 1.70 2006/09/25 05:12:21 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR/Common.php';
require_once 'PEAR/PackageFile.php';
require_once 'System.php';
 
/**
* Administration class used to make a PEAR release tarball.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Packager extends PEAR_Common
{
/**
* @var PEAR_Registry
*/
var $_registry;
// {{{ package()
 
function package($pkgfile = null, $compress = true, $pkg2 = null)
{
// {{{ validate supplied package.xml file
if (empty($pkgfile)) {
$pkgfile = 'package.xml';
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pkg = &new PEAR_PackageFile($this->config, $this->debug);
$pf = &$pkg->fromPackageFile($pkgfile, PEAR_VALIDATE_NORMAL);
$main = &$pf;
PEAR::staticPopErrorHandling();
if (PEAR::isError($pf)) {
if (is_array($pf->getUserInfo())) {
foreach ($pf->getUserInfo() as $error) {
$this->log(0, 'Error: ' . $error['message']);
}
}
$this->log(0, $pf->getMessage());
return $this->raiseError("Cannot package, errors in package file");
} else {
foreach ($pf->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
}
 
// }}}
if ($pkg2) {
$this->log(0, 'Attempting to process the second package file');
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pf2 = &$pkg->fromPackageFile($pkg2, PEAR_VALIDATE_NORMAL);
PEAR::staticPopErrorHandling();
if (PEAR::isError($pf2)) {
if (is_array($pf2->getUserInfo())) {
foreach ($pf2->getUserInfo() as $error) {
$this->log(0, 'Error: ' . $error['message']);
}
}
$this->log(0, $pf2->getMessage());
return $this->raiseError("Cannot package, errors in second package file");
} else {
foreach ($pf2->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
}
if ($pf2->getPackagexmlVersion() == '2.0' ||
$pf2->getPackagexmlVersion() == '2.1') {
$main = &$pf2;
$other = &$pf;
} else {
$main = &$pf;
$other = &$pf2;
}
if ($main->getPackagexmlVersion() != '2.0' &&
$main->getPackagexmlVersion() != '2.1') {
return PEAR::raiseError('Error: cannot package two package.xml version 1.0, can ' .
'only package together a package.xml 1.0 and package.xml 2.0');
}
if ($other->getPackagexmlVersion() != '1.0') {
return PEAR::raiseError('Error: cannot package two package.xml version 2.0, can ' .
'only package together a package.xml 1.0 and package.xml 2.0');
}
}
$main->setLogger($this);
if (!$main->validate(PEAR_VALIDATE_PACKAGING)) {
foreach ($main->getValidationWarnings() as $warning) {
$this->log(0, 'Error: ' . $warning['message']);
}
return $this->raiseError("Cannot package, errors in package");
} else {
foreach ($main->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
}
if ($pkg2) {
$other->setLogger($this);
$a = false;
if (!$other->validate(PEAR_VALIDATE_NORMAL) || $a = !$main->isEquivalent($other)) {
foreach ($other->getValidationWarnings() as $warning) {
$this->log(0, 'Error: ' . $warning['message']);
}
foreach ($main->getValidationWarnings() as $warning) {
$this->log(0, 'Error: ' . $warning['message']);
}
if ($a) {
return $this->raiseError('The two package.xml files are not equivalent!');
}
return $this->raiseError("Cannot package, errors in package");
} else {
foreach ($other->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
}
$gen = &$main->getDefaultGenerator();
$tgzfile = $gen->toTgz2($this, $other, $compress);
if (PEAR::isError($tgzfile)) {
return $tgzfile;
}
$dest_package = basename($tgzfile);
$pkgdir = dirname($pkgfile);
// TAR the Package -------------------------------------------
$this->log(1, "Package $dest_package done");
if (file_exists("$pkgdir/CVS/Root")) {
$cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion());
$cvstag = "RELEASE_$cvsversion";
$this->log(1, 'Tag the released code with "pear cvstag ' .
$main->getPackageFile() . '"');
$this->log(1, "(or set the CVS tag $cvstag by hand)");
}
} else { // this branch is executed for single packagefile packaging
$gen = &$pf->getDefaultGenerator();
$tgzfile = $gen->toTgz($this, $compress);
if (PEAR::isError($tgzfile)) {
$this->log(0, $tgzfile->getMessage());
return $this->raiseError("Cannot package, errors in package");
}
$dest_package = basename($tgzfile);
$pkgdir = dirname($pkgfile);
// TAR the Package -------------------------------------------
$this->log(1, "Package $dest_package done");
if (file_exists("$pkgdir/CVS/Root")) {
$cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion());
$cvstag = "RELEASE_$cvsversion";
$this->log(1, "Tag the released code with `pear cvstag $pkgfile'");
$this->log(1, "(or set the CVS tag $cvstag by hand)");
}
}
return $dest_package;
}
 
// }}}
}
 
// {{{ md5_file() utility function
if (!function_exists('md5_file')) {
function md5_file($file) {
if (!$fd = @fopen($file, 'r')) {
return false;
}
fclose($fd);
$md5 = md5(file_get_contents($file));
return $md5;
}
}
// }}}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Dependency.php
New file
0,0 → 1,495
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 5 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2004 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 3.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available through the world-wide-web at the following url: |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Tomas V.V.Cox <cox@idecnet.com> |
// | Stig Bakken <ssb@php.net> |
// +----------------------------------------------------------------------+
//
// THIS FILE IS DEPRECATED IN FAVOR OF DEPENDENCY2.PHP, AND IS NOT USED IN THE INSTALLER
// $Id: Dependency.php,v 1.42 2006/03/26 23:25:56 cellog Exp $
 
require_once "PEAR.php";
require_once "OS/Guess.php";
 
define('PEAR_DEPENDENCY_MISSING', -1);
define('PEAR_DEPENDENCY_CONFLICT', -2);
define('PEAR_DEPENDENCY_UPGRADE_MINOR', -3);
define('PEAR_DEPENDENCY_UPGRADE_MAJOR', -4);
define('PEAR_DEPENDENCY_BAD_DEPENDENCY', -5);
define('PEAR_DEPENDENCY_MISSING_OPTIONAL', -6);
define('PEAR_DEPENDENCY_CONFLICT_OPTIONAL', -7);
define('PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL', -8);
define('PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL', -9);
 
/**
* Dependency check for PEAR packages
*
* The class is based on the dependency RFC that can be found at
* http://cvs.php.net/cvs.php/pearweb/rfc. It requires PHP >= 4.1
*
* @author Tomas V.V.Vox <cox@idecnet.com>
* @author Stig Bakken <ssb@php.net>
*/
class PEAR_Dependency
{
// {{{ constructor
/**
* Constructor
*
* @access public
* @param object Registry object
* @return void
*/
function PEAR_Dependency(&$registry)
{
$this->registry = &$registry;
}
 
// }}}
// {{{ callCheckMethod()
 
/**
* This method maps the XML dependency definition to the
* corresponding one from PEAR_Dependency
*
* <pre>
* $opts => Array
* (
* [type] => pkg
* [rel] => ge
* [version] => 3.4
* [name] => HTML_Common
* [optional] => false
* )
* </pre>
*
* @param string Error message
* @param array Options
* @return boolean
*/
function callCheckMethod(&$errmsg, $opts)
{
$rel = isset($opts['rel']) ? $opts['rel'] : 'has';
$req = isset($opts['version']) ? $opts['version'] : null;
$name = isset($opts['name']) ? $opts['name'] : null;
$channel = isset($opts['channel']) ? $opts['channel'] : 'pear.php.net';
$opt = (isset($opts['optional']) && $opts['optional'] == 'yes') ?
$opts['optional'] : null;
$errmsg = '';
switch ($opts['type']) {
case 'pkg':
return $this->checkPackage($errmsg, $name, $req, $rel, $opt, $channel);
break;
case 'ext':
return $this->checkExtension($errmsg, $name, $req, $rel, $opt);
break;
case 'php':
return $this->checkPHP($errmsg, $req, $rel);
break;
case 'prog':
return $this->checkProgram($errmsg, $name);
break;
case 'os':
return $this->checkOS($errmsg, $name);
break;
case 'sapi':
return $this->checkSAPI($errmsg, $name);
break;
case 'zend':
return $this->checkZend($errmsg, $name);
break;
default:
return "'{$opts['type']}' dependency type not supported";
}
}
 
// }}}
// {{{ checkPackage()
 
/**
* Package dependencies check method
*
* @param string $errmsg Empty string, it will be populated with an error message, if any
* @param string $name Name of the package to test
* @param string $req The package version required
* @param string $relation How to compare versions with each other
* @param bool $opt Whether the relationship is optional
* @param string $channel Channel name
*
* @return mixed bool false if no error or the error string
*/
function checkPackage(&$errmsg, $name, $req = null, $relation = 'has',
$opt = false, $channel = 'pear.php.net')
{
if (is_string($req) && substr($req, 0, 2) == 'v.') {
$req = substr($req, 2);
}
switch ($relation) {
case 'has':
if (!$this->registry->packageExists($name, $channel)) {
if ($opt) {
$errmsg = "package `$channel/$name' is recommended to utilize some features.";
return PEAR_DEPENDENCY_MISSING_OPTIONAL;
}
$errmsg = "requires package `$channel/$name'";
return PEAR_DEPENDENCY_MISSING;
}
return false;
case 'not':
if ($this->registry->packageExists($name, $channel)) {
$errmsg = "conflicts with package `$channel/$name'";
return PEAR_DEPENDENCY_CONFLICT;
}
return false;
case 'lt':
case 'le':
case 'eq':
case 'ne':
case 'ge':
case 'gt':
$version = $this->registry->packageInfo($name, 'version', $channel);
if (!$this->registry->packageExists($name, $channel)
|| !version_compare("$version", "$req", $relation))
{
$code = $this->codeFromRelation($relation, $version, $req, $opt);
if ($opt) {
$errmsg = "package `$channel/$name' version " . $this->signOperator($relation) .
" $req is recommended to utilize some features.";
if ($version) {
$errmsg .= " Installed version is $version";
}
return $code;
}
$errmsg = "requires package `$channel/$name' " .
$this->signOperator($relation) . " $req";
return $code;
}
return false;
}
$errmsg = "relation '$relation' with requirement '$req' is not supported (name=$channel/$name)";
return PEAR_DEPENDENCY_BAD_DEPENDENCY;
}
 
// }}}
// {{{ checkPackageUninstall()
 
/**
* Check package dependencies on uninstall
*
* @param string $error The resultant error string
* @param string $warning The resultant warning string
* @param string $name Name of the package to test
* @param string $channel Channel name of the package
*
* @return bool true if there were errors
*/
function checkPackageUninstall(&$error, &$warning, $package, $channel = 'pear.php.net')
{
$channel = strtolower($channel);
$error = null;
$channels = $this->registry->listAllPackages();
foreach ($channels as $channelname => $packages) {
foreach ($packages as $pkg) {
if ($pkg == $package && $channel == $channelname) {
continue;
}
$deps = $this->registry->packageInfo($pkg, 'release_deps', $channel);
if (empty($deps)) {
continue;
}
foreach ($deps as $dep) {
$depchannel = isset($dep['channel']) ? $dep['channel'] : 'pear.php.net';
if ($dep['type'] == 'pkg' && (strcasecmp($dep['name'], $package) == 0) &&
($depchannel == $channel)) {
if ($dep['rel'] == 'ne') {
continue;
}
if (isset($dep['optional']) && $dep['optional'] == 'yes') {
$warning .= "\nWarning: Package '$depchannel/$pkg' optionally depends on '$channel:/package'";
} else {
$error .= "Package '$depchannel/$pkg' depends on '$channel/$package'\n";
}
}
}
}
}
return ($error) ? true : false;
}
 
// }}}
// {{{ checkExtension()
 
/**
* Extension dependencies check method
*
* @param string $name Name of the extension to test
* @param string $req_ext_ver Required extension version to compare with
* @param string $relation How to compare versions with eachother
* @param bool $opt Whether the relationship is optional
*
* @return mixed bool false if no error or the error string
*/
function checkExtension(&$errmsg, $name, $req = null, $relation = 'has',
$opt = false)
{
if ($relation == 'not') {
if (extension_loaded($name)) {
$errmsg = "conflicts with PHP extension '$name'";
return PEAR_DEPENDENCY_CONFLICT;
} else {
return false;
}
}
 
if (!extension_loaded($name)) {
if ($relation == 'ne') {
return false;
}
if ($opt) {
$errmsg = "'$name' PHP extension is recommended to utilize some features";
return PEAR_DEPENDENCY_MISSING_OPTIONAL;
}
$errmsg = "'$name' PHP extension is not installed";
return PEAR_DEPENDENCY_MISSING;
}
if ($relation == 'has') {
return false;
}
$code = false;
if (is_string($req) && substr($req, 0, 2) == 'v.') {
$req = substr($req, 2);
}
$ext_ver = phpversion($name);
$operator = $relation;
// Force params to be strings, otherwise the comparation will fail (ex. 0.9==0.90)
if (!version_compare("$ext_ver", "$req", $operator)) {
$errmsg = "'$name' PHP extension version " .
$this->signOperator($operator) . " $req is required";
$code = $this->codeFromRelation($relation, $ext_ver, $req, $opt);
if ($opt) {
$errmsg = "'$name' PHP extension version " . $this->signOperator($operator) .
" $req is recommended to utilize some features";
return $code;
}
}
return $code;
}
 
// }}}
// {{{ checkOS()
 
/**
* Operating system dependencies check method
*
* @param string $os Name of the operating system
*
* @return mixed bool false if no error or the error string
*/
function checkOS(&$errmsg, $os)
{
// XXX Fixme: Implement a more flexible way, like
// comma separated values or something similar to PEAR_OS
static $myos;
if (empty($myos)) {
$myos = new OS_Guess();
}
// only 'has' relation is currently supported
if ($myos->matchSignature($os)) {
return false;
}
$errmsg = "'$os' operating system not supported";
return PEAR_DEPENDENCY_CONFLICT;
}
 
// }}}
// {{{ checkPHP()
 
/**
* PHP version check method
*
* @param string $req which version to compare
* @param string $relation how to compare the version
*
* @return mixed bool false if no error or the error string
*/
function checkPHP(&$errmsg, $req, $relation = 'ge')
{
// this would be a bit stupid, but oh well :)
if ($relation == 'has') {
return false;
}
if ($relation == 'not') {
$errmsg = "Invalid dependency - 'not' is allowed when specifying PHP, you must run PHP in PHP";
return PEAR_DEPENDENCY_BAD_DEPENDENCY;
}
if (substr($req, 0, 2) == 'v.') {
$req = substr($req,2, strlen($req) - 2);
}
$php_ver = phpversion();
$operator = $relation;
if (!version_compare("$php_ver", "$req", $operator)) {
$errmsg = "PHP version " . $this->signOperator($operator) .
" $req is required";
return PEAR_DEPENDENCY_CONFLICT;
}
return false;
}
 
// }}}
// {{{ checkProgram()
 
/**
* External program check method. Looks for executable files in
* directories listed in the PATH environment variable.
*
* @param string $program which program to look for
*
* @return mixed bool false if no error or the error string
*/
function checkProgram(&$errmsg, $program)
{
// XXX FIXME honor safe mode
$exe_suffix = OS_WINDOWS ? '.exe' : '';
$path_elements = explode(PATH_SEPARATOR, getenv('PATH'));
foreach ($path_elements as $dir) {
$file = $dir . DIRECTORY_SEPARATOR . $program . $exe_suffix;
if (file_exists($file) && is_executable($file)) {
return false;
}
}
$errmsg = "'$program' program is not present in the PATH";
return PEAR_DEPENDENCY_MISSING;
}
 
// }}}
// {{{ checkSAPI()
 
/**
* SAPI backend check method. Version comparison is not yet
* available here.
*
* @param string $name name of SAPI backend
* @param string $req which version to compare
* @param string $relation how to compare versions (currently
* hardcoded to 'has')
* @return mixed bool false if no error or the error string
*/
function checkSAPI(&$errmsg, $name, $req = null, $relation = 'has')
{
// XXX Fixme: There is no way to know if the user has or
// not other SAPI backends installed than the installer one
 
$sapi_backend = php_sapi_name();
// Version comparisons not supported, sapi backends don't have
// version information yet.
if ($sapi_backend == $name) {
return false;
}
$errmsg = "'$sapi_backend' SAPI backend not supported";
return PEAR_DEPENDENCY_CONFLICT;
}
 
// }}}
// {{{ checkZend()
 
/**
* Zend version check method
*
* @param string $req which version to compare
* @param string $relation how to compare the version
*
* @return mixed bool false if no error or the error string
*/
function checkZend(&$errmsg, $req, $relation = 'ge')
{
if (substr($req, 0, 2) == 'v.') {
$req = substr($req,2, strlen($req) - 2);
}
$zend_ver = zend_version();
$operator = substr($relation,0,2);
if (!version_compare("$zend_ver", "$req", $operator)) {
$errmsg = "Zend version " . $this->signOperator($operator) .
" $req is required";
return PEAR_DEPENDENCY_CONFLICT;
}
return false;
}
 
// }}}
// {{{ signOperator()
 
/**
* Converts text comparing operators to them sign equivalents
*
* Example: 'ge' to '>='
*
* @access public
* @param string Operator
* @return string Sign equivalent
*/
function signOperator($operator)
{
switch($operator) {
case 'lt': return '<';
case 'le': return '<=';
case 'gt': return '>';
case 'ge': return '>=';
case 'eq': return '==';
case 'ne': return '!=';
default:
return $operator;
}
}
 
// }}}
// {{{ codeFromRelation()
 
/**
* Convert relation into corresponding code
*
* @access public
* @param string Relation
* @param string Version
* @param string Requirement
* @param bool Optional dependency indicator
* @return integer
*/
function codeFromRelation($relation, $version, $req, $opt = false)
{
$code = PEAR_DEPENDENCY_BAD_DEPENDENCY;
switch ($relation) {
case 'gt': case 'ge': case 'eq':
// upgrade
$have_major = preg_replace('/\D.*/', '', $version);
$need_major = preg_replace('/\D.*/', '', $req);
if ($need_major > $have_major) {
$code = $opt ? PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL :
PEAR_DEPENDENCY_UPGRADE_MAJOR;
} else {
$code = $opt ? PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL :
PEAR_DEPENDENCY_UPGRADE_MINOR;
}
break;
case 'lt': case 'le': case 'ne':
$code = $opt ? PEAR_DEPENDENCY_CONFLICT_OPTIONAL :
PEAR_DEPENDENCY_CONFLICT;
break;
}
return $code;
}
 
// }}}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/ErrorStack.php
New file
0,0 → 1,985
<?php
/**
* Error Stack Implementation
*
* This is an incredibly simple implementation of a very complex error handling
* facility. It contains the ability
* to track multiple errors from multiple packages simultaneously. In addition,
* it can track errors of many levels, save data along with the error, context
* information such as the exact file, line number, class and function that
* generated the error, and if necessary, it can raise a traditional PEAR_Error.
* It has built-in support for PEAR::Log, to log errors as they occur
*
* Since version 0.2alpha, it is also possible to selectively ignore errors,
* through the use of an error callback, see {@link pushCallback()}
*
* Since version 0.3alpha, it is possible to specify the exception class
* returned from {@link push()}
*
* Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can
* still be done quite handily in an error callback or by manipulating the returned array
* @category Debugging
* @package PEAR_ErrorStack
* @author Greg Beaver <cellog@php.net>
* @copyright 2004-2006 Greg Beaver
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: ErrorStack.php,v 1.26 2006/10/31 02:54:40 cellog Exp $
* @link http://pear.php.net/package/PEAR_ErrorStack
*/
 
/**
* Singleton storage
*
* Format:
* <pre>
* array(
* 'package1' => PEAR_ErrorStack object,
* 'package2' => PEAR_ErrorStack object,
* ...
* )
* </pre>
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON']
*/
$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array();
 
/**
* Global error callback (default)
*
* This is only used if set to non-false. * is the default callback for
* all packages, whereas specific packages may set a default callback
* for all instances, regardless of whether they are a singleton or not.
*
* To exclude non-singletons, only set the local callback for the singleton
* @see PEAR_ErrorStack::setDefaultCallback()
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']
*/
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
'*' => false,
);
 
/**
* Global Log object (default)
*
* This is only used if set to non-false. Use to set a default log object for
* all stacks, regardless of instantiation order or location
* @see PEAR_ErrorStack::setDefaultLogger()
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
*/
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false;
 
/**
* Global Overriding Callback
*
* This callback will override any error callbacks that specific loggers have set.
* Use with EXTREME caution
* @see PEAR_ErrorStack::staticPushCallback()
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
*/
$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
 
/**#@+
* One of four possible return values from the error Callback
* @see PEAR_ErrorStack::_errorCallback()
*/
/**
* If this is returned, then the error will be both pushed onto the stack
* and logged.
*/
define('PEAR_ERRORSTACK_PUSHANDLOG', 1);
/**
* If this is returned, then the error will only be pushed onto the stack,
* and not logged.
*/
define('PEAR_ERRORSTACK_PUSH', 2);
/**
* If this is returned, then the error will only be logged, but not pushed
* onto the error stack.
*/
define('PEAR_ERRORSTACK_LOG', 3);
/**
* If this is returned, then the error is completely ignored.
*/
define('PEAR_ERRORSTACK_IGNORE', 4);
/**
* If this is returned, then the error is logged and die() is called.
*/
define('PEAR_ERRORSTACK_DIE', 5);
/**#@-*/
 
/**
* Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in
* the singleton method.
*/
define('PEAR_ERRORSTACK_ERR_NONCLASS', 1);
 
/**
* Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()}
* that has no __toString() method
*/
define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
/**
* Error Stack Implementation
*
* Usage:
* <code>
* // global error stack
* $global_stack = &PEAR_ErrorStack::singleton('MyPackage');
* // local error stack
* $local_stack = new PEAR_ErrorStack('MyPackage');
* </code>
* @author Greg Beaver <cellog@php.net>
* @version 1.5.1
* @package PEAR_ErrorStack
* @category Debugging
* @copyright 2004-2006 Greg Beaver
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: ErrorStack.php,v 1.26 2006/10/31 02:54:40 cellog Exp $
* @link http://pear.php.net/package/PEAR_ErrorStack
*/
class PEAR_ErrorStack {
/**
* Errors are stored in the order that they are pushed on the stack.
* @since 0.4alpha Errors are no longer organized by error level.
* This renders pop() nearly unusable, and levels could be more easily
* handled in a callback anyway
* @var array
* @access private
*/
var $_errors = array();
 
/**
* Storage of errors by level.
*
* Allows easy retrieval and deletion of only errors from a particular level
* @since PEAR 1.4.0dev
* @var array
* @access private
*/
var $_errorsByLevel = array();
 
/**
* Package name this error stack represents
* @var string
* @access protected
*/
var $_package;
/**
* Determines whether a PEAR_Error is thrown upon every error addition
* @var boolean
* @access private
*/
var $_compat = false;
/**
* If set to a valid callback, this will be used to generate the error
* message from the error code, otherwise the message passed in will be
* used
* @var false|string|array
* @access private
*/
var $_msgCallback = false;
/**
* If set to a valid callback, this will be used to generate the error
* context for an error. For PHP-related errors, this will be a file
* and line number as retrieved from debug_backtrace(), but can be
* customized for other purposes. The error might actually be in a separate
* configuration file, or in a database query.
* @var false|string|array
* @access protected
*/
var $_contextCallback = false;
/**
* If set to a valid callback, this will be called every time an error
* is pushed onto the stack. The return value will be used to determine
* whether to allow an error to be pushed or logged.
*
* The return value must be one an PEAR_ERRORSTACK_* constant
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @var false|string|array
* @access protected
*/
var $_errorCallback = array();
/**
* PEAR::Log object for logging errors
* @var false|Log
* @access protected
*/
var $_logger = false;
/**
* Error messages - designed to be overridden
* @var array
* @abstract
*/
var $_errorMsgs = array();
/**
* Set up a new error stack
*
* @param string $package name of the package this error stack represents
* @param callback $msgCallback callback used for error message generation
* @param callback $contextCallback callback used for context generation,
* defaults to {@link getFileLine()}
* @param boolean $throwPEAR_Error
*/
function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false,
$throwPEAR_Error = false)
{
$this->_package = $package;
$this->setMessageCallback($msgCallback);
$this->setContextCallback($contextCallback);
$this->_compat = $throwPEAR_Error;
}
/**
* Return a single error stack for this package.
*
* Note that all parameters are ignored if the stack for package $package
* has already been instantiated
* @param string $package name of the package this error stack represents
* @param callback $msgCallback callback used for error message generation
* @param callback $contextCallback callback used for context generation,
* defaults to {@link getFileLine()}
* @param boolean $throwPEAR_Error
* @param string $stackClass class to instantiate
* @static
* @return PEAR_ErrorStack
*/
function &singleton($package, $msgCallback = false, $contextCallback = false,
$throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack')
{
if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
}
if (!class_exists($stackClass)) {
if (function_exists('debug_backtrace')) {
$trace = debug_backtrace();
}
PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS,
'exception', array('stackclass' => $stackClass),
'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
false, $trace);
}
$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
 
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
}
 
/**
* Internal error handler for PEAR_ErrorStack class
*
* Dies if the error is an exception (and would have died anyway)
* @access private
*/
function _handleError($err)
{
if ($err['level'] == 'exception') {
$message = $err['message'];
if (isset($_SERVER['REQUEST_URI'])) {
echo '<br />';
} else {
echo "\n";
}
var_dump($err['context']);
die($message);
}
}
/**
* Set up a PEAR::Log object for all error stacks that don't have one
* @param Log $log
* @static
*/
function setDefaultLogger(&$log)
{
if (is_object($log) && method_exists($log, 'log') ) {
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
} elseif (is_callable($log)) {
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
}
}
/**
* Set up a PEAR::Log object for this error stack
* @param Log $log
*/
function setLogger(&$log)
{
if (is_object($log) && method_exists($log, 'log') ) {
$this->_logger = &$log;
} elseif (is_callable($log)) {
$this->_logger = &$log;
}
}
/**
* Set an error code => error message mapping callback
*
* This method sets the callback that can be used to generate error
* messages for any instance
* @param array|string Callback function/method
*/
function setMessageCallback($msgCallback)
{
if (!$msgCallback) {
$this->_msgCallback = array(&$this, 'getErrorMessage');
} else {
if (is_callable($msgCallback)) {
$this->_msgCallback = $msgCallback;
}
}
}
/**
* Get an error code => error message mapping callback
*
* This method returns the current callback that can be used to generate error
* messages
* @return array|string|false Callback function/method or false if none
*/
function getMessageCallback()
{
return $this->_msgCallback;
}
/**
* Sets a default callback to be used by all error stacks
*
* This method sets the callback that can be used to generate error
* messages for a singleton
* @param array|string Callback function/method
* @param string Package name, or false for all packages
* @static
*/
function setDefaultCallback($callback = false, $package = false)
{
if (!is_callable($callback)) {
$callback = false;
}
$package = $package ? $package : '*';
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;
}
/**
* Set a callback that generates context information (location of error) for an error stack
*
* This method sets the callback that can be used to generate context
* information for an error. Passing in NULL will disable context generation
* and remove the expensive call to debug_backtrace()
* @param array|string|null Callback function/method
*/
function setContextCallback($contextCallback)
{
if ($contextCallback === null) {
return $this->_contextCallback = false;
}
if (!$contextCallback) {
$this->_contextCallback = array(&$this, 'getFileLine');
} else {
if (is_callable($contextCallback)) {
$this->_contextCallback = $contextCallback;
}
}
}
/**
* Set an error Callback
* If set to a valid callback, this will be called every time an error
* is pushed onto the stack. The return value will be used to determine
* whether to allow an error to be pushed or logged.
*
* The return value must be one of the ERRORSTACK_* constants.
*
* This functionality can be used to emulate PEAR's pushErrorHandling, and
* the PEAR_ERROR_CALLBACK mode, without affecting the integrity of
* the error stack or logging
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @see popCallback()
* @param string|array $cb
*/
function pushCallback($cb)
{
array_push($this->_errorCallback, $cb);
}
/**
* Remove a callback from the error callback stack
* @see pushCallback()
* @return array|string|false
*/
function popCallback()
{
if (!count($this->_errorCallback)) {
return false;
}
return array_pop($this->_errorCallback);
}
/**
* Set a temporary overriding error callback for every package error stack
*
* Use this to temporarily disable all existing callbacks (can be used
* to emulate the @ operator, for instance)
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @see staticPopCallback(), pushCallback()
* @param string|array $cb
* @static
*/
function staticPushCallback($cb)
{
array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
}
/**
* Remove a temporary overriding error callback
* @see staticPushCallback()
* @return array|string|false
* @static
*/
function staticPopCallback()
{
$ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
}
return $ret;
}
/**
* Add an error to the stack
*
* If the message generator exists, it is called with 2 parameters.
* - the current Error Stack object
* - an array that is in the same format as an error. Available indices
* are 'code', 'package', 'time', 'params', 'level', and 'context'
*
* Next, if the error should contain context information, this is
* handled by the context grabbing method.
* Finally, the error is pushed onto the proper error stack
* @param int $code Package-specific error code
* @param string $level Error level. This is NOT spell-checked
* @param array $params associative array of error parameters
* @param string $msg Error message, or a portion of it if the message
* is to be generated
* @param array $repackage If this error re-packages an error pushed by
* another package, place the array returned from
* {@link pop()} in this parameter
* @param array $backtrace Protected parameter: use this to pass in the
* {@link debug_backtrace()} that should be used
* to find error context
* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
* thrown. If a PEAR_Error is returned, the userinfo
* property is set to the following array:
*
* <code>
* array(
* 'code' => $code,
* 'params' => $params,
* 'package' => $this->_package,
* 'level' => $level,
* 'time' => time(),
* 'context' => $context,
* 'message' => $msg,
* //['repackage' => $err] repackaged error array/Exception class
* );
* </code>
*
* Normally, the previous array is returned.
*/
function push($code, $level = 'error', $params = array(), $msg = false,
$repackage = false, $backtrace = false)
{
$context = false;
// grab error context
if ($this->_contextCallback) {
if (!$backtrace) {
$backtrace = debug_backtrace();
}
$context = call_user_func($this->_contextCallback, $code, $params, $backtrace);
}
// save error
$time = explode(' ', microtime());
$time = $time[1] + $time[0];
$err = array(
'code' => $code,
'params' => $params,
'package' => $this->_package,
'level' => $level,
'time' => $time,
'context' => $context,
'message' => $msg,
);
 
if ($repackage) {
$err['repackage'] = $repackage;
}
 
// set up the error message, if necessary
if ($this->_msgCallback) {
$msg = call_user_func_array($this->_msgCallback,
array(&$this, $err));
$err['message'] = $msg;
}
$push = $log = true;
$die = false;
// try the overriding callback first
$callback = $this->staticPopCallback();
if ($callback) {
$this->staticPushCallback($callback);
}
if (!is_callable($callback)) {
// try the local callback next
$callback = $this->popCallback();
if (is_callable($callback)) {
$this->pushCallback($callback);
} else {
// try the default callback
$callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] :
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*'];
}
}
if (is_callable($callback)) {
switch(call_user_func($callback, $err)){
case PEAR_ERRORSTACK_IGNORE:
return $err;
break;
case PEAR_ERRORSTACK_PUSH:
$log = false;
break;
case PEAR_ERRORSTACK_LOG:
$push = false;
break;
case PEAR_ERRORSTACK_DIE:
$die = true;
break;
// anything else returned has the same effect as pushandlog
}
}
if ($push) {
array_unshift($this->_errors, $err);
if (!isset($this->_errorsByLevel[$err['level']])) {
$this->_errorsByLevel[$err['level']] = array();
}
$this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
}
if ($log) {
if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {
$this->_log($err);
}
}
if ($die) {
die();
}
if ($this->_compat && $push) {
return $this->raiseError($msg, $code, null, null, $err);
}
return $err;
}
/**
* Static version of {@link push()}
*
* @param string $package Package name this error belongs to
* @param int $code Package-specific error code
* @param string $level Error level. This is NOT spell-checked
* @param array $params associative array of error parameters
* @param string $msg Error message, or a portion of it if the message
* is to be generated
* @param array $repackage If this error re-packages an error pushed by
* another package, place the array returned from
* {@link pop()} in this parameter
* @param array $backtrace Protected parameter: use this to pass in the
* {@link debug_backtrace()} that should be used
* to find error context
* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
* thrown. see docs for {@link push()}
* @static
*/
function staticPush($package, $code, $level = 'error', $params = array(),
$msg = false, $repackage = false, $backtrace = false)
{
$s = &PEAR_ErrorStack::singleton($package);
if ($s->_contextCallback) {
if (!$backtrace) {
if (function_exists('debug_backtrace')) {
$backtrace = debug_backtrace();
}
}
}
return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
}
/**
* Log an error using PEAR::Log
* @param array $err Error array
* @param array $levels Error level => Log constant map
* @access protected
*/
function _log($err)
{
if ($this->_logger) {
$logger = &$this->_logger;
} else {
$logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'];
}
if (is_a($logger, 'Log')) {
$levels = array(
'exception' => PEAR_LOG_CRIT,
'alert' => PEAR_LOG_ALERT,
'critical' => PEAR_LOG_CRIT,
'error' => PEAR_LOG_ERR,
'warning' => PEAR_LOG_WARNING,
'notice' => PEAR_LOG_NOTICE,
'info' => PEAR_LOG_INFO,
'debug' => PEAR_LOG_DEBUG);
if (isset($levels[$err['level']])) {
$level = $levels[$err['level']];
} else {
$level = PEAR_LOG_INFO;
}
$logger->log($err['message'], $level, $err);
} else { // support non-standard logs
call_user_func($logger, $err);
}
}
 
/**
* Pop an error off of the error stack
*
* @return false|array
* @since 0.4alpha it is no longer possible to specify a specific error
* level to return - the last error pushed will be returned, instead
*/
function pop()
{
$err = @array_shift($this->_errors);
if (!is_null($err)) {
@array_pop($this->_errorsByLevel[$err['level']]);
if (!count($this->_errorsByLevel[$err['level']])) {
unset($this->_errorsByLevel[$err['level']]);
}
}
return $err;
}
 
/**
* Pop an error off of the error stack, static method
*
* @param string package name
* @return boolean
* @since PEAR1.5.0a1
*/
function staticPop($package)
{
if ($package) {
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return false;
}
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
}
}
 
/**
* Determine whether there are any errors on the stack
* @param string|array Level name. Use to determine if any errors
* of level (string), or levels (array) have been pushed
* @return boolean
*/
function hasErrors($level = false)
{
if ($level) {
return isset($this->_errorsByLevel[$level]);
}
return count($this->_errors);
}
/**
* Retrieve all errors since last purge
*
* @param boolean set in order to empty the error stack
* @param string level name, to return only errors of a particular severity
* @return array
*/
function getErrors($purge = false, $level = false)
{
if (!$purge) {
if ($level) {
if (!isset($this->_errorsByLevel[$level])) {
return array();
} else {
return $this->_errorsByLevel[$level];
}
} else {
return $this->_errors;
}
}
if ($level) {
$ret = $this->_errorsByLevel[$level];
foreach ($this->_errorsByLevel[$level] as $i => $unused) {
// entries are references to the $_errors array
$this->_errorsByLevel[$level][$i] = false;
}
// array_filter removes all entries === false
$this->_errors = array_filter($this->_errors);
unset($this->_errorsByLevel[$level]);
return $ret;
}
$ret = $this->_errors;
$this->_errors = array();
$this->_errorsByLevel = array();
return $ret;
}
/**
* Determine whether there are any errors on a single error stack, or on any error stack
*
* The optional parameter can be used to test the existence of any errors without the need of
* singleton instantiation
* @param string|false Package name to check for errors
* @param string Level name to check for a particular severity
* @return boolean
* @static
*/
function staticHasErrors($package = false, $level = false)
{
if ($package) {
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return false;
}
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);
}
foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
if ($obj->hasErrors($level)) {
return true;
}
}
return false;
}
/**
* Get a list of all errors since last purge, organized by package
* @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be
* @param boolean $purge Set to purge the error stack of existing errors
* @param string $level Set to a level name in order to retrieve only errors of a particular level
* @param boolean $merge Set to return a flat array, not organized by package
* @param array $sortfunc Function used to sort a merged array - default
* sorts by time, and should be good for most cases
* @static
* @return array
*/
function staticGetErrors($purge = false, $level = false, $merge = false,
$sortfunc = array('PEAR_ErrorStack', '_sortErrors'))
{
$ret = array();
if (!is_callable($sortfunc)) {
$sortfunc = array('PEAR_ErrorStack', '_sortErrors');
}
foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
$test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);
if ($test) {
if ($merge) {
$ret = array_merge($ret, $test);
} else {
$ret[$package] = $test;
}
}
}
if ($merge) {
usort($ret, $sortfunc);
}
return $ret;
}
/**
* Error sorting function, sorts by time
* @access private
*/
function _sortErrors($a, $b)
{
if ($a['time'] == $b['time']) {
return 0;
}
if ($a['time'] < $b['time']) {
return 1;
}
return -1;
}
 
/**
* Standard file/line number/function/class context callback
*
* This function uses a backtrace generated from {@link debug_backtrace()}
* and so will not work at all in PHP < 4.3.0. The frame should
* reference the frame that contains the source of the error.
* @return array|false either array('file' => file, 'line' => line,
* 'function' => function name, 'class' => class name) or
* if this doesn't work, then false
* @param unused
* @param integer backtrace frame.
* @param array Results of debug_backtrace()
* @static
*/
function getFileLine($code, $params, $backtrace = null)
{
if ($backtrace === null) {
return false;
}
$frame = 0;
$functionframe = 1;
if (!isset($backtrace[1])) {
$functionframe = 0;
} else {
while (isset($backtrace[$functionframe]['function']) &&
$backtrace[$functionframe]['function'] == 'eval' &&
isset($backtrace[$functionframe + 1])) {
$functionframe++;
}
}
if (isset($backtrace[$frame])) {
if (!isset($backtrace[$frame]['file'])) {
$frame++;
}
$funcbacktrace = $backtrace[$functionframe];
$filebacktrace = $backtrace[$frame];
$ret = array('file' => $filebacktrace['file'],
'line' => $filebacktrace['line']);
// rearrange for eval'd code or create function errors
if (strpos($filebacktrace['file'], '(') &&
preg_match(';^(.*?)\((\d+)\) : (.*?)$;', $filebacktrace['file'],
$matches)) {
$ret['file'] = $matches[1];
$ret['line'] = $matches[2] + 0;
}
if (isset($funcbacktrace['function']) && isset($backtrace[1])) {
if ($funcbacktrace['function'] != 'eval') {
if ($funcbacktrace['function'] == '__lambda_func') {
$ret['function'] = 'create_function() code';
} else {
$ret['function'] = $funcbacktrace['function'];
}
}
}
if (isset($funcbacktrace['class']) && isset($backtrace[1])) {
$ret['class'] = $funcbacktrace['class'];
}
return $ret;
}
return false;
}
/**
* Standard error message generation callback
*
* This method may also be called by a custom error message generator
* to fill in template values from the params array, simply
* set the third parameter to the error message template string to use
*
* The special variable %__msg% is reserved: use it only to specify
* where a message passed in by the user should be placed in the template,
* like so:
*
* Error message: %msg% - internal error
*
* If the message passed like so:
*
* <code>
* $stack->push(ERROR_CODE, 'error', array(), 'server error 500');
* </code>
*
* The returned error message will be "Error message: server error 500 -
* internal error"
* @param PEAR_ErrorStack
* @param array
* @param string|false Pre-generated error message template
* @static
* @return string
*/
function getErrorMessage(&$stack, $err, $template = false)
{
if ($template) {
$mainmsg = $template;
} else {
$mainmsg = $stack->getErrorMessageTemplate($err['code']);
}
$mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
if (is_array($err['params']) && count($err['params'])) {
foreach ($err['params'] as $name => $val) {
if (is_array($val)) {
// @ is needed in case $val is a multi-dimensional array
$val = @implode(', ', $val);
}
if (is_object($val)) {
if (method_exists($val, '__toString')) {
$val = $val->__toString();
} else {
PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING,
'warning', array('obj' => get_class($val)),
'object %obj% passed into getErrorMessage, but has no __toString() method');
$val = 'Object';
}
}
$mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
}
}
return $mainmsg;
}
/**
* Standard Error Message Template generator from code
* @return string
*/
function getErrorMessageTemplate($code)
{
if (!isset($this->_errorMsgs[$code])) {
return '%__msg%';
}
return $this->_errorMsgs[$code];
}
/**
* Set the Error Message Template array
*
* The array format must be:
* <pre>
* array(error code => 'message template',...)
* </pre>
*
* Error message parameters passed into {@link push()} will be used as input
* for the error message. If the template is 'message %foo% was %bar%', and the
* parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will
* be 'message one was six'
* @return string
*/
function setErrorMessageTemplate($template)
{
$this->_errorMsgs = $template;
}
/**
* emulate PEAR::raiseError()
*
* @return PEAR_Error
*/
function raiseError()
{
require_once 'PEAR.php';
$args = func_get_args();
return call_user_func_array(array('PEAR', 'raiseError'), $args);
}
}
$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');
$stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/ChannelFile/Parser.php
New file
0,0 → 1,73
<?php
/**
* PEAR_ChannelFile_Parser for parsing channel.xml
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Parser.php,v 1.4 2006/01/06 04:47:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* base xml parser class
*/
require_once 'PEAR/XMLParser.php';
require_once 'PEAR/ChannelFile.php';
/**
* Parser for channel.xml
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_ChannelFile_Parser extends PEAR_XMLParser
{
var $_config;
var $_logger;
var $_registry;
 
function setConfig(&$c)
{
$this->_config = &$c;
$this->_registry = &$c->getRegistry();
}
 
function setLogger(&$l)
{
$this->_logger = &$l;
}
 
function parse($data, $file)
{
if (PEAR::isError($err = parent::parse($data, $file))) {
return $err;
}
$ret = new PEAR_ChannelFile;
$ret->setConfig($this->_config);
if (isset($this->_logger)) {
$ret->setLogger($this->_logger);
}
$ret->fromArray($this->_unserializedData);
// make sure the filelist is in the easy to read format needed
$ret->flattenFilelist();
$ret->setPackagefile($file, $archive);
return $ret;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/DependencyDB.php
New file
0,0 → 1,707
<?php
/**
* PEAR_DependencyDB, advanced installed packages dependency database
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: DependencyDB.php,v 1.35 2007/01/06 04:03:32 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* Needed for error handling
*/
require_once 'PEAR.php';
require_once 'PEAR/Config.php';
 
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array();
/**
* Track dependency relationships between installed packages
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Tomas V.V.Cox <cox@idec.net.com>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_DependencyDB
{
// {{{ properties
 
/**
* This is initialized by {@link setConfig()}
* @var PEAR_Config
* @access private
*/
var $_config;
/**
* This is initialized by {@link setConfig()}
* @var PEAR_Registry
* @access private
*/
var $_registry;
/**
* Filename of the dependency DB (usually .depdb)
* @var string
* @access private
*/
var $_depdb = false;
/**
* File name of the lockfile (usually .depdblock)
* @var string
* @access private
*/
var $_lockfile = false;
/**
* Open file resource for locking the lockfile
* @var resource|false
* @access private
*/
var $_lockFp = false;
/**
* API version of this class, used to validate a file on-disk
* @var string
* @access private
*/
var $_version = '1.0';
/**
* Cached dependency database file
* @var array|null
* @access private
*/
var $_cache;
 
// }}}
// {{{ & singleton()
 
/**
* Get a raw dependency database. Calls setConfig() and assertDepsDB()
* @param PEAR_Config
* @param string|false full path to the dependency database, or false to use default
* @return PEAR_DependencyDB|PEAR_Error
* @static
*/
function &singleton(&$config, $depdb = false)
{
if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
[$config->get('php_dir', null, 'pear.php.net')])) {
$a = new PEAR_DependencyDB;
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
[$config->get('php_dir', null, 'pear.php.net')] = &$a;
$a->setConfig($config, $depdb);
if (PEAR::isError($e = $a->assertDepsDB())) {
return $e;
}
}
return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
[$config->get('php_dir', null, 'pear.php.net')];
}
 
/**
* Set up the registry/location of dependency DB
* @param PEAR_Config|false
* @param string|false full path to the dependency database, or false to use default
*/
function setConfig(&$config, $depdb = false)
{
if (!$config) {
$this->_config = &PEAR_Config::singleton();
} else {
$this->_config = &$config;
}
$this->_registry = &$this->_config->getRegistry();
if (!$depdb) {
$this->_depdb = $this->_config->get('php_dir', null, 'pear.php.net') .
DIRECTORY_SEPARATOR . '.depdb';
} else {
$this->_depdb = $depdb;
}
$this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock';
}
// }}}
 
function hasWriteAccess()
{
if (!file_exists($this->_depdb)) {
$dir = $this->_depdb;
while ($dir && $dir != '.') {
$dir = dirname($dir); // cd ..
if ($dir != '.' && file_exists($dir)) {
if (is_writeable($dir)) {
return true;
} else {
return false;
}
}
}
return false;
}
return is_writeable($this->_depdb);
}
 
// {{{ assertDepsDB()
 
/**
* Create the dependency database, if it doesn't exist. Error if the database is
* newer than the code reading it.
* @return void|PEAR_Error
*/
function assertDepsDB()
{
if (!is_file($this->_depdb)) {
$this->rebuildDB();
} else {
$depdb = $this->_getDepDB();
// Datatype format has been changed, rebuild the Deps DB
if ($depdb['_version'] < $this->_version) {
$this->rebuildDB();
}
if ($depdb['_version']{0} > $this->_version{0}) {
return PEAR::raiseError('Dependency database is version ' .
$depdb['_version'] . ', and we are version ' .
$this->_version . ', cannot continue');
}
}
}
 
/**
* Get a list of installed packages that depend on this package
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
* @return array|false
*/
function getDependentPackages(&$pkg)
{
$data = $this->_getDepDB();
if (is_object($pkg)) {
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
} else {
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
}
if (isset($data['packages'][$channel][$package])) {
return $data['packages'][$channel][$package];
}
return false;
}
 
/**
* Get a list of the actual dependencies of installed packages that depend on
* a package.
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
* @return array|false
*/
function getDependentPackageDependencies(&$pkg)
{
$data = $this->_getDepDB();
if (is_object($pkg)) {
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
} else {
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
}
$depend = $this->getDependentPackages($pkg);
if (!$depend) {
return false;
}
$dependencies = array();
foreach ($depend as $info) {
$temp = $this->getDependencies($info);
foreach ($temp as $dep) {
if (strtolower($dep['dep']['channel']) == strtolower($channel) &&
strtolower($dep['dep']['name']) == strtolower($package)) {
if (!isset($dependencies[$info['channel']])) {
$dependencies[$info['channel']] = array();
}
if (!isset($dependencies[$info['channel']][$info['package']])) {
$dependencies[$info['channel']][$info['package']] = array();
}
$dependencies[$info['channel']][$info['package']][] = $dep;
}
}
}
return $dependencies;
}
 
/**
* Get a list of dependencies of this installed package
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
* @return array|false
*/
function getDependencies(&$pkg)
{
if (is_object($pkg)) {
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
} else {
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
}
$data = $this->_getDepDB();
if (isset($data['dependencies'][$channel][$package])) {
return $data['dependencies'][$channel][$package];
}
return false;
}
 
/**
* Determine whether $parent depends on $child, near or deep
* @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
* @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
*/
function dependsOn($parent, $child)
{
$c = array();
$this->_getDepDB();
return $this->_dependsOn($parent, $child, $c);
}
function _dependsOn($parent, $child, &$checked)
{
if (is_object($parent)) {
$channel = strtolower($parent->getChannel());
$package = strtolower($parent->getPackage());
} else {
$channel = strtolower($parent['channel']);
$package = strtolower($parent['package']);
}
if (is_object($child)) {
$depchannel = strtolower($child->getChannel());
$deppackage = strtolower($child->getPackage());
} else {
$depchannel = strtolower($child['channel']);
$deppackage = strtolower($child['package']);
}
if (isset($checked[$channel][$package][$depchannel][$deppackage])) {
return false; // avoid endless recursion
}
$checked[$channel][$package][$depchannel][$deppackage] = true;
if (!isset($this->_cache['dependencies'][$channel][$package])) {
return false;
}
foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
if (isset($info['dep']['uri'])) {
if (is_object($child)) {
if ($info['dep']['uri'] == $child->getURI()) {
return true;
}
} elseif (isset($child['uri'])) {
if ($info['dep']['uri'] == $child['uri']) {
return true;
}
}
return false;
}
if (strtolower($info['dep']['channel']) == strtolower($depchannel) &&
strtolower($info['dep']['name']) == strtolower($deppackage)) {
return true;
}
}
foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
if (isset($info['dep']['uri'])) {
if ($this->_dependsOn(array(
'uri' => $info['dep']['uri'],
'package' => $info['dep']['name']), $child, $checked)) {
return true;
}
} else {
if ($this->_dependsOn(array(
'channel' => $info['dep']['channel'],
'package' => $info['dep']['name']), $child, $checked)) {
return true;
}
}
}
return false;
}
 
/**
* Register dependencies of a package that is being installed or upgraded
* @param PEAR_PackageFile_v2|PEAR_PackageFile_v2
*/
function installPackage(&$package)
{
$data = $this->_getDepDB();
unset($this->_cache);
$this->_setPackageDeps($data, $package);
$this->_writeDepDB($data);
}
 
/**
* Remove dependencies of a package that is being uninstalled, or upgraded.
*
* Upgraded packages first uninstall, then install
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have
* indices 'channel' and 'package'
*/
function uninstallPackage(&$pkg)
{
$data = $this->_getDepDB();
unset($this->_cache);
if (is_object($pkg)) {
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
} else {
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
}
if (!isset($data['dependencies'][$channel][$package])) {
return true;
}
foreach ($data['dependencies'][$channel][$package] as $dep) {
$found = false;
if (isset($dep['dep']['uri'])) {
$depchannel = '__uri';
} else {
$depchannel = strtolower($dep['dep']['channel']);
}
if (isset($data['packages'][$depchannel][strtolower($dep['dep']['name'])])) {
foreach ($data['packages'][$depchannel][strtolower($dep['dep']['name'])] as
$i => $info) {
if ($info['channel'] == $channel &&
$info['package'] == $package) {
$found = true;
break;
}
}
}
if ($found) {
unset($data['packages'][$depchannel][strtolower($dep['dep']['name'])][$i]);
if (!count($data['packages'][$depchannel][strtolower($dep['dep']['name'])])) {
unset($data['packages'][$depchannel][strtolower($dep['dep']['name'])]);
if (!count($data['packages'][$depchannel])) {
unset($data['packages'][$depchannel]);
}
} else {
$data['packages'][$depchannel][strtolower($dep['dep']['name'])] =
array_values(
$data['packages'][$depchannel][strtolower($dep['dep']['name'])]);
}
}
}
unset($data['dependencies'][$channel][$package]);
if (!count($data['dependencies'][$channel])) {
unset($data['dependencies'][$channel]);
}
if (!count($data['dependencies'])) {
unset($data['dependencies']);
}
if (!count($data['packages'])) {
unset($data['packages']);
}
$this->_writeDepDB($data);
}
 
/**
* Rebuild the dependency DB by reading registry entries.
* @return true|PEAR_Error
*/
function rebuildDB()
{
$depdb = array('_version' => $this->_version);
if (!$this->hasWriteAccess()) {
// allow startup for read-only with older Registry
return $depdb;
}
$packages = $this->_registry->listAllPackages();
foreach ($packages as $channel => $ps) {
foreach ($ps as $package) {
$package = $this->_registry->getPackage($package, $channel);
$this->_setPackageDeps($depdb, $package);
}
}
$error = $this->_writeDepDB($depdb);
if (PEAR::isError($error)) {
return $error;
}
$this->_cache = $depdb;
return true;
}
 
/**
* Register usage of the dependency DB to prevent race conditions
* @param int one of the LOCK_* constants
* @return true|PEAR_Error
* @access private
*/
function _lock($mode = LOCK_EX)
{
if (!eregi('Windows 9', php_uname())) {
if ($mode != LOCK_UN && is_resource($this->_lockFp)) {
// XXX does not check type of lock (LOCK_SH/LOCK_EX)
return true;
}
$open_mode = 'w';
// XXX People reported problems with LOCK_SH and 'w'
if ($mode === LOCK_SH) {
if (!file_exists($this->_lockfile)) {
touch($this->_lockfile);
} elseif (!is_file($this->_lockfile)) {
return PEAR::raiseError('could not create Dependency lock file, ' .
'it exists and is not a regular file');
}
$open_mode = 'r';
}
 
if (!is_resource($this->_lockFp)) {
$this->_lockFp = @fopen($this->_lockfile, $open_mode);
}
if (!is_resource($this->_lockFp)) {
return PEAR::raiseError("could not create Dependency lock file" .
(isset($php_errormsg) ? ": " . $php_errormsg : ""));
}
if (!(int)flock($this->_lockFp, $mode)) {
switch ($mode) {
case LOCK_SH: $str = 'shared'; break;
case LOCK_EX: $str = 'exclusive'; break;
case LOCK_UN: $str = 'unlock'; break;
default: $str = 'unknown'; break;
}
return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)");
}
}
return true;
}
 
/**
* Release usage of dependency DB
* @return true|PEAR_Error
* @access private
*/
function _unlock()
{
$ret = $this->_lock(LOCK_UN);
if (is_resource($this->_lockFp)) {
fclose($this->_lockFp);
}
$this->_lockFp = null;
return $ret;
}
 
/**
* Load the dependency database from disk, or return the cache
* @return array|PEAR_Error
*/
function _getDepDB()
{
if (!$this->hasWriteAccess()) {
return array('_version' => $this->_version);
}
if (isset($this->_cache)) {
return $this->_cache;
}
if (!$fp = fopen($this->_depdb, 'r')) {
$err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'");
return $err;
}
$rt = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
clearstatcache();
fclose($fp);
$data = unserialize(file_get_contents($this->_depdb));
set_magic_quotes_runtime($rt);
$this->_cache = $data;
return $data;
}
 
/**
* Write out the dependency database to disk
* @param array the database
* @return true|PEAR_Error
* @access private
*/
function _writeDepDB(&$deps)
{
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
if (!$fp = fopen($this->_depdb, 'wb')) {
$this->_unlock();
return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing");
}
$rt = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
fwrite($fp, serialize($deps));
set_magic_quotes_runtime($rt);
fclose($fp);
$this->_unlock();
$this->_cache = $deps;
return true;
}
 
/**
* Register all dependencies from a package in the dependencies database, in essence
* "installing" the package's dependency information
* @param array the database
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @access private
*/
function _setPackageDeps(&$data, &$pkg)
{
$pkg->setConfig($this->_config);
if ($pkg->getPackagexmlVersion() == '1.0') {
$gen = &$pkg->getDefaultGenerator();
$deps = $gen->dependenciesToV2();
} else {
$deps = $pkg->getDeps(true);
}
if (!$deps) {
return;
}
if (!is_array($data)) {
$data = array();
}
if (!isset($data['dependencies'])) {
$data['dependencies'] = array();
}
if (!isset($data['dependencies'][strtolower($pkg->getChannel())])) {
$data['dependencies'][strtolower($pkg->getChannel())] = array();
}
$data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())]
= array();
if (isset($deps['required']['package'])) {
if (!isset($deps['required']['package'][0])) {
$deps['required']['package'] = array($deps['required']['package']);
}
foreach ($deps['required']['package'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'required');
}
}
if (isset($deps['optional']['package'])) {
if (!isset($deps['optional']['package'][0])) {
$deps['optional']['package'] = array($deps['optional']['package']);
}
foreach ($deps['optional']['package'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'optional');
}
}
if (isset($deps['required']['subpackage'])) {
if (!isset($deps['required']['subpackage'][0])) {
$deps['required']['subpackage'] = array($deps['required']['subpackage']);
}
foreach ($deps['required']['subpackage'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'required');
}
}
if (isset($deps['optional']['subpackage'])) {
if (!isset($deps['optional']['subpackage'][0])) {
$deps['optional']['subpackage'] = array($deps['optional']['subpackage']);
}
foreach ($deps['optional']['subpackage'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'optional');
}
}
if (isset($deps['group'])) {
if (!isset($deps['group'][0])) {
$deps['group'] = array($deps['group']);
}
foreach ($deps['group'] as $group) {
if (isset($group['package'])) {
if (!isset($group['package'][0])) {
$group['package'] = array($group['package']);
}
foreach ($group['package'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'optional',
$group['attribs']['name']);
}
}
if (isset($group['subpackage'])) {
if (!isset($group['subpackage'][0])) {
$group['subpackage'] = array($group['subpackage']);
}
foreach ($group['subpackage'] as $dep) {
$this->_registerDep($data, $pkg, $dep, 'optional',
$group['attribs']['name']);
}
}
}
}
if ($data['dependencies'][strtolower($pkg->getChannel())]
[strtolower($pkg->getPackage())] == array()) {
unset($data['dependencies'][strtolower($pkg->getChannel())]
[strtolower($pkg->getPackage())]);
if (!count($data['dependencies'][strtolower($pkg->getChannel())])) {
unset($data['dependencies'][strtolower($pkg->getChannel())]);
}
}
}
 
/**
* @param array the database
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param array the specific dependency
* @param required|optional whether this is a required or an optional dep
* @param string|false dependency group this dependency is from, or false for ordinary dep
*/
function _registerDep(&$data, &$pkg, $dep, $type, $group = false)
{
$info = array(
'dep' => $dep,
'type' => $type,
'group' => $group);
 
if (isset($dep['channel'])) {
$depchannel = $dep['channel'];
} else {
$depchannel = '__uri';
}
if (!isset($data['dependencies'])) {
$data['dependencies'] = array();
}
if (!isset($data['dependencies'][strtolower($pkg->getChannel())])) {
$data['dependencies'][strtolower($pkg->getChannel())] = array();
}
if (!isset($data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())])) {
$data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())] = array();
}
$data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())][]
= $info;
if (isset($data['packages'][strtolower($depchannel)][strtolower($dep['name'])])) {
$found = false;
foreach ($data['packages'][strtolower($depchannel)][strtolower($dep['name'])]
as $i => $p) {
if ($p['channel'] == strtolower($pkg->getChannel()) &&
$p['package'] == strtolower($pkg->getPackage())) {
$found = true;
break;
}
}
if (!$found) {
$data['packages'][strtolower($depchannel)][strtolower($dep['name'])][]
= array('channel' => strtolower($pkg->getChannel()),
'package' => strtolower($pkg->getPackage()));
}
} else {
if (!isset($data['packages'])) {
$data['packages'] = array();
}
if (!isset($data['packages'][strtolower($depchannel)])) {
$data['packages'][strtolower($depchannel)] = array();
}
if (!isset($data['packages'][strtolower($depchannel)][strtolower($dep['name'])])) {
$data['packages'][strtolower($depchannel)][strtolower($dep['name'])] = array();
}
$data['packages'][strtolower($depchannel)][strtolower($dep['name'])][]
= array('channel' => strtolower($pkg->getChannel()),
'package' => strtolower($pkg->getPackage()));
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Common.php
New file
0,0 → 1,1126
<?php
/**
* PEAR_Common, the base class for the PEAR Installer
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Common.php,v 1.157 2006/05/12 02:38:58 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1.0
* @deprecated File deprecated since Release 1.4.0a1
*/
 
/**
* Include error handling
*/
require_once 'PEAR.php';
 
// {{{ constants and globals
 
/**
* PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode()
*/
define('PEAR_COMMON_ERROR_INVALIDPHP', 1);
define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+');
define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '$/');
 
// this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1
define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?');
define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '$/i');
 
// XXX far from perfect :-)
define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG .
')(-([.0-9a-zA-Z]+))?');
define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG .
'$/');
 
define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+');
define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '$/');
 
// this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED
define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*');
define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '$/i');
 
define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/('
. _PEAR_COMMON_PACKAGE_NAME_PREG . ')');
define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '$/i');
 
define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::('
. _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?');
define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '$/');
 
/**
* List of temporary files and directories registered by
* PEAR_Common::addTempFile().
* @var array
*/
$GLOBALS['_PEAR_Common_tempfiles'] = array();
 
/**
* Valid maintainer roles
* @var array
*/
$GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper');
 
/**
* Valid release states
* @var array
*/
$GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel');
 
/**
* Valid dependency types
* @var array
*/
$GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi');
 
/**
* Valid dependency relations
* @var array
*/
$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne');
 
/**
* Valid file roles
* @var array
*/
$GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script');
 
/**
* Valid replacement types
* @var array
*/
$GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info');
 
/**
* Valid "provide" types
* @var array
*/
$GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api');
 
/**
* Valid "provide" types
* @var array
*/
$GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup');
 
// }}}
 
/**
* Class providing common functionality for PEAR administration classes.
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @deprecated This class will disappear, and its components will be spread
* into smaller classes, like the AT&T breakup, as of Release 1.4.0a1
*/
class PEAR_Common extends PEAR
{
// {{{ properties
 
/** stack of elements, gives some sort of XML context */
var $element_stack = array();
 
/** name of currently parsed XML element */
var $current_element;
 
/** array of attributes of the currently parsed XML element */
var $current_attributes = array();
 
/** assoc with information about a package */
var $pkginfo = array();
 
/**
* User Interface object (PEAR_Frontend_* class). If null,
* the log() method uses print.
* @var object
*/
var $ui = null;
 
/**
* Configuration object (PEAR_Config).
* @var object
*/
var $config = null;
 
var $current_path = null;
 
/**
* PEAR_SourceAnalyzer instance
* @var object
*/
var $source_analyzer = null;
/**
* Flag variable used to mark a valid package file
* @var boolean
* @access private
*/
var $_validPackageFile;
 
// }}}
 
// {{{ constructor
 
/**
* PEAR_Common constructor
*
* @access public
*/
function PEAR_Common()
{
parent::PEAR();
$this->config = &PEAR_Config::singleton();
$this->debug = $this->config->get('verbose');
}
 
// }}}
// {{{ destructor
 
/**
* PEAR_Common destructor
*
* @access private
*/
function _PEAR_Common()
{
// doesn't work due to bug #14744
//$tempfiles = $this->_tempfiles;
$tempfiles =& $GLOBALS['_PEAR_Common_tempfiles'];
while ($file = array_shift($tempfiles)) {
if (@is_dir($file)) {
if (!class_exists('System')) {
require_once 'System.php';
}
System::rm(array('-rf', $file));
} elseif (file_exists($file)) {
unlink($file);
}
}
}
 
// }}}
// {{{ addTempFile()
 
/**
* Register a temporary file or directory. When the destructor is
* executed, all registered temporary files and directories are
* removed.
*
* @param string $file name of file or directory
*
* @return void
*
* @access public
*/
function addTempFile($file)
{
if (!class_exists('PEAR_Frontend')) {
require_once 'PEAR/Frontend.php';
}
PEAR_Frontend::addTempFile($file);
}
 
// }}}
// {{{ mkDirHier()
 
/**
* Wrapper to System::mkDir(), creates a directory as well as
* any necessary parent directories.
*
* @param string $dir directory name
*
* @return bool TRUE on success, or a PEAR error
*
* @access public
*/
function mkDirHier($dir)
{
$this->log(2, "+ create dir $dir");
if (!class_exists('System')) {
require_once 'System.php';
}
return System::mkDir(array('-p', $dir));
}
 
// }}}
// {{{ log()
 
/**
* Logging method.
*
* @param int $level log level (0 is quiet, higher is noisier)
* @param string $msg message to write to the log
*
* @return void
*
* @access public
* @static
*/
function log($level, $msg, $append_crlf = true)
{
if ($this->debug >= $level) {
if (!class_exists('PEAR_Frontend')) {
require_once 'PEAR/Frontend.php';
}
$ui = &PEAR_Frontend::singleton();
if (is_a($ui, 'PEAR_Frontend')) {
$ui->log($msg, $append_crlf);
} else {
print "$msg\n";
}
}
}
 
// }}}
// {{{ mkTempDir()
 
/**
* Create and register a temporary directory.
*
* @param string $tmpdir (optional) Directory to use as tmpdir.
* Will use system defaults (for example
* /tmp or c:\windows\temp) if not specified
*
* @return string name of created directory
*
* @access public
*/
function mkTempDir($tmpdir = '')
{
if ($tmpdir) {
$topt = array('-t', $tmpdir);
} else {
$topt = array();
}
$topt = array_merge($topt, array('-d', 'pear'));
if (!class_exists('System')) {
require_once 'System.php';
}
if (!$tmpdir = System::mktemp($topt)) {
return false;
}
$this->addTempFile($tmpdir);
return $tmpdir;
}
 
// }}}
// {{{ setFrontendObject()
 
/**
* Set object that represents the frontend to be used.
*
* @param object Reference of the frontend object
* @return void
* @access public
*/
function setFrontendObject(&$ui)
{
$this->ui = &$ui;
}
 
// }}}
 
// {{{ infoFromTgzFile()
 
/**
* Returns information about a package file. Expects the name of
* a gzipped tar file as input.
*
* @param string $file name of .tgz file
*
* @return array array with package information
*
* @access public
* @deprecated use PEAR_PackageFile->fromTgzFile() instead
*
*/
function infoFromTgzFile($file)
{
$packagefile = &new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
return $pf;
}
return $this->_postProcessValidPackagexml($pf);
}
 
// }}}
// {{{ infoFromDescriptionFile()
 
/**
* Returns information about a package file. Expects the name of
* a package xml file as input.
*
* @param string $descfile name of package xml file
*
* @return array array with package information
*
* @access public
* @deprecated use PEAR_PackageFile->fromPackageFile() instead
*
*/
function infoFromDescriptionFile($descfile)
{
$packagefile = &new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
return $pf;
}
return $this->_postProcessValidPackagexml($pf);
}
 
// }}}
// {{{ infoFromString()
 
/**
* Returns information about a package file. Expects the contents
* of a package xml file as input.
*
* @param string $data contents of package.xml file
*
* @return array array with package information
*
* @access public
* @deprecated use PEAR_PackageFile->fromXmlstring() instead
*
*/
function infoFromString($data)
{
$packagefile = &new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false);
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
return $pf;
}
return $this->_postProcessValidPackagexml($pf);
}
// }}}
 
/**
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @return array
*/
function _postProcessValidPackagexml(&$pf)
{
if (is_a($pf, 'PEAR_PackageFile_v2')) {
// sort of make this into a package.xml 1.0-style array
// changelog is not converted to old format.
$arr = $pf->toArray(true);
$arr = array_merge($arr, $arr['old']);
unset($arr['old']);
unset($arr['xsdversion']);
unset($arr['contents']);
unset($arr['compatible']);
unset($arr['channel']);
unset($arr['uri']);
unset($arr['dependencies']);
unset($arr['phprelease']);
unset($arr['extsrcrelease']);
unset($arr['zendextsrcrelease']);
unset($arr['extbinrelease']);
unset($arr['zendextbinrelease']);
unset($arr['bundle']);
unset($arr['lead']);
unset($arr['developer']);
unset($arr['helper']);
unset($arr['contributor']);
$arr['filelist'] = $pf->getFilelist();
$this->pkginfo = $arr;
return $arr;
} else {
$this->pkginfo = $pf->toArray();
return $this->pkginfo;
}
}
// {{{ infoFromAny()
 
/**
* Returns package information from different sources
*
* This method is able to extract information about a package
* from a .tgz archive or from a XML package definition file.
*
* @access public
* @param string Filename of the source ('package.xml', '<package>.tgz')
* @return string
* @deprecated use PEAR_PackageFile->fromAnyFile() instead
*/
function infoFromAny($info)
{
if (is_string($info) && file_exists($info)) {
$packagefile = &new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
return $pf;
}
return $this->_postProcessValidPackagexml($pf);
}
return $info;
}
 
// }}}
// {{{ xmlFromInfo()
 
/**
* Return an XML document based on the package info (as returned
* by the PEAR_Common::infoFrom* methods).
*
* @param array $pkginfo package info
*
* @return string XML data
*
* @access public
* @deprecated use a PEAR_PackageFile_v* object's generator instead
*/
function xmlFromInfo($pkginfo)
{
$config = &PEAR_Config::singleton();
$packagefile = &new PEAR_PackageFile($config);
$pf = &$packagefile->fromArray($pkginfo);
$gen = &$pf->getDefaultGenerator();
return $gen->toXml(PEAR_VALIDATE_PACKAGING);
}
 
// }}}
// {{{ validatePackageInfo()
 
/**
* Validate XML package definition file.
*
* @param string $info Filename of the package archive or of the
* package definition file
* @param array $errors Array that will contain the errors
* @param array $warnings Array that will contain the warnings
* @param string $dir_prefix (optional) directory where source files
* may be found, or empty if they are not available
* @access public
* @return boolean
* @deprecated use the validation of PEAR_PackageFile objects
*/
function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '')
{
$config = &PEAR_Config::singleton();
$packagefile = &new PEAR_PackageFile($config);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (strpos($info, '<?xml') !== false) {
$pf = &$packagefile->fromXmlString($info, PEAR_VALIDATE_NORMAL, '');
} else {
$pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL);
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
if ($error['level'] == 'error') {
$errors[] = $error['message'];
} else {
$warnings[] = $error['message'];
}
}
}
return false;
}
return true;
}
 
// }}}
// {{{ buildProvidesArray()
 
/**
* Build a "provides" array from data returned by
* analyzeSourceCode(). The format of the built array is like
* this:
*
* array(
* 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
* ...
* )
*
*
* @param array $srcinfo array with information about a source file
* as returned by the analyzeSourceCode() method.
*
* @return void
*
* @access public
*
*/
function buildProvidesArray($srcinfo)
{
$file = basename($srcinfo['source_file']);
$pn = '';
if (isset($this->_packageName)) {
$pn = $this->_packageName;
}
$pnl = strlen($pn);
foreach ($srcinfo['declared_classes'] as $class) {
$key = "class;$class";
if (isset($this->pkginfo['provides'][$key])) {
continue;
}
$this->pkginfo['provides'][$key] =
array('file'=> $file, 'type' => 'class', 'name' => $class);
if (isset($srcinfo['inheritance'][$class])) {
$this->pkginfo['provides'][$key]['extends'] =
$srcinfo['inheritance'][$class];
}
}
foreach ($srcinfo['declared_methods'] as $class => $methods) {
foreach ($methods as $method) {
$function = "$class::$method";
$key = "function;$function";
if ($method{0} == '_' || !strcasecmp($method, $class) ||
isset($this->pkginfo['provides'][$key])) {
continue;
}
$this->pkginfo['provides'][$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
}
 
foreach ($srcinfo['declared_functions'] as $function) {
$key = "function;$function";
if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) {
continue;
}
if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
$warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
}
$this->pkginfo['provides'][$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
}
 
// }}}
// {{{ analyzeSourceCode()
 
/**
* Analyze the source code of the given PHP file
*
* @param string Filename of the PHP file
* @return mixed
* @access public
*/
function analyzeSourceCode($file)
{
if (!function_exists("token_get_all")) {
return false;
}
if (!defined('T_DOC_COMMENT')) {
define('T_DOC_COMMENT', T_COMMENT);
}
if (!defined('T_INTERFACE')) {
define('T_INTERFACE', -1);
}
if (!defined('T_IMPLEMENTS')) {
define('T_IMPLEMENTS', -1);
}
if (!$fp = @fopen($file, "r")) {
return false;
}
fclose($fp);
$contents = file_get_contents($file);
$tokens = token_get_all($contents);
/*
for ($i = 0; $i < sizeof($tokens); $i++) {
@list($token, $data) = $tokens[$i];
if (is_string($token)) {
var_dump($token);
} else {
print token_name($token) . ' ';
var_dump(rtrim($data));
}
}
*/
$look_for = 0;
$paren_level = 0;
$bracket_level = 0;
$brace_level = 0;
$lastphpdoc = '';
$current_class = '';
$current_interface = '';
$current_class_level = -1;
$current_function = '';
$current_function_level = -1;
$declared_classes = array();
$declared_interfaces = array();
$declared_functions = array();
$declared_methods = array();
$used_classes = array();
$used_functions = array();
$extends = array();
$implements = array();
$nodeps = array();
$inquote = false;
$interface = false;
for ($i = 0; $i < sizeof($tokens); $i++) {
if (is_array($tokens[$i])) {
list($token, $data) = $tokens[$i];
} else {
$token = $tokens[$i];
$data = '';
}
if ($inquote) {
if ($token != '"') {
continue;
} else {
$inquote = false;
continue;
}
}
switch ($token) {
case T_WHITESPACE:
continue;
case ';':
if ($interface) {
$current_function = '';
$current_function_level = -1;
}
break;
case '"':
$inquote = true;
break;
case T_CURLY_OPEN:
case T_DOLLAR_OPEN_CURLY_BRACES:
case '{': $brace_level++; continue 2;
case '}':
$brace_level--;
if ($current_class_level == $brace_level) {
$current_class = '';
$current_class_level = -1;
}
if ($current_function_level == $brace_level) {
$current_function = '';
$current_function_level = -1;
}
continue 2;
case '[': $bracket_level++; continue 2;
case ']': $bracket_level--; continue 2;
case '(': $paren_level++; continue 2;
case ')': $paren_level--; continue 2;
case T_INTERFACE:
$interface = true;
case T_CLASS:
if (($current_class_level != -1) || ($current_function_level != -1)) {
PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"",
PEAR_COMMON_ERROR_INVALIDPHP);
return false;
}
case T_FUNCTION:
case T_NEW:
case T_EXTENDS:
case T_IMPLEMENTS:
$look_for = $token;
continue 2;
case T_STRING:
if (version_compare(zend_version(), '2.0', '<')) {
if (in_array(strtolower($data),
array('public', 'private', 'protected', 'abstract',
'interface', 'implements', 'throw')
)) {
PEAR::raiseError('Error: PHP5 token encountered in ' . $file .
'packaging should be done in PHP 5');
return false;
}
}
if ($look_for == T_CLASS) {
$current_class = $data;
$current_class_level = $brace_level;
$declared_classes[] = $current_class;
} elseif ($look_for == T_INTERFACE) {
$current_interface = $data;
$current_class_level = $brace_level;
$declared_interfaces[] = $current_interface;
} elseif ($look_for == T_IMPLEMENTS) {
$implements[$current_class] = $data;
} elseif ($look_for == T_EXTENDS) {
$extends[$current_class] = $data;
} elseif ($look_for == T_FUNCTION) {
if ($current_class) {
$current_function = "$current_class::$data";
$declared_methods[$current_class][] = $data;
} elseif ($current_interface) {
$current_function = "$current_interface::$data";
$declared_methods[$current_interface][] = $data;
} else {
$current_function = $data;
$declared_functions[] = $current_function;
}
$current_function_level = $brace_level;
$m = array();
} elseif ($look_for == T_NEW) {
$used_classes[$data] = true;
}
$look_for = 0;
continue 2;
case T_VARIABLE:
$look_for = 0;
continue 2;
case T_DOC_COMMENT:
case T_COMMENT:
if (preg_match('!^/\*\*\s!', $data)) {
$lastphpdoc = $data;
if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
$nodeps = array_merge($nodeps, $m[1]);
}
}
continue 2;
case T_DOUBLE_COLON:
if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"",
PEAR_COMMON_ERROR_INVALIDPHP);
return false;
}
$class = $tokens[$i - 1][1];
if (strtolower($class) != 'parent') {
$used_classes[$class] = true;
}
continue 2;
}
}
return array(
"source_file" => $file,
"declared_classes" => $declared_classes,
"declared_interfaces" => $declared_interfaces,
"declared_methods" => $declared_methods,
"declared_functions" => $declared_functions,
"used_classes" => array_diff(array_keys($used_classes), $nodeps),
"inheritance" => $extends,
"implements" => $implements,
);
}
 
// }}}
// {{{ betterStates()
 
/**
* Return an array containing all of the states that are more stable than
* or equal to the passed in state
*
* @param string Release state
* @param boolean Determines whether to include $state in the list
* @return false|array False if $state is not a valid release state
*/
function betterStates($state, $include = false)
{
static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
$i = array_search($state, $states);
if ($i === false) {
return false;
}
if ($include) {
$i--;
}
return array_slice($states, $i + 1);
}
 
// }}}
// {{{ detectDependencies()
 
function detectDependencies($any, $status_callback = null)
{
if (!function_exists("token_get_all")) {
return false;
}
if (PEAR::isError($info = $this->infoFromAny($any))) {
return $this->raiseError($info);
}
if (!is_array($info)) {
return false;
}
$deps = array();
$used_c = $decl_c = $decl_f = $decl_m = array();
foreach ($info['filelist'] as $file => $fa) {
$tmp = $this->analyzeSourceCode($file);
$used_c = @array_merge($used_c, $tmp['used_classes']);
$decl_c = @array_merge($decl_c, $tmp['declared_classes']);
$decl_f = @array_merge($decl_f, $tmp['declared_functions']);
$decl_m = @array_merge($decl_m, $tmp['declared_methods']);
$inheri = @array_merge($inheri, $tmp['inheritance']);
}
$used_c = array_unique($used_c);
$decl_c = array_unique($decl_c);
$undecl_c = array_diff($used_c, $decl_c);
return array('used_classes' => $used_c,
'declared_classes' => $decl_c,
'declared_methods' => $decl_m,
'declared_functions' => $decl_f,
'undeclared_classes' => $undecl_c,
'inheritance' => $inheri,
);
}
 
// }}}
// {{{ getUserRoles()
 
/**
* Get the valid roles for a PEAR package maintainer
*
* @return array
* @static
*/
function getUserRoles()
{
return $GLOBALS['_PEAR_Common_maintainer_roles'];
}
 
// }}}
// {{{ getReleaseStates()
 
/**
* Get the valid package release states of packages
*
* @return array
* @static
*/
function getReleaseStates()
{
return $GLOBALS['_PEAR_Common_release_states'];
}
 
// }}}
// {{{ getDependencyTypes()
 
/**
* Get the implemented dependency types (php, ext, pkg etc.)
*
* @return array
* @static
*/
function getDependencyTypes()
{
return $GLOBALS['_PEAR_Common_dependency_types'];
}
 
// }}}
// {{{ getDependencyRelations()
 
/**
* Get the implemented dependency relations (has, lt, ge etc.)
*
* @return array
* @static
*/
function getDependencyRelations()
{
return $GLOBALS['_PEAR_Common_dependency_relations'];
}
 
// }}}
// {{{ getFileRoles()
 
/**
* Get the implemented file roles
*
* @return array
* @static
*/
function getFileRoles()
{
return $GLOBALS['_PEAR_Common_file_roles'];
}
 
// }}}
// {{{ getReplacementTypes()
 
/**
* Get the implemented file replacement types in
*
* @return array
* @static
*/
function getReplacementTypes()
{
return $GLOBALS['_PEAR_Common_replacement_types'];
}
 
// }}}
// {{{ getProvideTypes()
 
/**
* Get the implemented file replacement types in
*
* @return array
* @static
*/
function getProvideTypes()
{
return $GLOBALS['_PEAR_Common_provide_types'];
}
 
// }}}
// {{{ getScriptPhases()
 
/**
* Get the implemented file replacement types in
*
* @return array
* @static
*/
function getScriptPhases()
{
return $GLOBALS['_PEAR_Common_script_phases'];
}
 
// }}}
// {{{ validPackageName()
 
/**
* Test whether a string contains a valid package name.
*
* @param string $name the package name to test
*
* @return bool
*
* @access public
*/
function validPackageName($name)
{
return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name);
}
 
 
// }}}
// {{{ validPackageVersion()
 
/**
* Test whether a string contains a valid package version.
*
* @param string $ver the package version to test
*
* @return bool
*
* @access public
*/
function validPackageVersion($ver)
{
return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver);
}
 
 
// }}}
 
// {{{ downloadHttp()
 
/**
* Download a file through HTTP. Considers suggested file name in
* Content-disposition: header and can run a callback function for
* different events. The callback will be called with two
* parameters: the callback type, and parameters. The implemented
* callback types are:
*
* 'setup' called at the very beginning, parameter is a UI object
* that should be used for all output
* 'message' the parameter is a string with an informational message
* 'saveas' may be used to save with a different file name, the
* parameter is the filename that is about to be used.
* If a 'saveas' callback returns a non-empty string,
* that file name will be used as the filename instead.
* Note that $save_dir will not be affected by this, only
* the basename of the file.
* 'start' download is starting, parameter is number of bytes
* that are expected, or -1 if unknown
* 'bytesread' parameter is the number of bytes read so far
* 'done' download is complete, parameter is the total number
* of bytes read
* 'connfailed' if the TCP connection fails, this callback is called
* with array(host,port,errno,errmsg)
* 'writefailed' if writing to disk fails, this callback is called
* with array(destfile,errmsg)
*
* If an HTTP proxy has been configured (http_proxy PEAR_Config
* setting), the proxy will be used.
*
* @param string $url the URL to download
* @param object $ui PEAR_Frontend_* instance
* @param object $config PEAR_Config instance
* @param string $save_dir (optional) directory to save file in
* @param mixed $callback (optional) function/method to call for status
* updates
*
* @return string Returns the full path of the downloaded file or a PEAR
* error on failure. If the error is caused by
* socket-related errors, the error object will
* have the fsockopen error code available through
* getCode().
*
* @access public
* @deprecated in favor of PEAR_Downloader::downloadHttp()
*/
function downloadHttp($url, &$ui, $save_dir = '.', $callback = null)
{
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
return PEAR_Downloader::downloadHttp($url, $ui, $save_dir, $callback);
}
 
// }}}
 
/**
* @param string $path relative or absolute include path
* @return boolean
* @static
*/
function isIncludeable($path)
{
if (file_exists($path) && is_readable($path)) {
return true;
}
$ipath = explode(PATH_SEPARATOR, ini_get('include_path'));
foreach ($ipath as $include) {
$test = realpath($include . DIRECTORY_SEPARATOR . $path);
if (file_exists($test) && is_readable($test)) {
return true;
}
}
return false;
}
}
require_once 'PEAR/Config.php';
require_once 'PEAR/PackageFile.php';
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Remote.php
New file
0,0 → 1,498
<?php
/**
* PEAR_Remote
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Remote.php,v 1.79 2006/03/27 04:33:11 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* needed for PEAR_Error
*/
require_once 'PEAR.php';
require_once 'PEAR/Config.php';
 
/**
* This is a class for doing remote operations against the central
* PEAR database.
*
* @nodep XML_RPC_Value
* @nodep XML_RPC_Message
* @nodep XML_RPC_Client
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Remote extends PEAR
{
// {{{ properties
 
var $config = null;
var $cache = null;
/**
* @var PEAR_Registry
* @access private
*/
var $_registry;
 
// }}}
 
// {{{ PEAR_Remote(config_object)
 
function PEAR_Remote(&$config)
{
$this->PEAR();
$this->config = &$config;
$this->_registry = &$this->config->getRegistry();
}
 
// }}}
// {{{ setRegistry()
function setRegistry(&$reg)
{
$this->_registry = &$reg;
}
// }}}
// {{{ getCache()
 
 
function getCache($args)
{
$id = md5(serialize($args));
$cachedir = $this->config->get('cache_dir');
$filename = $cachedir . DIRECTORY_SEPARATOR . 'xmlrpc_cache_' . $id;
if (!file_exists($filename)) {
return null;
}
 
$fp = fopen($filename, 'rb');
if (!$fp) {
return null;
}
fclose($fp);
$content = file_get_contents($filename);
$result = array(
'age' => time() - filemtime($filename),
'lastChange' => filemtime($filename),
'content' => unserialize($content),
);
return $result;
}
 
// }}}
 
// {{{ saveCache()
 
function saveCache($args, $data)
{
$id = md5(serialize($args));
$cachedir = $this->config->get('cache_dir');
if (!file_exists($cachedir)) {
System::mkdir(array('-p', $cachedir));
}
$filename = $cachedir.'/xmlrpc_cache_'.$id;
 
$fp = @fopen($filename, "wb");
if ($fp) {
fwrite($fp, serialize($data));
fclose($fp);
}
}
 
// }}}
 
// {{{ clearCache()
 
function clearCache($method, $args)
{
array_unshift($args, $method);
array_unshift($args, $this->config->get('default_channel')); // cache by channel
$id = md5(serialize($args));
$cachedir = $this->config->get('cache_dir');
$filename = $cachedir.'/xmlrpc_cache_'.$id;
if (file_exists($filename)) {
@unlink($filename);
}
}
 
// }}}
// {{{ call(method, [args...])
 
function call($method)
{
$_args = $args = func_get_args();
 
$server_channel = $this->config->get('default_channel');
$channel = $this->_registry->getChannel($server_channel);
if (!PEAR::isError($channel)) {
$mirror = $this->config->get('preferred_mirror');
if ($channel->getMirror($mirror)) {
if ($channel->supports('xmlrpc', $method, $mirror)) {
$server_channel = $server_host = $mirror; // use the preferred mirror
$server_port = $channel->getPort($mirror);
} elseif (!$channel->supports('xmlrpc', $method)) {
return $this->raiseError("Channel $server_channel does not " .
"support xml-rpc method $method");
}
}
if (!isset($server_host)) {
if (!$channel->supports('xmlrpc', $method)) {
return $this->raiseError("Channel $server_channel does not support " .
"xml-rpc method $method");
} else {
$server_host = $server_channel;
$server_port = $channel->getPort();
}
}
} else {
return $this->raiseError("Unknown channel '$server_channel'");
}
 
array_unshift($_args, $server_channel); // cache by channel
$this->cache = $this->getCache($_args);
$cachettl = $this->config->get('cache_ttl');
// If cache is newer than $cachettl seconds, we use the cache!
if ($this->cache !== null && $this->cache['age'] < $cachettl) {
return $this->cache['content'];
}
$fp = false;
if (extension_loaded("xmlrpc")) {
$result = call_user_func_array(array(&$this, 'call_epi'), $args);
if (!PEAR::isError($result)) {
$this->saveCache($_args, $result);
}
return $result;
} elseif (!($fp = fopen('XML/RPC.php', 'r', true))) {
return $this->raiseError("For this remote PEAR operation you need to load the xmlrpc extension or install XML_RPC");
}
include_once 'XML/RPC.php';
if ($fp) {
fclose($fp);
}
 
array_shift($args);
$username = $this->config->get('username');
$password = $this->config->get('password');
$eargs = array();
foreach($args as $arg) {
$eargs[] = $this->_encode($arg);
}
$f = new XML_RPC_Message($method, $eargs);
if ($this->cache !== null) {
$maxAge = '?maxAge='.$this->cache['lastChange'];
} else {
$maxAge = '';
}
$proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
if ($proxy = parse_url($this->config->get('http_proxy'))) {
$proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') {
$proxy_host = 'https://' . $proxy_host;
}
$proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080;
$proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
$proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
}
$shost = $server_host;
if ($channel->getSSL()) {
$shost = "https://$shost";
}
$c = new XML_RPC_Client('/' . $channel->getPath('xmlrpc')
. $maxAge, $shost, $server_port, $proxy_host, $proxy_port,
$proxy_user, $proxy_pass);
if ($username && $password) {
$c->setCredentials($username, $password);
}
if ($this->config->get('verbose') >= 3) {
$c->setDebug(1);
}
$r = $c->send($f);
if (!$r) {
return $this->raiseError("XML_RPC send failed");
}
$v = $r->value();
if ($e = $r->faultCode()) {
if ($e == $GLOBALS['XML_RPC_err']['http_error'] && strstr($r->faultString(), '304 Not Modified') !== false) {
return $this->cache['content'];
}
return $this->raiseError($r->faultString(), $e);
}
 
$result = XML_RPC_decode($v);
$this->saveCache($_args, $result);
return $result;
}
 
// }}}
 
// {{{ call_epi(method, [args...])
 
function call_epi($method)
{
if (!extension_loaded("xmlrpc")) {
return $this->raiseError("xmlrpc extension is not loaded");
}
$server_channel = $this->config->get('default_channel');
$channel = $this->_registry->getChannel($server_channel);
if (!PEAR::isError($channel)) {
$mirror = $this->config->get('preferred_mirror');
if ($channel->getMirror($mirror)) {
if ($channel->supports('xmlrpc', $method, $mirror)) {
$server_channel = $server_host = $mirror; // use the preferred mirror
$server_port = $channel->getPort($mirror);
} elseif (!$channel->supports('xmlrpc', $method)) {
return $this->raiseError("Channel $server_channel does not " .
"support xml-rpc method $method");
}
}
if (!isset($server_host)) {
if (!$channel->supports('xmlrpc', $method)) {
return $this->raiseError("Channel $server_channel does not support " .
"xml-rpc method $method");
} else {
$server_host = $server_channel;
$server_port = $channel->getPort();
}
}
} else {
return $this->raiseError("Unknown channel '$server_channel'");
}
$params = func_get_args();
array_shift($params);
$method = str_replace("_", ".", $method);
$request = xmlrpc_encode_request($method, $params);
if ($http_proxy = $this->config->get('http_proxy')) {
$proxy = parse_url($http_proxy);
$proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
$proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') {
$proxy_host = 'https://' . $proxy_host;
}
$proxy_port = isset($proxy['port']) ? $proxy['port'] : null;
$proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
$proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
$fp = @fsockopen($proxy_host, $proxy_port);
$use_proxy = true;
if ($channel->getSSL()) {
$server_host = "https://$server_host";
}
} else {
$use_proxy = false;
$ssl = $channel->getSSL();
$fp = @fsockopen(($ssl ? 'ssl://' : '') . $server_host, $server_port);
if (!$fp) {
$server_host = "$ssl$server_host"; // for error-reporting
}
}
if (!$fp && $http_proxy) {
return $this->raiseError("PEAR_Remote::call: fsockopen(`$proxy_host', $proxy_port) failed");
} elseif (!$fp) {
return $this->raiseError("PEAR_Remote::call: fsockopen(`$server_host', $server_port) failed");
}
$len = strlen($request);
$req_headers = "Host: $server_host:$server_port\r\n" .
"Content-type: text/xml\r\n" .
"Content-length: $len\r\n";
$username = $this->config->get('username');
$password = $this->config->get('password');
if ($username && $password) {
$req_headers .= "Cookie: PEAR_USER=$username; PEAR_PW=$password\r\n";
$tmp = base64_encode("$username:$password");
$req_headers .= "Authorization: Basic $tmp\r\n";
}
if ($this->cache !== null) {
$maxAge = '?maxAge='.$this->cache['lastChange'];
} else {
$maxAge = '';
}
 
if ($use_proxy && $proxy_host != '' && $proxy_user != '') {
$req_headers .= 'Proxy-Authorization: Basic '
.base64_encode($proxy_user.':'.$proxy_pass)
."\r\n";
}
 
if ($this->config->get('verbose') > 3) {
print "XMLRPC REQUEST HEADERS:\n";
var_dump($req_headers);
print "XMLRPC REQUEST BODY:\n";
var_dump($request);
}
 
if ($use_proxy && $proxy_host != '') {
$post_string = "POST http://".$server_host;
if ($proxy_port > '') {
$post_string .= ':'.$server_port;
}
} else {
$post_string = "POST ";
}
 
$path = '/' . $channel->getPath('xmlrpc');
fwrite($fp, ($post_string . $path . "$maxAge HTTP/1.0\r\n$req_headers\r\n$request"));
$response = '';
$line1 = fgets($fp, 2048);
if (!preg_match('!^HTTP/[0-9\.]+ (\d+) (.*)!', $line1, $matches)) {
return $this->raiseError("PEAR_Remote: invalid HTTP response from XML-RPC server");
}
switch ($matches[1]) {
case "200": // OK
break;
case "304": // Not Modified
return $this->cache['content'];
case "401": // Unauthorized
if ($username && $password) {
return $this->raiseError("PEAR_Remote ($server_host:$server_port) " .
": authorization failed", 401);
} else {
return $this->raiseError("PEAR_Remote ($server_host:$server_port) " .
": authorization required, please log in first", 401);
}
default:
return $this->raiseError("PEAR_Remote ($server_host:$server_port) : " .
"unexpected HTTP response", (int)$matches[1], null, null,
"$matches[1] $matches[2]");
}
while (trim(fgets($fp, 2048)) != ''); // skip rest of headers
while ($chunk = fread($fp, 10240)) {
$response .= $chunk;
}
fclose($fp);
if ($this->config->get('verbose') > 3) {
print "XMLRPC RESPONSE:\n";
var_dump($response);
}
$ret = xmlrpc_decode($response);
if (is_array($ret) && isset($ret['__PEAR_TYPE__'])) {
if ($ret['__PEAR_TYPE__'] == 'error') {
if (isset($ret['__PEAR_CLASS__'])) {
$class = $ret['__PEAR_CLASS__'];
} else {
$class = "PEAR_Error";
}
if ($ret['code'] === '') $ret['code'] = null;
if ($ret['message'] === '') $ret['message'] = null;
if ($ret['userinfo'] === '') $ret['userinfo'] = null;
if (strtolower($class) == 'db_error') {
$ret = $this->raiseError(PEAR::errorMessage($ret['code']),
$ret['code'], null, null,
$ret['userinfo']);
} else {
$ret = $this->raiseError($ret['message'], $ret['code'],
null, null, $ret['userinfo']);
}
}
} elseif (is_array($ret) && sizeof($ret) == 1 && isset($ret[0])
&& is_array($ret[0]) &&
!empty($ret[0]['faultString']) &&
!empty($ret[0]['faultCode'])) {
extract($ret[0]);
$faultString = "XML-RPC Server Fault: " .
str_replace("\n", " ", $faultString);
return $this->raiseError($faultString, $faultCode);
} elseif (is_array($ret) && sizeof($ret) == 2 && !empty($ret['faultString']) &&
!empty($ret['faultCode'])) {
extract($ret);
$faultString = "XML-RPC Server Fault: " .
str_replace("\n", " ", $faultString);
return $this->raiseError($faultString, $faultCode);
}
return $ret;
}
 
// }}}
 
// {{{ _encode
 
// a slightly extended version of XML_RPC_encode
function _encode($php_val)
{
global $XML_RPC_Boolean, $XML_RPC_Int, $XML_RPC_Double;
global $XML_RPC_String, $XML_RPC_Array, $XML_RPC_Struct;
 
$type = gettype($php_val);
$xmlrpcval = new XML_RPC_Value;
 
switch($type) {
case "array":
reset($php_val);
$firstkey = key($php_val);
end($php_val);
$lastkey = key($php_val);
reset($php_val);
if ($firstkey === 0 && is_int($lastkey) &&
($lastkey + 1) == count($php_val)) {
$is_continuous = true;
reset($php_val);
$size = count($php_val);
for ($expect = 0; $expect < $size; $expect++, next($php_val)) {
if (key($php_val) !== $expect) {
$is_continuous = false;
break;
}
}
if ($is_continuous) {
reset($php_val);
$arr = array();
while (list($k, $v) = each($php_val)) {
$arr[$k] = $this->_encode($v);
}
$xmlrpcval->addArray($arr);
break;
}
}
// fall though if not numerical and continuous
case "object":
$arr = array();
while (list($k, $v) = each($php_val)) {
$arr[$k] = $this->_encode($v);
}
$xmlrpcval->addStruct($arr);
break;
case "integer":
$xmlrpcval->addScalar($php_val, $XML_RPC_Int);
break;
case "double":
$xmlrpcval->addScalar($php_val, $XML_RPC_Double);
break;
case "string":
case "NULL":
$xmlrpcval->addScalar($php_val, $XML_RPC_String);
break;
case "boolean":
$xmlrpcval->addScalar($php_val, $XML_RPC_Boolean);
break;
case "unknown type":
default:
return null;
}
return $xmlrpcval;
}
 
// }}}
 
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Exception.php
New file
0,0 → 1,393
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
/**
* PEAR_Exception
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Hans Lellelid <hans@velum.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Exception.php,v 1.26 2006/10/30 03:47:48 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.3.3
*/
 
 
/**
* Base PEAR_Exception Class
*
* 1) Features:
*
* - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
* - Definable triggers, shot when exceptions occur
* - Pretty and informative error messages
* - Added more context info available (like class, method or cause)
* - cause can be a PEAR_Exception or an array of mixed
* PEAR_Exceptions/PEAR_ErrorStack warnings
* - callbacks for specific exception classes and their children
*
* 2) Ideas:
*
* - Maybe a way to define a 'template' for the output
*
* 3) Inherited properties from PHP Exception Class:
*
* protected $message
* protected $code
* protected $line
* protected $file
* private $trace
*
* 4) Inherited methods from PHP Exception Class:
*
* __clone
* __construct
* getMessage
* getCode
* getFile
* getLine
* getTraceSafe
* getTraceSafeAsString
* __toString
*
* 5) Usage example
*
* <code>
* require_once 'PEAR/Exception.php';
*
* class Test {
* function foo() {
* throw new PEAR_Exception('Error Message', ERROR_CODE);
* }
* }
*
* function myLogger($pear_exception) {
* echo $pear_exception->getMessage();
* }
* // each time a exception is thrown the 'myLogger' will be called
* // (its use is completely optional)
* PEAR_Exception::addObserver('myLogger');
* $test = new Test;
* try {
* $test->foo();
* } catch (PEAR_Exception $e) {
* print $e;
* }
* </code>
*
* @category pear
* @package PEAR
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Hans Lellelid <hans@velum.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.3.3
*
*/
class PEAR_Exception extends Exception
{
const OBSERVER_PRINT = -2;
const OBSERVER_TRIGGER = -4;
const OBSERVER_DIE = -8;
protected $cause;
private static $_observers = array();
private static $_uniqueid = 0;
private $_trace;
 
/**
* Supported signatures:
* - PEAR_Exception(string $message);
* - PEAR_Exception(string $message, int $code);
* - PEAR_Exception(string $message, Exception $cause);
* - PEAR_Exception(string $message, Exception $cause, int $code);
* - PEAR_Exception(string $message, PEAR_Error $cause);
* - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
* - PEAR_Exception(string $message, array $causes);
* - PEAR_Exception(string $message, array $causes, int $code);
* @param string exception message
* @param int|Exception|PEAR_Error|array|null exception cause
* @param int|null exception code or null
*/
public function __construct($message, $p2 = null, $p3 = null)
{
if (is_int($p2)) {
$code = $p2;
$this->cause = null;
} elseif (is_object($p2) || is_array($p2)) {
// using is_object allows both Exception and PEAR_Error
if (is_object($p2) && !($p2 instanceof Exception)) {
if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
throw new PEAR_Exception('exception cause must be Exception, ' .
'array, or PEAR_Error');
}
}
$code = $p3;
if (is_array($p2) && isset($p2['message'])) {
// fix potential problem of passing in a single warning
$p2 = array($p2);
}
$this->cause = $p2;
} else {
$code = null;
$this->cause = null;
}
parent::__construct($message, $code);
$this->signal();
}
 
/**
* @param mixed $callback - A valid php callback, see php func is_callable()
* - A PEAR_Exception::OBSERVER_* constant
* - An array(const PEAR_Exception::OBSERVER_*,
* mixed $options)
* @param string $label The name of the observer. Use this if you want
* to remove it later with removeObserver()
*/
public static function addObserver($callback, $label = 'default')
{
self::$_observers[$label] = $callback;
}
 
public static function removeObserver($label = 'default')
{
unset(self::$_observers[$label]);
}
 
/**
* @return int unique identifier for an observer
*/
public static function getUniqueId()
{
return self::$_uniqueid++;
}
 
private function signal()
{
foreach (self::$_observers as $func) {
if (is_callable($func)) {
call_user_func($func, $this);
continue;
}
settype($func, 'array');
switch ($func[0]) {
case self::OBSERVER_PRINT :
$f = (isset($func[1])) ? $func[1] : '%s';
printf($f, $this->getMessage());
break;
case self::OBSERVER_TRIGGER :
$f = (isset($func[1])) ? $func[1] : E_USER_NOTICE;
trigger_error($this->getMessage(), $f);
break;
case self::OBSERVER_DIE :
$f = (isset($func[1])) ? $func[1] : '%s';
die(printf($f, $this->getMessage()));
break;
default:
trigger_error('invalid observer type', E_USER_WARNING);
}
}
}
 
/**
* Return specific error information that can be used for more detailed
* error messages or translation.
*
* This method may be overridden in child exception classes in order
* to add functionality not present in PEAR_Exception and is a placeholder
* to define API
*
* The returned array must be an associative array of parameter => value like so:
* <pre>
* array('name' => $name, 'context' => array(...))
* </pre>
* @return array
*/
public function getErrorData()
{
return array();
}
 
/**
* Returns the exception that caused this exception to be thrown
* @access public
* @return Exception|array The context of the exception
*/
public function getCause()
{
return $this->cause;
}
 
/**
* Function must be public to call on caused exceptions
* @param array
*/
public function getCauseMessage(&$causes)
{
$trace = $this->getTraceSafe();
$cause = array('class' => get_class($this),
'message' => $this->message,
'file' => 'unknown',
'line' => 'unknown');
if (isset($trace[0])) {
if (isset($trace[0]['file'])) {
$cause['file'] = $trace[0]['file'];
$cause['line'] = $trace[0]['line'];
}
}
$causes[] = $cause;
if ($this->cause instanceof PEAR_Exception) {
$this->cause->getCauseMessage($causes);
} elseif ($this->cause instanceof Exception) {
$causes[] = array('class' => get_class($this->cause),
'message' => $this->cause->getMessage(),
'file' => $this->cause->getFile(),
'line' => $this->cause->getLine());
} elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
$causes[] = array('class' => get_class($this->cause),
'message' => $this->cause->getMessage());
} elseif (is_array($this->cause)) {
foreach ($this->cause as $cause) {
if ($cause instanceof PEAR_Exception) {
$cause->getCauseMessage($causes);
} elseif ($cause instanceof Exception) {
$causes[] = array('class' => get_class($cause),
'message' => $cause->getMessage(),
'file' => $cause->getFile(),
'line' => $cause->getLine());
} elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) {
$causes[] = array('class' => get_class($cause),
'message' => $cause->getMessage());
} elseif (is_array($cause) && isset($cause['message'])) {
// PEAR_ErrorStack warning
$causes[] = array(
'class' => $cause['package'],
'message' => $cause['message'],
'file' => isset($cause['context']['file']) ?
$cause['context']['file'] :
'unknown',
'line' => isset($cause['context']['line']) ?
$cause['context']['line'] :
'unknown',
);
}
}
}
}
 
public function getTraceSafe()
{
if (!isset($this->_trace)) {
$this->_trace = $this->getTrace();
if (empty($this->_trace)) {
$backtrace = debug_backtrace();
$this->_trace = array($backtrace[count($backtrace)-1]);
}
}
return $this->_trace;
}
 
public function getErrorClass()
{
$trace = $this->getTraceSafe();
return $trace[0]['class'];
}
 
public function getErrorMethod()
{
$trace = $this->getTraceSafe();
return $trace[0]['function'];
}
 
public function __toString()
{
if (isset($_SERVER['REQUEST_URI'])) {
return $this->toHtml();
}
return $this->toText();
}
 
public function toHtml()
{
$trace = $this->getTraceSafe();
$causes = array();
$this->getCauseMessage($causes);
$html = '<table border="1" cellspacing="0">' . "\n";
foreach ($causes as $i => $cause) {
$html .= '<tr><td colspan="3" bgcolor="#ff9999">'
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
. htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
. 'on line <b>' . $cause['line'] . '</b>'
. "</td></tr>\n";
}
$html .= '<tr><td colspan="3" bgcolor="#aaaaaa" align="center"><b>Exception trace</b></td></tr>' . "\n"
. '<tr><td align="center" bgcolor="#cccccc" width="20"><b>#</b></td>'
. '<td align="center" bgcolor="#cccccc"><b>Function</b></td>'
. '<td align="center" bgcolor="#cccccc"><b>Location</b></td></tr>' . "\n";
 
foreach ($trace as $k => $v) {
$html .= '<tr><td align="center">' . $k . '</td>'
. '<td>';
if (!empty($v['class'])) {
$html .= $v['class'] . $v['type'];
}
$html .= $v['function'];
$args = array();
if (!empty($v['args'])) {
foreach ($v['args'] as $arg) {
if (is_null($arg)) $args[] = 'null';
elseif (is_array($arg)) $args[] = 'Array';
elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')';
elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false';
elseif (is_int($arg) || is_double($arg)) $args[] = $arg;
else {
$arg = (string)$arg;
$str = htmlspecialchars(substr($arg, 0, 16));
if (strlen($arg) > 16) $str .= '&hellip;';
$args[] = "'" . $str . "'";
}
}
}
$html .= '(' . implode(', ',$args) . ')'
. '</td>'
. '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
. ':' . (isset($v['line']) ? $v['line'] : 'unknown')
. '</td></tr>' . "\n";
}
$html .= '<tr><td align="center">' . ($k+1) . '</td>'
. '<td>{main}</td>'
. '<td>&nbsp;</td></tr>' . "\n"
. '</table>';
return $html;
}
 
public function toText()
{
$causes = array();
$this->getCauseMessage($causes);
$causeMsg = '';
foreach ($causes as $i => $cause) {
$causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': '
. $cause['message'] . ' in ' . $cause['file']
. ' on line ' . $cause['line'] . "\n";
}
return $causeMsg . $this->getTraceAsString();
}
}
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR/Validator/PECL.php
New file
0,0 → 1,63
<?php
/**
* Channel Validator for the pecl.php.net channel
*
* PHP 4 and PHP 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: PECL.php,v 1.8 2006/05/12 02:38:58 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a5
*/
/**
* This is the parent class for all validators
*/
require_once 'PEAR/Validate.php';
/**
* Channel Validator for the pecl.php.net channel
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a5
*/
class PEAR_Validator_PECL extends PEAR_Validate
{
function validateVersion()
{
if ($this->_state == PEAR_VALIDATE_PACKAGING) {
$version = $this->_packagexml->getVersion();
$versioncomponents = explode('.', $version);
$last = array_pop($versioncomponents);
if (substr($last, 1, 2) == 'rc') {
$this->_addFailure('version', 'Release Candidate versions must have ' .
'upper-case RC, not lower-case rc');
return false;
}
}
return true;
}
 
function validatePackageName()
{
$ret = parent::validatePackageName();
if ($this->_packagexml->getPackageType() == 'extsrc' ||
$this->_packagexml->getPackageType() == 'zendextsrc') {
if (strtolower($this->_packagexml->getPackage()) !=
strtolower($this->_packagexml->getProvidesExtension())) {
$this->_addWarning('providesextension', 'package name "' .
$this->_packagexml->getPackage() . '" is different from extension name "' .
$this->_packagexml->getProvidesExtension() . '"');
}
}
return $ret;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Decorator.php
New file
0,0 → 1,558
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Decorator.php,v 1.3 2005/10/22 10:29:46 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Decorator.php,v 1.3 2005/10/22 10:29:46 quipo Exp $
*/
/**
* Decorates any calendar class.
* Create a subclass of this class for your own "decoration".
* Used for "selections"
* <code>
* class DayDecorator extends Calendar_Decorator
* {
* function thisDay($format = 'int')
* {
.* $day = parent::thisDay('timestamp');
.* return date('D', $day);
* }
* }
* $Day = & new Calendar_Day(2003, 10, 25);
* $DayDecorator = & new DayDecorator($Day);
* echo $DayDecorator->thisDay(); // Outputs "Sat"
* </code>
* @abstract
* @package Calendar
*/
class Calendar_Decorator
{
/**
* Subclass of Calendar being decorated
* @var object
* @access private
*/
var $calendar;
 
/**
* Constructs the Calendar_Decorator
* @param object subclass to Calendar to decorate
*/
function Calendar_Decorator(& $calendar)
{
$this->calendar = & $calendar;
}
 
/**
* Defines the calendar by a Unix timestamp, replacing values
* passed to the constructor
* @param int Unix timestamp
* @return void
* @access public
*/
function setTimestamp($ts)
{
$this->calendar->setTimestamp($ts);
}
 
/**
* Returns a timestamp from the current date / time values. Format of
* timestamp depends on Calendar_Engine implementation being used
* @return int timestamp
* @access public
*/
function getTimestamp()
{
return $this->calendar->getTimeStamp();
}
 
/**
* Defines calendar object as selected (e.g. for today)
* @param boolean state whether Calendar subclass
* @return void
* @access public
*/
function setSelected($state = true)
{
$this->calendar->setSelected($state = true);
}
 
/**
* True if the calendar subclass object is selected (e.g. today)
* @return boolean
* @access public
*/
function isSelected()
{
return $this->calendar->isSelected();
}
 
/**
* Adjusts the date (helper method)
* @return void
* @access public
*/
function adjust()
{
$this->calendar->adjust();
}
 
/**
* Returns the date as an associative array (helper method)
* @param mixed timestamp (leave empty for current timestamp)
* @return array
* @access public
*/
function toArray($stamp=null)
{
return $this->calendar->toArray($stamp);
}
 
/**
* Returns the value as an associative array (helper method)
* @param string type of date object that return value represents
* @param string $format ['int' | 'array' | 'timestamp' | 'object']
* @param mixed timestamp (depending on Calendar engine being used)
* @param int integer default value (i.e. give me the answer quick)
* @return mixed
* @access private
*/
function returnValue($returnType, $format, $stamp, $default)
{
return $this->calendar->returnValue($returnType, $format, $stamp, $default);
}
 
/**
* Defines Day object as first in a week
* Only used by Calendar_Month_Weekdays::build()
* @param boolean state
* @return void
* @access private
*/
function setFirst ($state = true)
{
if ( method_exists($this->calendar,'setFirst') ) {
$this->calendar->setFirst($state);
}
}
 
/**
* Defines Day object as last in a week
* Used only following Calendar_Month_Weekdays::build()
* @param boolean state
* @return void
* @access private
*/
function setLast($state = true)
{
if ( method_exists($this->calendar,'setLast') ) {
$this->calendar->setLast($state);
}
}
 
/**
* Returns true if Day object is first in a Week
* Only relevant when Day is created by Calendar_Month_Weekdays::build()
* @return boolean
* @access public
*/
function isFirst() {
if ( method_exists($this->calendar,'isFirst') ) {
return $this->calendar->isFirst();
}
}
 
/**
* Returns true if Day object is last in a Week
* Only relevant when Day is created by Calendar_Month_Weekdays::build()
* @return boolean
* @access public
*/
function isLast()
{
if ( method_exists($this->calendar,'isLast') ) {
return $this->calendar->isLast();
}
}
 
/**
* Defines Day object as empty
* Only used by Calendar_Month_Weekdays::build()
* @param boolean state
* @return void
* @access private
*/
function setEmpty ($state = true)
{
if ( method_exists($this->calendar,'setEmpty') ) {
$this->calendar->setEmpty($state);
}
}
 
/**
* @return boolean
* @access public
*/
function isEmpty()
{
if ( method_exists($this->calendar,'isEmpty') ) {
return $this->calendar->isEmpty();
}
}
 
/**
* Build the children
* @param array containing Calendar objects to select (optional)
* @return boolean
* @access public
* @abstract
*/
function build($sDates = array())
{
$this->calendar->build($sDates);
}
 
/**
* Iterator method for fetching child Calendar subclass objects
* (e.g. a minute from an hour object). On reaching the end of
* the collection, returns false and resets the collection for
* further iteratations.
* @return mixed either an object subclass of Calendar or false
* @access public
*/
function fetch()
{
return $this->calendar->fetch();
}
 
/**
* Fetches all child from the current collection of children
* @return array
* @access public
*/
function fetchAll()
{
return $this->calendar->fetchAll();
}
 
/**
* Get the number Calendar subclass objects stored in the internal
* collection.
* @return int
* @access public
*/
function size()
{
return $this->calendar->size();
}
 
/**
* Determine whether this date is valid, with the bounds determined by
* the Calendar_Engine. The call is passed on to
* Calendar_Validator::isValid
* @return boolean
* @access public
*/
function isValid()
{
return $this->calendar->isValid();
}
 
/**
* Returns an instance of Calendar_Validator
* @return Calendar_Validator
* @access public
*/
function & getValidator()
{
$validator = $this->calendar->getValidator();
return $validator;
}
 
/**
* Returns a reference to the current Calendar_Engine being used. Useful
* for Calendar_Table_Helper and Calendar_Validator
* @return object implementing Calendar_Engine_Inteface
* @access private
*/
function & getEngine()
{
return $this->calendar->getEngine();
}
 
/**
* Returns the value for the previous year
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 2002 or timestamp
* @access public
*/
function prevYear($format = 'int')
{
return $this->calendar->prevYear($format);
}
 
/**
* Returns the value for this year
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 2003 or timestamp
* @access public
*/
function thisYear($format = 'int')
{
return $this->calendar->thisYear($format);
}
 
/**
* Returns the value for next year
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 2004 or timestamp
* @access public
*/
function nextYear($format = 'int')
{
return $this->calendar->nextYear($format);
}
 
/**
* Returns the value for the previous month
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 4 or Unix timestamp
* @access public
*/
function prevMonth($format = 'int')
{
return $this->calendar->prevMonth($format);
}
 
/**
* Returns the value for this month
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 5 or timestamp
* @access public
*/
function thisMonth($format = 'int')
{
return $this->calendar->thisMonth($format);
}
 
/**
* Returns the value for next month
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 6 or timestamp
* @access public
*/
function nextMonth($format = 'int')
{
return $this->calendar->nextMonth($format);
}
 
/**
* Returns the value for the previous week
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 4 or Unix timestamp
* @access public
*/
function prevWeek($format = 'n_in_month')
{
if ( method_exists($this->calendar,'prevWeek') ) {
return $this->calendar->prevWeek($format);
} else {
require_once 'PEAR.php';
PEAR::raiseError(
'Cannot call prevWeek on Calendar object of type: '.
get_class($this->calendar), 133, PEAR_ERROR_TRIGGER,
E_USER_NOTICE, 'Calendar_Decorator::prevWeek()');
return false;
}
}
 
/**
* Returns the value for this week
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 5 or timestamp
* @access public
*/
function thisWeek($format = 'n_in_month')
{
if ( method_exists($this->calendar,'thisWeek') ) {
return $this->calendar->thisWeek($format);
} else {
require_once 'PEAR.php';
PEAR::raiseError(
'Cannot call thisWeek on Calendar object of type: '.
get_class($this->calendar), 133, PEAR_ERROR_TRIGGER,
E_USER_NOTICE, 'Calendar_Decorator::thisWeek()');
return false;
}
}
 
/**
* Returns the value for next week
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 6 or timestamp
* @access public
*/
function nextWeek($format = 'n_in_month')
{
if ( method_exists($this->calendar,'nextWeek') ) {
return $this->calendar->nextWeek($format);
} else {
require_once 'PEAR.php';
PEAR::raiseError(
'Cannot call thisWeek on Calendar object of type: '.
get_class($this->calendar), 133, PEAR_ERROR_TRIGGER,
E_USER_NOTICE, 'Calendar_Decorator::nextWeek()');
return false;
}
}
 
/**
* Returns the value for the previous day
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 10 or timestamp
* @access public
*/
function prevDay($format = 'int') {
return $this->calendar->prevDay($format);
}
 
/**
* Returns the value for this day
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 11 or timestamp
* @access public
*/
function thisDay($format = 'int')
{
return $this->calendar->thisDay($format);
}
 
/**
* Returns the value for the next day
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 12 or timestamp
* @access public
*/
function nextDay($format = 'int')
{
return $this->calendar->nextDay($format);
}
 
/**
* Returns the value for the previous hour
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 13 or timestamp
* @access public
*/
function prevHour($format = 'int')
{
return $this->calendar->prevHour($format);
}
 
/**
* Returns the value for this hour
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 14 or timestamp
* @access public
*/
function thisHour($format = 'int')
{
return $this->calendar->thisHour($format);
}
 
/**
* Returns the value for the next hour
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 14 or timestamp
* @access public
*/
function nextHour($format = 'int')
{
return $this->calendar->nextHour($format);
}
 
/**
* Returns the value for the previous minute
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 23 or timestamp
* @access public
*/
function prevMinute($format = 'int')
{
return $this->calendar->prevMinute($format);
}
 
/**
* Returns the value for this minute
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 24 or timestamp
* @access public
*/
function thisMinute($format = 'int')
{
return $this->calendar->thisMinute($format);
}
 
/**
* Returns the value for the next minute
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 25 or timestamp
* @access public
*/
function nextMinute($format = 'int')
{
return $this->calendar->nextMinute($format);
}
 
/**
* Returns the value for the previous second
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 43 or timestamp
* @access public
*/
function prevSecond($format = 'int')
{
return $this->calendar->prevSecond($format);
}
 
/**
* Returns the value for this second
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 44 or timestamp
* @access public
*/
function thisSecond($format = 'int')
{
return $this->calendar->thisSecond($format);
}
 
/**
* Returns the value for the next second
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 45 or timestamp
* @access public
*/
function nextSecond($format = 'int')
{
return $this->calendar->nextSecond($format);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Month.php
New file
0,0 → 1,114
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Month.php,v 1.3 2005/10/22 10:10:26 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Month.php,v 1.3 2005/10/22 10:10:26 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar base class
*/
require_once CALENDAR_ROOT.'Calendar.php';
 
/**
* Represents a Month and builds Days
* <code>
* require_once 'Calendar/Month.php';
* $Month = & new Calendar_Month(2003, 10); // Oct 2003
* $Month->build(); // Build Calendar_Day objects
* while ($Day = & $Month->fetch()) {
* echo $Day->thisDay().'<br />';
* }
* </code>
* @package Calendar
* @access public
*/
class Calendar_Month extends Calendar
{
/**
* Constructs Calendar_Month
* @param int $y year e.g. 2003
* @param int $m month e.g. 5
* @param int $firstDay first day of the week [optional]
* @access public
*/
function Calendar_Month($y, $m, $firstDay=null)
{
Calendar::Calendar($y, $m);
$this->firstDay = $this->defineFirstDayOfWeek($firstDay);
}
 
/**
* Builds Day objects for this Month. Creates as many Calendar_Day objects
* as there are days in the month
* @param array (optional) Calendar_Day objects representing selected dates
* @return boolean
* @access public
*/
function build($sDates=array())
{
require_once CALENDAR_ROOT.'Day.php';
$daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month);
for ($i=1; $i<=$daysInMonth; $i++) {
$this->children[$i] = new Calendar_Day($this->year, $this->month, $i);
}
if (count($sDates) > 0) {
$this->setSelection($sDates);
}
return true;
}
 
/**
* Called from build()
* @param array
* @return void
* @access private
*/
function setSelection($sDates)
{
foreach ($sDates as $sDate) {
if ($this->year == $sDate->thisYear()
&& $this->month == $sDate->thisMonth()
) {
$key = $sDate->thisDay();
if (isset($this->children[$key])) {
$sDate->setSelected();
$class = strtolower(get_class($sDate));
if ($class == 'calendar_day' || $class == 'calendar_decorator') {
$sDate->setFirst($this->children[$key]->isFirst());
$sDate->setLast($this->children[$key]->isLast());
}
$this->children[$key] = $sDate;
}
}
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Validator.php
New file
0,0 → 1,335
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Validator.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Validator.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
*/
 
/**
* Validation Error Messages
*/
if (!defined('CALENDAR_VALUE_TOOSMALL')) {
define('CALENDAR_VALUE_TOOSMALL', 'Too small: min = ');
}
if (!defined('CALENDAR_VALUE_TOOLARGE')) {
define('CALENDAR_VALUE_TOOLARGE', 'Too large: max = ');
}
 
/**
* Used to validate any given Calendar date object. Instances of this class
* can be obtained from any data object using the getValidator method
* @see Calendar::getValidator()
* @package Calendar
* @access public
*/
class Calendar_Validator
{
/**
* Instance of the Calendar date object to validate
* @var object
* @access private
*/
var $calendar;
 
/**
* Instance of the Calendar_Engine
* @var object
* @access private
*/
var $cE;
 
/**
* Array of errors for validation failures
* @var array
* @access private
*/
var $errors = array();
 
/**
* Constructs Calendar_Validator
* @param object subclass of Calendar
* @access public
*/
function Calendar_Validator(& $calendar)
{
$this->calendar = & $calendar;
$this->cE = & $calendar->getEngine();
}
 
/**
* Calls all the other isValidXXX() methods in the validator
* @return boolean
* @access public
*/
function isValid()
{
$checks = array('isValidYear', 'isValidMonth', 'isValidDay',
'isValidHour', 'isValidMinute', 'isValidSecond');
$valid = true;
foreach ($checks as $check) {
if (!$this->{$check}()) {
$valid = false;
}
}
return $valid;
}
 
/**
* Check whether this is a valid year
* @return boolean
* @access public
*/
function isValidYear()
{
$y = $this->calendar->thisYear();
$min = $this->cE->getMinYears();
if ($min > $y) {
$this->errors[] = new Calendar_Validation_Error(
'Year', $y, CALENDAR_VALUE_TOOSMALL.$min);
return false;
}
$max = $this->cE->getMaxYears();
if ($y > $max) {
$this->errors[] = new Calendar_Validation_Error(
'Year', $y, CALENDAR_VALUE_TOOLARGE.$max);
return false;
}
return true;
}
 
/**
* Check whether this is a valid month
* @return boolean
* @access public
*/
function isValidMonth()
{
$m = $this->calendar->thisMonth();
$min = 1;
if ($min > $m) {
$this->errors[] = new Calendar_Validation_Error(
'Month', $m, CALENDAR_VALUE_TOOSMALL.$min);
return false;
}
$max = $this->cE->getMonthsInYear($this->calendar->thisYear());
if ($m > $max) {
$this->errors[] = new Calendar_Validation_Error(
'Month', $m, CALENDAR_VALUE_TOOLARGE.$max);
return false;
}
return true;
}
 
/**
* Check whether this is a valid day
* @return boolean
* @access public
*/
function isValidDay()
{
$d = $this->calendar->thisDay();
$min = 1;
if ($min > $d) {
$this->errors[] = new Calendar_Validation_Error(
'Day', $d, CALENDAR_VALUE_TOOSMALL.$min);
return false;
}
$max = $this->cE->getDaysInMonth(
$this->calendar->thisYear(), $this->calendar->thisMonth());
if ($d > $max) {
$this->errors[] = new Calendar_Validation_Error(
'Day', $d, CALENDAR_VALUE_TOOLARGE.$max);
return false;
}
return true;
}
 
/**
* Check whether this is a valid hour
* @return boolean
* @access public
*/
function isValidHour()
{
$h = $this->calendar->thisHour();
$min = 0;
if ($min > $h) {
$this->errors[] = new Calendar_Validation_Error(
'Hour', $h, CALENDAR_VALUE_TOOSMALL.$min);
return false;
}
$max = ($this->cE->getHoursInDay($this->calendar->thisDay())-1);
if ($h > $max) {
$this->errors[] = new Calendar_Validation_Error(
'Hour', $h, CALENDAR_VALUE_TOOLARGE.$max);
return false;
}
return true;
}
 
/**
* Check whether this is a valid minute
* @return boolean
* @access public
*/
function isValidMinute()
{
$i = $this->calendar->thisMinute();
$min = 0;
if ($min > $i) {
$this->errors[] = new Calendar_Validation_Error(
'Minute', $i, CALENDAR_VALUE_TOOSMALL.$min);
return false;
}
$max = ($this->cE->getMinutesInHour($this->calendar->thisHour())-1);
if ($i > $max) {
$this->errors[] = new Calendar_Validation_Error(
'Minute', $i, CALENDAR_VALUE_TOOLARGE.$max);
return false;
}
return true;
}
 
/**
* Check whether this is a valid second
* @return boolean
* @access public
*/
function isValidSecond()
{
$s = $this->calendar->thisSecond();
$min = 0;
if ($min > $s) {
$this->errors[] = new Calendar_Validation_Error(
'Second', $s, CALENDAR_VALUE_TOOSMALL.$min);
return false;
}
$max = ($this->cE->getSecondsInMinute($this->calendar->thisMinute())-1);
if ($s > $max) {
$this->errors[] = new Calendar_Validation_Error(
'Second', $s, CALENDAR_VALUE_TOOLARGE.$max);
return false;
}
return true;
}
 
/**
* Iterates over any validation errors
* @return mixed either Calendar_Validation_Error or false
* @access public
*/
function fetch()
{
$error = each ($this->errors);
if ($error) {
return $error['value'];
} else {
reset($this->errors);
return false;
}
}
}
 
/**
* For Validation Error messages
* @see Calendar::fetch()
* @package Calendar
* @access public
*/
class Calendar_Validation_Error
{
/**
* Date unit (e.g. month,hour,second) which failed test
* @var string
* @access private
*/
var $unit;
 
/**
* Value of unit which failed test
* @var int
* @access private
*/
var $value;
 
/**
* Validation error message
* @var string
* @access private
*/
var $message;
 
/**
* Constructs Calendar_Validation_Error
* @param string Date unit (e.g. month,hour,second)
* @param int Value of unit which failed test
* @param string Validation error message
* @access protected
*/
function Calendar_Validation_Error($unit,$value,$message)
{
$this->unit = $unit;
$this->value = $value;
$this->message = $message;
}
 
/**
* Returns the Date unit
* @return string
* @access public
*/
function getUnit()
{
return $this->unit;
}
 
/**
* Returns the value of the unit
* @return int
* @access public
*/
function getValue()
{
return $this->value;
}
 
/**
* Returns the validation error message
* @return string
* @access public
*/
function getMessage()
{
return $this->message;
}
 
/**
* Returns a string containing the unit, value and error message
* @return string
* @access public
*/
function toString ()
{
return $this->unit.' = '.$this->value.' ['.$this->message.']';
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Util/Uri.php
New file
0,0 → 1,169
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: Uri.php,v 1.1 2004/08/16 09:03:55 hfuecks Exp $
//
/**
* @package Calendar
* @version $Id: Uri.php,v 1.1 2004/08/16 09:03:55 hfuecks Exp $
*/
 
/**
* Utility to help building HTML links for navigating the calendar<br />
* <code>
* $Day = new Calendar_Day(2003, 10, 23);
* $Uri = & new Calendar_Util_Uri('year', 'month', 'day');
* echo $Uri->prev($Day,'month'); // Displays year=2003&amp;month=10
* echo $Uri->prev($Day,'day'); // Displays year=2003&amp;month=10&amp;day=22
* $Uri->seperator = '/';
* $Uri->scalar = true;
* echo $Uri->prev($Day,'month'); // Displays 2003/10
* echo $Uri->prev($Day,'day'); // Displays 2003/10/22
* </code>
* @package Calendar
* @access public
*/
class Calendar_Util_Uri
{
/**
* Uri fragments for year, month, day etc.
* @var array
* @access private
*/
var $uris = array();
 
/**
* String to separate fragments with.
* Set to just & for HTML.
* For a scalar URL you might use / as the seperator
* @var string (default XHTML &amp;)
* @access public
*/
var $separator = '&amp;';
 
/**
* To output a "scalar" string - variable names omitted.
* Used for urls like index.php/2004/8/12
* @var boolean (default false)
* @access public
*/
var $scalar = false;
 
/**
* Constructs Calendar_Decorator_Uri
* The term "fragment" means <i>name</i> of a calendar GET variables in the URL
* @param string URI fragment for year
* @param string (optional) URI fragment for month
* @param string (optional) URI fragment for day
* @param string (optional) URI fragment for hour
* @param string (optional) URI fragment for minute
* @param string (optional) URI fragment for second
* @access public
*/
function Calendar_Util_Uri($y, $m=null, $d=null, $h=null, $i=null, $s=null)
{
$this->setFragments($y, $m, $d, $h, $i, $s);
}
 
/**
* Sets the URI fragment names
* @param string URI fragment for year
* @param string (optional) URI fragment for month
* @param string (optional) URI fragment for day
* @param string (optional) URI fragment for hour
* @param string (optional) URI fragment for minute
* @param string (optional) URI fragment for second
* @return void
* @access public
*/
function setFragments($y, $m=null, $d=null, $h=null, $i=null, $s=null) {
if (!is_null($y)) $this->uris['Year'] = $y;
if (!is_null($m)) $this->uris['Month'] = $m;
if (!is_null($d)) $this->uris['Day'] = $d;
if (!is_null($h)) $this->uris['Hour'] = $h;
if (!is_null($i)) $this->uris['Minute'] = $i;
if (!is_null($s)) $this->uris['Second'] = $s;
}
 
/**
* Gets the URI string for the previous calendar unit
* @param object subclassed from Calendar e.g. Calendar_Month
* @param string calendar unit ( must be year, month, week, day, hour, minute or second)
* @return string
* @access public
*/
function prev($Calendar, $unit)
{
$method = 'prev'.$unit;
$stamp = $Calendar->{$method}('timestamp');
return $this->buildUriString($Calendar, $method, $stamp);
}
 
/**
* Gets the URI string for the current calendar unit
* @param object subclassed from Calendar e.g. Calendar_Month
* @param string calendar unit ( must be year, month, week, day, hour, minute or second)
* @return string
* @access public
*/
function this($Calendar, $unit)
{
$method = 'this'.$unit;
$stamp = $Calendar->{$method}('timestamp');
return $this->buildUriString($Calendar, $method, $stamp);
}
 
/**
* Gets the URI string for the next calendar unit
* @param object subclassed from Calendar e.g. Calendar_Month
* @param string calendar unit ( must be year, month, week, day, hour, minute or second)
* @return string
* @access public
*/
function next($Calendar, $unit)
{
$method = 'next'.$unit;
$stamp = $Calendar->{$method}('timestamp');
return $this->buildUriString($Calendar, $method, $stamp);
}
 
/**
* Build the URI string
* @param string method substring
* @param int timestamp
* @return string build uri string
* @access private
*/
function buildUriString($Calendar, $method, $stamp)
{
$uriString = '';
$cE = & $Calendar->getEngine();
$separator = '';
foreach ($this->uris as $unit => $uri) {
$call = 'stampTo'.$unit;
$uriString .= $separator;
if (!$this->scalar) $uriString .= $uri.'=';
$uriString .= $cE->{$call}($stamp);
$separator = $this->separator;
}
return $uriString;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Util/Textual.php
New file
0,0 → 1,239
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: Textual.php,v 1.2 2004/08/16 13:13:09 hfuecks Exp $
//
/**
* @package Calendar
* @version $Id: Textual.php,v 1.2 2004/08/16 13:13:09 hfuecks Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar decorator base class
*/
require_once CALENDAR_ROOT.'Decorator.php';
 
/**
* Static utlities to help with fetching textual representations of months and
* days of the week.
* @package Calendar
* @access public
*/
class Calendar_Util_Textual
{
 
/**
* Returns an array of 12 month names (first index = 1)
* @param string (optional) format of returned months (one,two,short or long)
* @return array
* @access public
* @static
*/
function monthNames($format='long')
{
$formats = array('one'=>'%b', 'two'=>'%b', 'short'=>'%b', 'long'=>'%B');
if (!array_key_exists($format,$formats)) {
$format = 'long';
}
$months = array();
for ($i=1; $i<=12; $i++) {
$stamp = mktime(0, 0, 0, $i, 1, 2003);
$month = strftime($formats[$format], $stamp);
switch($format) {
case 'one':
$month = substr($month, 0, 1);
break;
case 'two':
$month = substr($month, 0, 2);
break;
}
$months[$i] = $month;
}
return $months;
}
 
/**
* Returns an array of 7 week day names (first index = 0)
* @param string (optional) format of returned days (one,two,short or long)
* @return array
* @access public
* @static
*/
function weekdayNames($format='long')
{
$formats = array('one'=>'%a', 'two'=>'%a', 'short'=>'%a', 'long'=>'%A');
if (!array_key_exists($format,$formats)) {
$format = 'long';
}
$days = array();
for ($i=0; $i<=6; $i++) {
$stamp = mktime(0, 0, 0, 11, $i+2, 2003);
$day = strftime($formats[$format], $stamp);
switch($format) {
case 'one':
$day = substr($day, 0, 1);
break;
case 'two':
$day = substr($day, 0, 2);
break;
}
$days[$i] = $day;
}
return $days;
}
 
/**
* Returns textual representation of the previous month of the decorated calendar object
* @param object subclass of Calendar e.g. Calendar_Month
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
* @static
*/
function prevMonthName($Calendar, $format='long')
{
$months = Calendar_Util_Textual::monthNames($format);
return $months[$Calendar->prevMonth()];
}
 
/**
* Returns textual representation of the month of the decorated calendar object
* @param object subclass of Calendar e.g. Calendar_Month
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
* @static
*/
function thisMonthName($Calendar, $format='long')
{
$months = Calendar_Util_Textual::monthNames($format);
return $months[$Calendar->thisMonth()];
}
 
/**
* Returns textual representation of the next month of the decorated calendar object
* @param object subclass of Calendar e.g. Calendar_Month
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
* @static
*/
function nextMonthName($Calendar, $format='long')
{
$months = Calendar_Util_Textual::monthNames($format);
return $months[$Calendar->nextMonth()];
}
 
/**
* Returns textual representation of the previous day of week of the decorated calendar object
* <b>Note:</b> Requires PEAR::Date
* @param object subclass of Calendar e.g. Calendar_Month
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
* @static
*/
function prevDayName($Calendar, $format='long')
{
$days = Calendar_Util_Textual::weekdayNames($format);
$stamp = $Calendar->prevDay('timestamp');
$cE = $Calendar->getEngine();
require_once 'Date/Calc.php';
$day = Date_Calc::dayOfWeek($cE->stampToDay($stamp),
$cE->stampToMonth($stamp), $cE->stampToYear($stamp));
return $days[$day];
}
 
/**
* Returns textual representation of the day of week of the decorated calendar object
* <b>Note:</b> Requires PEAR::Date
* @param object subclass of Calendar e.g. Calendar_Month
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
* @static
*/
function thisDayName($Calendar, $format='long')
{
$days = Calendar_Util_Textual::weekdayNames($format);
require_once 'Date/Calc.php';
$day = Date_Calc::dayOfWeek($Calendar->thisDay(), $Calendar->thisMonth(), $Calendar->thisYear());
return $days[$day];
}
 
/**
* Returns textual representation of the next day of week of the decorated calendar object
* @param object subclass of Calendar e.g. Calendar_Month
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
* @static
*/
function nextDayName($Calendar, $format='long')
{
$days = Calendar_Util_Textual::weekdayNames($format);
$stamp = $Calendar->nextDay('timestamp');
$cE = $Calendar->getEngine();
require_once 'Date/Calc.php';
$day = Date_Calc::dayOfWeek($cE->stampToDay($stamp),
$cE->stampToMonth($stamp), $cE->stampToYear($stamp));
return $days[$day];
}
 
/**
* Returns the days of the week using the order defined in the decorated
* calendar object. Only useful for Calendar_Month_Weekdays, Calendar_Month_Weeks
* and Calendar_Week. Otherwise the returned array will begin on Sunday
* @param object subclass of Calendar e.g. Calendar_Month
* @param string (optional) format of returned months (one,two,short or long)
* @return array ordered array of week day names
* @access public
* @static
*/
function orderedWeekdays($Calendar, $format='long')
{
$days = Calendar_Util_Textual::weekdayNames($format);
// Not so good - need methods to access this information perhaps...
if (isset($Calendar->tableHelper)) {
$ordereddays = $Calendar->tableHelper->daysOfWeek;
} else {
$ordereddays = array(0, 1, 2, 3, 4, 5, 6);
}
$ordereddays = array_flip($ordereddays);
$i = 0;
$returndays = array();
foreach ($ordereddays as $key => $value) {
$returndays[$i] = $days[$key];
$i++;
}
return $returndays;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Week.php
New file
0,0 → 1,394
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: Week.php,v 1.7 2005/10/22 10:26:49 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Week.php,v 1.7 2005/10/22 10:26:49 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar base class
*/
require_once CALENDAR_ROOT.'Calendar.php';
 
/**
* Represents a Week and builds Days in tabular format<br>
* <code>
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Week.php';
* $Week = & new Calendar_Week(2003, 10, 1); Oct 2003, 1st tabular week
* echo '<tr>';
* while ($Day = & $Week->fetch()) {
* if ($Day->isEmpty()) {
* echo '<td>&nbsp;</td>';
* } else {
* echo '<td>'.$Day->thisDay().'</td>';
* }
* }
* echo '</tr>';
* </code>
* @package Calendar
* @access public
*/
class Calendar_Week extends Calendar
{
/**
* Instance of Calendar_Table_Helper
* @var Calendar_Table_Helper
* @access private
*/
var $tableHelper;
 
/**
* Stores the timestamp of the first day of this week
* @access private
* @var object
*/
var $thisWeek;
 
/**
* Stores the timestamp of first day of previous week
* @access private
* @var object
*/
var $prevWeek;
 
/**
* Stores the timestamp of first day of next week
* @access private
* @var object
*/
var $nextWeek;
 
/**
* Used by build() to set empty days
* @access private
* @var boolean
*/
var $firstWeek = false;
 
/**
* Used by build() to set empty days
* @access private
* @var boolean
*/
var $lastWeek = false;
 
/**
* First day of the week (0=sunday, 1=monday...)
* @access private
* @var boolean
*/
var $firstDay = 1;
 
/**
* Constructs Week
* @param int year e.g. 2003
* @param int month e.g. 5
* @param int a day of the desired week
* @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.)
* @access public
*/
function Calendar_Week($y, $m, $d, $firstDay=null)
{
require_once CALENDAR_ROOT.'Table/Helper.php';
Calendar::Calendar($y, $m, $d);
$this->firstDay = $this->defineFirstDayOfWeek($firstDay);
$this->tableHelper = new Calendar_Table_Helper($this, $this->firstDay);
$this->thisWeek = $this->tableHelper->getWeekStart($y, $m, $d, $this->firstDay);
$this->prevWeek = $this->tableHelper->getWeekStart($y, $m, $d - $this->cE->getDaysInWeek(
$this->thisYear(),
$this->thisMonth(),
$this->thisDay()), $this->firstDay);
$this->nextWeek = $this->tableHelper->getWeekStart($y, $m, $d + $this->cE->getDaysInWeek(
$this->thisYear(),
$this->thisMonth(),
$this->thisDay()), $this->firstDay);
}
 
/**
* Defines the calendar by a timestamp (Unix or ISO-8601), replacing values
* passed to the constructor
* @param int|string Unix or ISO-8601 timestamp
* @return void
* @access public
*/
function setTimestamp($ts)
{
parent::setTimestamp($ts);
$this->thisWeek = $this->tableHelper->getWeekStart(
$this->year, $this->month, $this->day, $this->firstDay
);
$this->prevWeek = $this->tableHelper->getWeekStart(
$this->year, $this->month, $this->day - $this->cE->getDaysInWeek(
$this->thisYear(),
$this->thisMonth(),
$this->thisDay()), $this->firstDay
);
$this->nextWeek = $this->tableHelper->getWeekStart(
$this->year, $this->month, $this->day + $this->cE->getDaysInWeek(
$this->thisYear(),
$this->thisMonth(),
$this->thisDay()), $this->firstDay
);
}
 
/**
* Builds Calendar_Day objects for this Week
* @param array (optional) Calendar_Day objects representing selected dates
* @return boolean
* @access public
*/
function build($sDates = array())
{
require_once CALENDAR_ROOT.'Day.php';
$year = $this->cE->stampToYear($this->thisWeek);
$month = $this->cE->stampToMonth($this->thisWeek);
$day = $this->cE->stampToDay($this->thisWeek);
$end = $this->cE->getDaysInWeek(
$this->thisYear(),
$this->thisMonth(),
$this->thisDay()
);
 
for ($i=1; $i <= $end; $i++) {
$stamp = $this->cE->dateToStamp($year, $month, $day++);
$this->children[$i] = new Calendar_Day(
$this->cE->stampToYear($stamp),
$this->cE->stampToMonth($stamp),
$this->cE->stampToDay($stamp));
}
 
//set empty days (@see Calendar_Month_Weeks::build())
if ($this->firstWeek) {
$eBefore = $this->tableHelper->getEmptyDaysBefore();
for ($i=1; $i <= $eBefore; $i++) {
$this->children[$i]->setEmpty();
}
}
if ($this->lastWeek) {
$eAfter = $this->tableHelper->getEmptyDaysAfterOffset();
for ($i = $eAfter+1; $i <= $end; $i++) {
$this->children[$i]->setEmpty();
}
}
 
if (count($sDates) > 0) {
$this->setSelection($sDates);
}
return true;
}
 
/**
* @param boolean
* @return void
* @access private
*/
function setFirst($state=true)
{
$this->firstWeek = $state;
}
 
/**
* @param boolean
* @return void
* @access private
*/
function setLast($state=true)
{
$this->lastWeek = $state;
}
 
/**
* Called from build()
* @param array
* @return void
* @access private
*/
function setSelection($sDates)
{
foreach ($sDates as $sDate) {
foreach ($this->children as $key => $child) {
if ($child->thisDay() == $sDate->thisDay() &&
$child->thisMonth() == $sDate->thisMonth() &&
$child->thisYear() == $sDate->thisYear()
) {
$this->children[$key] = $sDate;
$this->children[$key]->setSelected();
}
}
}
reset($this->children);
}
 
/**
* Gets the value of the previous week, according to the requested format
*
* @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array']
* @return mixed
* @access public
*/
function prevWeek($format = 'n_in_month')
{
switch (strtolower($format)) {
case 'int':
case 'n_in_month':
return ($this->firstWeek) ? null : $this->thisWeek('n_in_month') -1;
break;
case 'n_in_year':
return $this->cE->getWeekNInYear(
$this->cE->stampToYear($this->prevWeek),
$this->cE->stampToMonth($this->prevWeek),
$this->cE->stampToDay($this->prevWeek));
break;
case 'array':
return $this->toArray($this->prevWeek);
break;
case 'object':
require_once CALENDAR_ROOT.'Factory.php';
return Calendar_Factory::createByTimestamp('Week', $this->prevWeek);
break;
case 'timestamp':
default:
return $this->prevWeek;
break;
}
}
 
/**
* Gets the value of the current week, according to the requested format
*
* @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array']
* @return mixed
* @access public
*/
function thisWeek($format = 'n_in_month')
{
switch (strtolower($format)) {
case 'int':
case 'n_in_month':
if ($this->firstWeek) {
return 1;
}
if ($this->lastWeek) {
return $this->cE->getWeeksInMonth(
$this->thisYear(),
$this->thisMonth(),
$this->firstDay);
}
return $this->cE->getWeekNInMonth(
$this->thisYear(),
$this->thisMonth(),
$this->thisDay(),
$this->firstDay);
break;
case 'n_in_year':
return $this->cE->getWeekNInYear(
$this->cE->stampToYear($this->thisWeek),
$this->cE->stampToMonth($this->thisWeek),
$this->cE->stampToDay($this->thisWeek));
break;
case 'array':
return $this->toArray($this->thisWeek);
break;
case 'object':
require_once CALENDAR_ROOT.'Factory.php';
return Calendar_Factory::createByTimestamp('Week', $this->thisWeek);
break;
case 'timestamp':
default:
return $this->thisWeek;
break;
}
}
 
/**
* Gets the value of the following week, according to the requested format
*
* @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array']
* @return mixed
* @access public
*/
function nextWeek($format = 'n_in_month')
{
switch (strtolower($format)) {
case 'int':
case 'n_in_month':
return ($this->lastWeek) ? null : $this->thisWeek('n_in_month') +1;
break;
case 'n_in_year':
return $this->cE->getWeekNInYear(
$this->cE->stampToYear($this->nextWeek),
$this->cE->stampToMonth($this->nextWeek),
$this->cE->stampToDay($this->nextWeek));
break;
case 'array':
return $this->toArray($this->nextWeek);
break;
case 'object':
require_once CALENDAR_ROOT.'Factory.php';
return Calendar_Factory::createByTimestamp('Week', $this->nextWeek);
break;
case 'timestamp':
default:
return $this->nextWeek;
break;
}
}
 
/**
* Returns the instance of Calendar_Table_Helper.
* Called from Calendar_Validator::isValidWeek
* @return Calendar_Table_Helper
* @access protected
*/
function & getHelper()
{
return $this->tableHelper;
}
 
/**
* Makes sure theres a value for $this->day
* @return void
* @access private
*/
function findFirstDay()
{
if (!count($this->children) > 0) {
$this->build();
foreach ($this->children as $Day) {
if (!$Day->isEmpty()) {
$this->day = $Day->thisDay();
break;
}
}
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Decorator/Uri.php
New file
0,0 → 1,151
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: Uri.php,v 1.3 2004/08/16 09:04:20 hfuecks Exp $
//
/**
* @package Calendar
* @version $Id: Uri.php,v 1.3 2004/08/16 09:04:20 hfuecks Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar decorator base class
*/
require_once CALENDAR_ROOT.'Decorator.php';
 
/**
* Load the Uri utility
*/
require_once CALENDAR_ROOT.'Util'.DIRECTORY_SEPARATOR.'Uri.php';
 
/**
* Decorator to help with building HTML links for navigating the calendar<br />
* <b>Note:</b> for performance you should prefer Calendar_Util_Uri unless you
* have a specific need to use a decorator
* <code>
* $Day = new Calendar_Day(2003, 10, 23);
* $Uri = & new Calendar_Decorator_Uri($Day);
* $Uri->setFragments('year', 'month', 'day');
* echo $Uri->getPrev(); // Displays year=2003&month=10&day=22
* </code>
* @see Calendar_Util_Uri
* @package Calendar
* @access public
*/
class Calendar_Decorator_Uri extends Calendar_Decorator
{
 
/**
* @var Calendar_Util_Uri
* @access private
*/
var $Uri;
 
/**
* Constructs Calendar_Decorator_Uri
* @param object subclass of Calendar
* @access public
*/
function Calendar_Decorator_Uri(&$Calendar)
{
parent::Calendar_Decorator($Calendar);
}
 
/**
* Sets the URI fragment names
* @param string URI fragment for year
* @param string (optional) URI fragment for month
* @param string (optional) URI fragment for day
* @param string (optional) URI fragment for hour
* @param string (optional) URI fragment for minute
* @param string (optional) URI fragment for second
* @return void
* @access public
*/
function setFragments($y, $m=null, $d=null, $h=null, $i=null, $s=null) {
$this->Uri = & new Calendar_Util_Uri($y, $m, $d, $h, $i, $s);
}
 
/**
* Sets the separator string between fragments
* @param string separator e.g. /
* @return void
* @access public
*/
function setSeparator($separator)
{
$this->Uri->separator = $separator;
}
 
/**
* Puts Uri decorator into "scalar mode" - URI variable names are not
* returned
* @param boolean (optional)
* @return void
* @access public
*/
function setScalar($state=true)
{
$this->Uri->scalar = $state;
}
 
/**
* Gets the URI string for the previous calendar unit
* @param string calendar unit to fetch uri for (year,month,week or day etc)
* @return string
* @access public
*/
function prev($method)
{
return $this->Uri->prev($this, $method);
}
 
/**
* Gets the URI string for the current calendar unit
* @param string calendar unit to fetch uri for (year,month,week or day etc)
* @return string
* @access public
*/
function this($method)
{
return $this->Uri->this($this, $method);
}
 
/**
* Gets the URI string for the next calendar unit
* @param string calendar unit to fetch uri for (year,month,week or day etc)
* @return string
* @access public
*/
function next($method)
{
return $this->Uri->next($this, $method);
}
 
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Decorator/Wrapper.php
New file
0,0 → 1,90
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: Wrapper.php,v 1.2 2005/11/03 20:35:03 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Wrapper.php,v 1.2 2005/11/03 20:35:03 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar decorator base class
*/
require_once CALENDAR_ROOT.'Decorator.php';
 
/**
* Decorator to help with wrapping built children in another decorator
* @package Calendar
* @access public
*/
class Calendar_Decorator_Wrapper extends Calendar_Decorator
{
/**
* Constructs Calendar_Decorator_Wrapper
* @param object subclass of Calendar
* @access public
*/
function Calendar_Decorator_Wrapper(&$Calendar)
{
parent::Calendar_Decorator($Calendar);
}
 
/**
* Wraps objects returned from fetch in the named Decorator class
* @param string name of Decorator class to wrap with
* @return object instance of named decorator
* @access public
*/
function & fetch($decorator)
{
$Calendar = parent::fetch();
if ($Calendar) {
$ret =& new $decorator($Calendar);
} else {
$ret = false;
}
return $ret;
}
 
/**
* Wraps the returned calendar objects from fetchAll in the named decorator
* @param string name of Decorator class to wrap with
* @return array
* @access public
*/
function fetchAll($decorator)
{
$children = parent::fetchAll();
foreach ($children as $key => $Calendar) {
$children[$key] = & new $decorator($Calendar);
}
return $children;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Decorator/Textual.php
New file
0,0 → 1,169
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: Textual.php,v 1.3 2004/08/16 13:02:44 hfuecks Exp $
//
/**
* @package Calendar
* @version $Id: Textual.php,v 1.3 2004/08/16 13:02:44 hfuecks Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar decorator base class
*/
require_once CALENDAR_ROOT.'Decorator.php';
 
/**
* Load the Uri utility
*/
require_once CALENDAR_ROOT.'Util'.DIRECTORY_SEPARATOR.'Textual.php';
 
/**
* Decorator to help with fetching textual representations of months and
* days of the week.
* <b>Note:</b> for performance you should prefer Calendar_Util_Textual unless you
* have a specific need to use a decorator
* @package Calendar
* @access public
*/
class Calendar_Decorator_Textual extends Calendar_Decorator
{
/**
* Constructs Calendar_Decorator_Textual
* @param object subclass of Calendar
* @access public
*/
function Calendar_Decorator_Textual(&$Calendar)
{
parent::Calendar_Decorator($Calendar);
}
 
/**
* Returns an array of 12 month names (first index = 1)
* @param string (optional) format of returned months (one,two,short or long)
* @return array
* @access public
* @static
*/
function monthNames($format='long')
{
return Calendar_Util_Textual::monthNames($format);
}
 
/**
* Returns an array of 7 week day names (first index = 0)
* @param string (optional) format of returned days (one,two,short or long)
* @return array
* @access public
* @static
*/
function weekdayNames($format='long')
{
return Calendar_Util_Textual::weekdayNames($format);
}
 
/**
* Returns textual representation of the previous month of the decorated calendar object
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
*/
function prevMonthName($format='long')
{
return Calendar_Util_Textual::prevMonthName($this->calendar,$format);
}
 
/**
* Returns textual representation of the month of the decorated calendar object
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
*/
function thisMonthName($format='long')
{
return Calendar_Util_Textual::thisMonthName($this->calendar,$format);
}
 
/**
* Returns textual representation of the next month of the decorated calendar object
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
*/
function nextMonthName($format='long')
{
return Calendar_Util_Textual::nextMonthName($this->calendar,$format);
}
 
/**
* Returns textual representation of the previous day of week of the decorated calendar object
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
*/
function prevDayName($format='long')
{
return Calendar_Util_Textual::prevDayName($this->calendar,$format);
}
 
/**
* Returns textual representation of the day of week of the decorated calendar object
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
*/
function thisDayName($format='long')
{
return Calendar_Util_Textual::thisDayName($this->calendar,$format);
}
 
/**
* Returns textual representation of the next day of week of the decorated calendar object
* @param string (optional) format of returned months (one,two,short or long)
* @return string
* @access public
*/
function nextDayName($format='long')
{
return Calendar_Util_Textual::nextDayName($this->calendar,$format);
}
 
/**
* Returns the days of the week using the order defined in the decorated
* calendar object. Only useful for Calendar_Month_Weekdays, Calendar_Month_Weeks
* and Calendar_Week. Otherwise the returned array will begin on Sunday
* @param string (optional) format of returned months (one,two,short or long)
* @return array ordered array of week day names
* @access public
*/
function orderedWeekdays($format='long')
{
return Calendar_Util_Textual::orderedWeekdays($this->calendar,$format);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Decorator/Weekday.php
New file
0,0 → 1,148
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: Weekday.php,v 1.3 2004/08/16 12:25:15 hfuecks Exp $
//
/**
* @package Calendar
* @version $Id: Weekday.php,v 1.3 2004/08/16 12:25:15 hfuecks Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar decorator base class
*/
require_once CALENDAR_ROOT.'Decorator.php';
 
/**
* Load a Calendar_Day
*/
require_once CALENDAR_ROOT.'Day.php';
/**
* Decorator for fetching the day of the week
* <code>
* $Day = new Calendar_Day(2003, 10, 23);
* $Weekday = & new Calendar_Decorator_Weekday($Day);
* $Weekday->setFirstDay(0); // Set first day of week to Sunday (default Mon)
* echo $Weekday->thisWeekDay(); // Displays 5 - fifth day of week relative to Sun
* </code>
* @package Calendar
* @access public
*/
class Calendar_Decorator_Weekday extends Calendar_Decorator
{
/**
* First day of week
* @var int (default = 1 for Monday)
* @access private
*/
var $firstDay = 1;
 
/**
* Constructs Calendar_Decorator_Weekday
* @param object subclass of Calendar
* @access public
*/
function Calendar_Decorator_Weekday(& $Calendar)
{
parent::Calendar_Decorator($Calendar);
}
 
/**
* Sets the first day of the week (0 = Sunday, 1 = Monday (default) etc)
* @param int first day of week
* @return void
* @access public
*/
function setFirstDay($firstDay) {
$this->firstDay = (int)$firstDay;
}
 
/**
* Returns the previous weekday
* @param string (default = 'int') return value format
* @return int numeric day of week or timestamp
* @access public
*/
function prevWeekDay($format = 'int')
{
$ts = $this->calendar->prevDay('timestamp');
$Day = new Calendar_Day(2000,1,1);
$Day->setTimeStamp($ts);
$day = $this->calendar->cE->getDayOfWeek($Day->thisYear(),$Day->thisMonth(),$Day->thisDay());
$day = $this->adjustWeekScale($day);
return $this->returnValue('Day', $format, $ts, $day);
}
 
/**
* Returns the current weekday
* @param string (default = 'int') return value format
* @return int numeric day of week or timestamp
* @access public
*/
function thisWeekDay($format = 'int')
{
$ts = $this->calendar->thisDay('timestamp');
$day = $this->calendar->cE->getDayOfWeek($this->calendar->year,$this->calendar->month,$this->calendar->day);
$day = $this->adjustWeekScale($day);
return $this->returnValue('Day', $format, $ts, $day);
}
 
/**
* Returns the next weekday
* @param string (default = 'int') return value format
* @return int numeric day of week or timestamp
* @access public
*/
function nextWeekDay($format = 'int')
{
$ts = $this->calendar->nextDay('timestamp');
$Day = new Calendar_Day(2000,1,1);
$Day->setTimeStamp($ts);
$day = $this->calendar->cE->getDayOfWeek($Day->thisYear(),$Day->thisMonth(),$Day->thisDay());
$day = $this->adjustWeekScale($day);
return $this->returnValue('Day', $format, $ts, $day);
}
 
/**
* Adjusts the day of the week relative to the first day of the week
* @param int day of week calendar from Calendar_Engine
* @return int day of week adjusted to first day
* @access private
*/
function adjustWeekScale($dayOfWeek) {
$dayOfWeek = $dayOfWeek - $this->firstDay;
if ( $dayOfWeek >= 0 ) {
return $dayOfWeek;
} else {
return $this->calendar->cE->getDaysInWeek(
$this->calendar->year,$this->calendar->month,$this->calendar->day
) + $dayOfWeek;
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Month/Weekdays.php
New file
0,0 → 1,189
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Weekdays.php,v 1.4 2005/10/22 10:28:49 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Weekdays.php,v 1.4 2005/10/22 10:28:49 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar base class
*/
require_once CALENDAR_ROOT.'Calendar.php';
 
/**
* Load base month
*/
require_once CALENDAR_ROOT.'Month.php';
 
/**
* Represents a Month and builds Days in tabular form<br>
* <code>
* require_once 'Calendar/Month/Weekdays.php';
* $Month = & new Calendar_Month_Weekdays(2003, 10); // Oct 2003
* $Month->build(); // Build Calendar_Day objects
* while ($Day = & $Month->fetch()) {
* if ($Day->isFirst()) {
* echo '<tr>';
* }
* if ($Day->isEmpty()) {
* echo '<td>&nbsp;</td>';
* } else {
* echo '<td>'.$Day->thisDay().'</td>';
* }
* if ($Day->isLast()) {
* echo '</tr>';
* }
* }
* </code>
* @package Calendar
* @access public
*/
class Calendar_Month_Weekdays extends Calendar_Month
{
/**
* Instance of Calendar_Table_Helper
* @var Calendar_Table_Helper
* @access private
*/
var $tableHelper;
 
/**
* First day of the week
* @access private
* @var string
*/
var $firstDay;
 
/**
* Constructs Calendar_Month_Weekdays
* @param int year e.g. 2003
* @param int month e.g. 5
* @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.)
* @access public
*/
function Calendar_Month_Weekdays($y, $m, $firstDay=null)
{
Calendar_Month::Calendar_Month($y, $m, $firstDay);
}
 
/**
* Builds Day objects in tabular form, to allow display of calendar month
* with empty cells if the first day of the week does not fall on the first
* day of the month.
* @see Calendar_Day::isEmpty()
* @see Calendar_Day_Base::isFirst()
* @see Calendar_Day_Base::isLast()
* @param array (optional) Calendar_Day objects representing selected dates
* @return boolean
* @access public
*/
function build($sDates=array())
{
require_once CALENDAR_ROOT.'Table/Helper.php';
$this->tableHelper = & new Calendar_Table_Helper($this, $this->firstDay);
Calendar_Month::build($sDates);
$this->buildEmptyDaysBefore();
$this->shiftDays();
$this->buildEmptyDaysAfter();
$this->setWeekMarkers();
return true;
}
 
/**
* Prepends empty days before the real days in the month
* @return void
* @access private
*/
function buildEmptyDaysBefore()
{
$eBefore = $this->tableHelper->getEmptyDaysBefore();
for ($i=0; $i < $eBefore; $i++) {
$stamp = $this->cE->dateToStamp($this->year, $this->month, -$i);
$Day = new Calendar_Day(
$this->cE->stampToYear($stamp),
$this->cE->stampToMonth($stamp),
$this->cE->stampToDay($stamp));
$Day->setEmpty();
$Day->adjust();
array_unshift($this->children, $Day);
}
}
 
/**
* Shifts the array of children forward, if necessary
* @return void
* @access private
*/
function shiftDays()
{
if (isset ($this->children[0])) {
array_unshift($this->children, null);
unset($this->children[0]);
}
}
 
/**
* Appends empty days after the real days in the month
* @return void
* @access private
*/
function buildEmptyDaysAfter()
{
$eAfter = $this->tableHelper->getEmptyDaysAfter();
$sDOM = $this->tableHelper->getNumTableDaysInMonth();
for ($i = 1; $i <= $sDOM-$eAfter; $i++) {
$Day = new Calendar_Day($this->year, $this->month+1, $i);
$Day->setEmpty();
$Day->adjust();
array_push($this->children, $Day);
}
}
 
/**
* Sets the "markers" for the beginning and of a of week, in the
* built Calendar_Day children
* @return void
* @access private
*/
function setWeekMarkers()
{
$dIW = $this->cE->getDaysInWeek(
$this->thisYear(),
$this->thisMonth(),
$this->thisDay()
);
$sDOM = $this->tableHelper->getNumTableDaysInMonth();
for ($i=1; $i <= $sDOM; $i+= $dIW) {
$this->children[$i]->setFirst();
$this->children[$i+($dIW-1)]->setLast();
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Month/Weeks.php
New file
0,0 → 1,139
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: Weeks.php,v 1.3 2005/10/22 10:28:49 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Weeks.php,v 1.3 2005/10/22 10:28:49 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar base class
*/
require_once CALENDAR_ROOT.'Calendar.php';
 
/**
* Load base month
*/
require_once CALENDAR_ROOT.'Month.php';
 
/**
* Represents a Month and builds Weeks
* <code>
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Month'.DIRECTORY_SEPARATOR.'Weeks.php';
* $Month = & new Calendar_Month_Weeks(2003, 10); // Oct 2003
* $Month->build(); // Build Calendar_Day objects
* while ($Week = & $Month->fetch()) {
* echo $Week->thisWeek().'<br />';
* }
* </code>
* @package Calendar
* @access public
*/
class Calendar_Month_Weeks extends Calendar_Month
{
/**
* Instance of Calendar_Table_Helper
* @var Calendar_Table_Helper
* @access private
*/
var $tableHelper;
 
/**
* First day of the week
* @access private
* @var string
*/
var $firstDay;
 
/**
* Constructs Calendar_Month_Weeks
* @param int year e.g. 2003
* @param int month e.g. 5
* @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.)
* @access public
*/
function Calendar_Month_Weeks($y, $m, $firstDay=null)
{
Calendar_Month::Calendar_Month($y, $m, $firstDay);
}
 
/**
* Builds Calendar_Week objects for the Month. Note that Calendar_Week
* builds Calendar_Day object in tabular form (with Calendar_Day->empty)
* @param array (optional) Calendar_Week objects representing selected dates
* @return boolean
* @access public
*/
function build($sDates=array())
{
require_once CALENDAR_ROOT.'Table/Helper.php';
$this->tableHelper = new Calendar_Table_Helper($this, $this->firstDay);
require_once CALENDAR_ROOT.'Week.php';
$numWeeks = $this->tableHelper->getNumWeeks();
for ($i=1, $d=1; $i<=$numWeeks; $i++,
$d+=$this->cE->getDaysInWeek(
$this->thisYear(),
$this->thisMonth(),
$this->thisDay()) ) {
$this->children[$i] = new Calendar_Week(
$this->year, $this->month, $d, $this->tableHelper->getFirstDay());
}
//used to set empty days
$this->children[1]->setFirst(true);
$this->children[$numWeeks]->setLast(true);
 
// Handle selected weeks here
if (count($sDates) > 0) {
$this->setSelection($sDates);
}
return true;
}
 
/**
* Called from build()
* @param array
* @return void
* @access private
*/
function setSelection($sDates)
{
foreach ($sDates as $sDate) {
if ($this->year == $sDate->thisYear()
&& $this->month == $sDate->thisMonth())
{
$key = $sDate->thisWeek('n_in_month');
if (isset($this->children[$key])) {
$this->children[$key]->setSelected();
}
}
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Year.php
New file
0,0 → 1,113
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Year.php,v 1.4 2005/10/22 10:25:39 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Year.php,v 1.4 2005/10/22 10:25:39 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar base class
*/
require_once CALENDAR_ROOT.'Calendar.php';
 
/**
* Represents a Year and builds Months<br>
* <code>
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Year.php';
* $Year = & new Calendar_Year(2003, 10, 21); // 21st Oct 2003
* $Year->build(); // Build Calendar_Month objects
* while ($Month = & $Year->fetch()) {
* echo $Month->thisMonth().'<br />';
* }
* </code>
* @package Calendar
* @access public
*/
class Calendar_Year extends Calendar
{
/**
* Constructs Calendar_Year
* @param int year e.g. 2003
* @access public
*/
function Calendar_Year($y)
{
Calendar::Calendar($y);
}
 
/**
* Builds the Months of the Year.<br>
* <b>Note:</b> by defining the constant CALENDAR_MONTH_STATE you can
* control what class of Calendar_Month is built e.g.;
* <code>
* require_once 'Calendar/Calendar_Year.php';
* define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKDAYS); // Use Calendar_Month_Weekdays
* // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKS); // Use Calendar_Month_Weeks
* // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH); // Use Calendar_Month
* </code>
* It defaults to building Calendar_Month objects.
* @param array (optional) array of Calendar_Month objects representing selected dates
* @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.)
* @return boolean
* @access public
*/
function build($sDates = array(), $firstDay = null)
{
require_once CALENDAR_ROOT.'Factory.php';
$this->firstDay = $this->defineFirstDayOfWeek($firstDay);
$monthsInYear = $this->cE->getMonthsInYear($this->thisYear());
for ($i=1; $i <= $monthsInYear; $i++) {
$this->children[$i] = Calendar_Factory::create('Month', $this->year, $i);
}
if (count($sDates) > 0) {
$this->setSelection($sDates);
}
return true;
}
 
/**
* Called from build()
* @param array
* @return void
* @access private
*/
function setSelection($sDates) {
foreach ($sDates as $sDate) {
if ($this->year == $sDate->thisYear()) {
$key = $sDate->thisMonth();
if (isset($this->children[$key])) {
$sDate->setSelected();
$this->children[$key] = $sDate;
}
}
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Minute.php
New file
0,0 → 1,114
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Minute.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Minute.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar base class
*/
require_once CALENDAR_ROOT.'Calendar.php';
 
/**
* Represents a Minute and builds Seconds
* <code>
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Minute.php';
* $Minute = & new Calendar_Minute(2003, 10, 21, 15, 31); // Oct 21st 2003, 3:31pm
* $Minute->build(); // Build Calendar_Second objects
* while ($Second = & $Minute->fetch()) {
* echo $Second->thisSecond().'<br />';
* }
* </code>
* @package Calendar
* @access public
*/
class Calendar_Minute extends Calendar
{
/**
* Constructs Minute
* @param int year e.g. 2003
* @param int month e.g. 5
* @param int day e.g. 11
* @param int hour e.g. 13
* @param int minute e.g. 31
* @access public
*/
function Calendar_Minute($y, $m, $d, $h, $i)
{
Calendar::Calendar($y, $m, $d, $h, $i);
}
 
/**
* Builds the Calendar_Second objects
* @param array (optional) Calendar_Second objects representing selected dates
* @return boolean
* @access public
*/
function build($sDates=array())
{
require_once CALENDAR_ROOT.'Second.php';
$sIM = $this->cE->getSecondsInMinute($this->year, $this->month,
$this->day, $this->hour, $this->minute);
for ($i=0; $i < $sIM; $i++) {
$this->children[$i] = new Calendar_Second($this->year, $this->month,
$this->day, $this->hour, $this->minute, $i);
}
if (count($sDates) > 0) {
$this->setSelection($sDates);
}
return true;
}
 
/**
* Called from build()
* @param array
* @return void
* @access private
*/
function setSelection($sDates)
{
foreach ($sDates as $sDate) {
if ($this->year == $sDate->thisYear()
&& $this->month == $sDate->thisMonth()
&& $this->day == $sDate->thisDay()
&& $this->hour == $sDate->thisHour()
&& $this->minute == $sDate->thisMinute())
{
$key = (int)$sDate->thisSecond();
if (isset($this->children[$key])) {
$sDate->setSelected();
$this->children[$key] = $sDate;
}
}
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Table/Helper.php
New file
0,0 → 1,280
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Helper.php,v 1.5 2005/10/22 09:51:53 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Helper.php,v 1.5 2005/10/22 09:51:53 quipo Exp $
*/
 
/**
* Used by Calendar_Month_Weekdays, Calendar_Month_Weeks and Calendar_Week to
* help with building the calendar in tabular form
* @package Calendar
* @access protected
*/
class Calendar_Table_Helper
{
/**
* Instance of the Calendar object being helped.
* @var object
* @access private
*/
var $calendar;
 
/**
* Instance of the Calendar_Engine
* @var object
* @access private
*/
var $cE;
 
/**
* First day of the week
* @access private
* @var string
*/
var $firstDay;
 
/**
* The seven days of the week named
* @access private
* @var array
*/
var $weekDays;
 
/**
* Days of the week ordered with $firstDay at the beginning
* @access private
* @var array
*/
var $daysOfWeek = array();
 
/**
* Days of the month built from days of the week
* @access private
* @var array
*/
var $daysOfMonth = array();
 
/**
* Number of weeks in month
* @var int
* @access private
*/
var $numWeeks = null;
 
/**
* Number of emtpy days before real days begin in month
* @var int
* @access private
*/
var $emptyBefore = 0;
 
/**
* Constructs Calendar_Table_Helper
* @param object Calendar_Month_Weekdays, Calendar_Month_Weeks, Calendar_Week
* @param int (optional) first day of the week e.g. 1 for Monday
* @access protected
*/
function Calendar_Table_Helper(& $calendar, $firstDay=null)
{
$this->calendar = & $calendar;
$this->cE = & $calendar->getEngine();
if (is_null($firstDay)) {
$firstDay = $this->cE->getFirstDayOfWeek(
$this->calendar->thisYear(),
$this->calendar->thisMonth(),
$this->calendar->thisDay()
);
}
$this->firstDay = $firstDay;
$this->setFirstDay();
$this->setDaysOfMonth();
}
 
/**
* Constructs $this->daysOfWeek based on $this->firstDay
* @return void
* @access private
*/
function setFirstDay()
{
$weekDays = $this->cE->getWeekDays(
$this->calendar->thisYear(),
$this->calendar->thisMonth(),
$this->calendar->thisDay()
);
$endDays = array();
$tmpDays = array();
$begin = false;
foreach ($weekDays as $day) {
if ($begin) {
$endDays[] = $day;
} else if ($day === $this->firstDay) {
$begin = true;
$endDays[] = $day;
} else {
$tmpDays[] = $day;
}
}
$this->daysOfWeek = array_merge($endDays, $tmpDays);
}
 
/**
* Constructs $this->daysOfMonth
* @return void
* @access private
*/
function setDaysOfMonth()
{
$this->daysOfMonth = $this->daysOfWeek;
$daysInMonth = $this->cE->getDaysInMonth(
$this->calendar->thisYear(), $this->calendar->thisMonth());
$firstDayInMonth = $this->cE->getFirstDayInMonth(
$this->calendar->thisYear(), $this->calendar->thisMonth());
$this->emptyBefore=0;
foreach ($this->daysOfMonth as $dayOfWeek) {
if ($firstDayInMonth == $dayOfWeek) {
break;
}
$this->emptyBefore++;
}
$this->numWeeks = ceil(
($daysInMonth + $this->emptyBefore)
/
$this->cE->getDaysInWeek(
$this->calendar->thisYear(),
$this->calendar->thisMonth(),
$this->calendar->thisDay()
)
);
for ($i=1; $i < $this->numWeeks; $i++) {
$this->daysOfMonth =
array_merge($this->daysOfMonth, $this->daysOfWeek);
}
}
 
/**
* Returns the first day of the month
* @see Calendar_Engine_Interface::getFirstDayOfWeek()
* @return int
* @access protected
*/
function getFirstDay()
{
return $this->firstDay;
}
 
/**
* Returns the order array of days in a week
* @return int
* @access protected
*/
function getDaysOfWeek()
{
return $this->daysOfWeek;
}
 
/**
* Returns the number of tabular weeks in a month
* @return int
* @access protected
*/
function getNumWeeks()
{
return $this->numWeeks;
}
 
/**
* Returns the number of real days + empty days
* @return int
* @access protected
*/
function getNumTableDaysInMonth()
{
return count($this->daysOfMonth);
}
 
/**
* Returns the number of empty days before the real days begin
* @return int
* @access protected
*/
function getEmptyDaysBefore()
{
return $this->emptyBefore;
}
 
/**
* Returns the index of the last real day in the month
* @todo Potential performance optimization with static
* @return int
* @access protected
*/
function getEmptyDaysAfter()
{
// Causes bug when displaying more than one month
// static $index;
// if (!isset($index)) {
$index = $this->getEmptyDaysBefore() + $this->cE->getDaysInMonth(
$this->calendar->thisYear(), $this->calendar->thisMonth());
// }
return $index;
}
 
/**
* Returns the index of the last real day in the month, relative to the
* beginning of the tabular week it is part of
* @return int
* @access protected
*/
function getEmptyDaysAfterOffset()
{
$eAfter = $this->getEmptyDaysAfter();
return $eAfter - (
$this->cE->getDaysInWeek(
$this->calendar->thisYear(),
$this->calendar->thisMonth(),
$this->calendar->thisDay()
) * ($this->numWeeks-1) );
}
 
/**
* Returns the timestamp of the first day of the current week
*/
function getWeekStart($y, $m, $d, $firstDay=1)
{
$dow = $this->cE->getDayOfWeek($y, $m, $d);
if ($dow > $firstDay) {
$d -= ($dow - $firstDay);
}
if ($dow < $firstDay) {
$d -= (
$this->cE->getDaysInWeek(
$this->calendar->thisYear(),
$this->calendar->thisMonth(),
$this->calendar->thisDay()
) - $firstDay + $dow);
}
return $this->cE->dateToStamp($y, $m, $d);
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/Readme
New file
0,0 → 1,3
Readme
 
See the PEAR manual at http://pear.php.net/manual/en/package.datetime.calendar.php for details.
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/4.phps
New file
0,0 → 1,49
<?php
/**
* Description: shows how to perform validation with PEAR::Calendar
*/
function getmicrotime(){
list($usec, $sec) = explode(' ', microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Second.php';
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('n');
if (!isset($_GET['d'])) $_GET['d'] = date('j');
if (!isset($_GET['h'])) $_GET['h'] = date('H');
if (!isset($_GET['i'])) $_GET['i'] = date('i');
if (!isset($_GET['s'])) $_GET['s'] = date('s');
 
$Unit = & new Calendar_Second($_GET['y'], $_GET['m'], $_GET['d'], $_GET['h'], $_GET['i'], $_GET['s']);
 
echo '<p><b>Result:</b> '.$Unit->thisYear().'-'.$Unit->thisMonth().'-'.$Unit->thisDay().
' '.$Unit->thisHour().':'.$Unit->thisMinute().':'.$Unit->thisSecond();
if ($Unit->isValid()) {
echo ' is valid!</p>';
} else {
$V= & $Unit->getValidator();
echo ' is invalid:</p>';
while ($error = $V->fetch()) {
echo $error->toString() .'<br />';
}
}
?>
<p>Enter a date / time to validate:</p>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
Year: <input type="text" name="y" value="2039"><br />
Month: <input type="text" name="m" value="13"><br />
Day: <input type="text" name="d" value="32"><br />
Hour: <input type="text" name="h" value="24"><br />
Minute: <input type="text" name="i" value="-1"><br />
Second: <input type="text" name="s" value="60"><br />
<input type="submit" value="Validate">
</form>
<p><b>Note:</b> Error messages can be controlled with the constants <code>CALENDAR_VALUE_TOOSMALL</code> and <code>CALENDAR_VALUE_TOOLARGE</code> - see <code>Calendar_Validator.php</code></p>
 
<?php echo '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>'; ?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/6.phps
New file
0,0 → 1,210
<?php
/**
* Description: A "personal planner" with some WML for fun
* Note this is done the stupid way - a giant if/else for WML or HTML
* could be greatly simplified with some HTML/WML rendering classes...
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Day.php';
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('n');
if (!isset($_GET['d'])) $_GET['d'] = date('j');
 
$Month = & new Calendar_Month_Weekdays($_GET['y'],$_GET['m']);
$Day = & new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']);
$selection = array($Day);
 
#-----------------------------------------------------------------------------#
if ( isset($_GET['mime']) && $_GET['mime']=='wml' ) {
header ('Content-Type: text/vnd.wap.wml');
echo ( '<?xml version="1.0"?>' );
?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<big><strong>Personal Planner Rendered with WML</strong></big>
<?php
if ( isset($_GET['viewday']) ) {
?>
<p><strong>Viewing <?php echo ( date('l, jS of F, Y',$Day->getTimeStamp()) ); ?></strong></p>
<p>
<anchor>
Back to Month View
<go href="<?php
echo ( "?y=".$Day->thisYear()."&amp;m=".
$Day->thisMonth()."&amp;d=".$Day->thisDay()."&amp;mime=wml" );
?>"/>
</anchor>
</p>
<table>
<?php
$Day->build();
while ( $Hour = & $Day->fetch() ) {
echo ( "<tr>\n" );
echo ( "<td>".date('g a',$Hour->getTimeStamp())."</td><td>Free time!</td>\n" );
echo ( "</tr>\n" );
}
?>
</table>
<?php
} else {
?>
<p><strong><?php echo ( date('F Y',$Month->getTimeStamp()) ); ?></strong></p>
<table>
<tr>
<td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td><td>S</td>
</tr>
<?php
$Month->build($selection);
while ( $Day = $Month->fetch() ) {
if ( $Day->isFirst() ) {
echo ( "<tr>\n" );
}
if ( $Day->isEmpty() ) {
echo ( "<td></td>\n" );
} else if ( $Day->isSelected() ) {
echo ( "<td><anchor><strong><u>".$Day->thisDay()."</u></strong>\n<go href=\"".$_SERVER['PHP_SELF']."?viewday=true&amp;y=".
$Day->thisYear()."&amp;m=".$Day->thisMonth()."&amp;d=".$Day->thisDay().
"&amp;mime=wml\" />\n</anchor></td>\n" );
} else {
echo ( "<td><anchor>".$Day->thisDay()."\n<go href=\"?viewday=true&amp;y=".
$Day->thisYear()."&amp;m=".$Day->thisMonth()."&amp;d=".$Day->thisDay().
"&amp;mime=wml\" /></anchor></td>\n" );
}
if ( $Day->isLast() ) {
echo ( "</tr>\n" );
}
}
?>
<tr>
<td>
<anchor>
&lt;&lt;
<go href="<?php
echo ( "?y=".$Month->thisYear()."&amp;m=".
$Month->prevMonth()."&amp;d=".$Month->thisDay()."&amp;mime=wml" );
?>"/>
</anchor>
</td>
<td></td><td></td><td></td><td></td><td></td>
<td>
<anchor>
&gt;&gt;
<go href="<?php
echo ( "?y=".$Month->thisYear()."&amp;m=".
$Month->nextMonth()."&amp;d=".$Month->thisDay()."&amp;mime=wml" );
?>"/>
</anchor>
</td>
</tr>
</table>
 
<?php
}
?>
<p><a href="<?php echo ( $_SERVER['PHP_SELF'] ); ?>">Back to HTML</a></p>
<?php echo ( '<p>Took: '.(getmicrotime()-$start).' seconds</p>' ); ?>
</wml>
<?php
#-----------------------------------------------------------------------------#
} else {
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> HTML (+WML) Personal Planner </title>
</head>
<body>
<h1>Personal Planner Rendered with HTML</h1>
<p>To view in WML, click <a href="<?php echo ( $_SERVER['PHP_SELF'] ); ?>?mime=wml">here</a> or place a ?mime=wml at the end of any URL.
Note that <a href="http://www.opera.com/download">Opera</a> supports WML natively and Mozilla / Firefox has the WMLBrowser
plugin: <a href="http://wmlbrowser.mozdev.org">wmlbrowser.mozdev.org</a></p>
<?php
if ( isset($_GET['viewday']) ) {
?>
<p><strong>Viewing <?php echo ( date('l, jS of F, Y',$Day->getTimeStamp()) ); ?></strong></p>
<p>
<anchor>
<a href="<?php
echo ( "?y=".$Day->thisYear()."&amp;m=".
$Day->thisMonth()."&amp;d=".$Day->thisDay());
?>">Back to Month View</a>
</p>
<table>
<?php
$Day->build();
while ( $Hour = & $Day->fetch() ) {
echo ( "<tr>\n" );
echo ( "<td>".date('g a',$Hour->getTimeStamp())."</td><td>Free time!</td>\n" );
echo ( "</tr>\n" );
}
?>
</table>
<?php
} else {
?>
<p><strong><?php echo ( date('F Y',$Month->getTimeStamp()) ); ?></strong></p>
<table>
<tr>
<td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td><td>S</td>
</tr>
<?php
$Month->build($selection);
while ( $Day = $Month->fetch() ) {
if ( $Day->isFirst() ) {
echo ( "<tr>\n" );
}
if ( $Day->isEmpty() ) {
echo ( "<td></td>\n" );
} else if ( $Day->isSelected() ) {
echo ( "<td><a href=\"".$_SERVER['PHP_SELF']."?viewday=true&amp;y=".
$Day->thisYear()."&amp;m=".$Day->thisMonth()."&amp;d=".$Day->thisDay().
"&amp;wml\"><strong><u>".$Day->thisDay()."</u></strong></a></td>\n" );
} else {
echo ( "<td><a href=\"".$_SERVER['PHP_SELF']."?viewday=true&amp;y=".
$Day->thisYear()."&amp;m=".$Day->thisMonth()."&amp;d=".$Day->thisDay().
"\">".$Day->thisDay()."</a></td>\n" );
}
if ( $Day->isLast() ) {
echo ( "</tr>\n" );
}
}
?>
<tr>
<td>
<a href="<?php
echo ( "?y=".$Month->thisYear()."&amp;m=".
$Month->prevMonth()."&amp;d=".$Month->thisDay() );
?>">
&lt;&lt;</a>
</td>
<td></td><td></td><td></td><td></td><td></td>
<td>
<a href="<?php
echo ( "?y=".$Month->thisYear()."&amp;m=".
$Month->nextMonth()."&amp;d=".$Month->thisDay() );
?>">&gt;&gt;</a>
</td>
</tr>
</table>
 
<?php
}
?>
 
 
<?php echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); ?>
</body>
</html>
<?php
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/8.phps
New file
0,0 → 1,70
<?php
/**
* Description: client for the SOAP Calendar Server
*/
if ( version_compare(phpversion(), "5.0.0", ">") ) {
die('PHP 5 has problems with PEAR::SOAP Client (8.0RC3)
- remove @ before include below to see why');
}
 
if (!@include('SOAP'.DIRECTORY_SEPARATOR.'Client.php')) {
die('You must have PEAR::SOAP installed');
}
 
// Just to save manaul modification...
$basePath = explode('/', $_SERVER['SCRIPT_NAME']);
array_pop($basePath);
$basePath = implode('/', $basePath);
$url = 'http://'.$_SERVER['SERVER_NAME'].$basePath.'/7.php?wsdl';
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('n');
 
$wsdl = new SOAP_WSDL ($url);
 
echo ( '<pre>'.$wsdl->generateProxyCode().'</pre>' );
 
$calendarClient = $wsdl->getProxy();
 
$month = $calendarClient->getMonth((int)$_GET['y'],(int)$_GET['m']);
 
if ( PEAR::isError($month) ) {
die ( $month->toString() );
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Calendar over the Wire </title>
</head>
<body>
<h1>Calendar Over the Wire (featuring PEAR::SOAP)</h1>
<table>
<caption><b><?php echo ( $month->monthname );?></b></caption>
<tr>
<th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th>
</tr>
<?php
foreach ( $month->days as $day ) {
 
if ( $day->isFirst === 1 )
echo ( "<tr>\n" );
if ( $day->isEmpty === 1 ) {
echo ( "<td></td>" );
} else {
echo ( "<td>".$day->day."</td>" );
}
if ( $day->isLast === 1 )
echo ( "</tr>\n" );
}
?>
<tr>
</table>
<p>Enter Year and Month to View:</p>
<form action="<?php echo ( $_SERVER['PHP_SELF'] ); ?>" method="get">
Year: <input type="text" size="4" name="y" value="<?php echo ( $_GET['y'] ); ?>">&nbsp;
Month: <input type="text" size="2" name="m" value="<?php echo ( $_GET['m'] ); ?>">&nbsp;
<input type="submit" value="Fetch Calendar">
</form>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/10.phps
New file
0,0 → 1,93
<?php
/**
* Description: demonstrates a decorator to provide simple output formatting
* on the month while still allowing the days to be accessed via the decorator
* In practice you _wouldn't_ do this - each decorator comes with a performance
* hit for extra method calls. For this example some simple functions could help
* format the month while the days are accessed via the normal Month object
*/
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Decorator.php';
 
// Decorate a Month with methods to improve formatting
class MonthDecorator extends Calendar_Decorator {
/**
* @param Calendar_Month
*/
function MonthDecorator(& $Month) {
parent::Calendar_Decorator($Month);
}
/**
* Override the prevMonth method to format the output
*/
function prevMonth() {
$prevStamp = parent::prevMonth(TRUE);
// Build the URL for the previous month
return $_SERVER['PHP_SELF'].'?y='.date('Y',$prevStamp).
'&m='.date('n',$prevStamp).'&d='.date('j',$prevStamp);
}
/**
* Override the thisMonth method to format the output
*/
function thisMonth() {
$thisStamp = parent::thisMonth(TRUE);
// A human readable string from this month
return date('F Y',$thisStamp);
}
/**
* Override the nextMonth method to format the output
*/
function nextMonth() {
$nextStamp = parent::nextMonth(TRUE);
// Build the URL for next month
return $_SERVER['PHP_SELF'].'?y='.date('Y',$nextStamp).
'&m='.date('n',$nextStamp).'&d='.date('j',$nextStamp);
}
}
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('n');
 
// Creata a month as usual
$Month = new Calendar_Month_Weekdays($_GET['y'],$_GET['m']);
 
// Pass it to the decorator and use the decorator from now on...
$MonthDecorator = new MonthDecorator($Month);
$MonthDecorator->build();
?>
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> A Simple Decorator </title>
</head>
<body>
<h1>A Simple Decorator</h1>
<table>
<caption><?php echo ( $MonthDecorator->thisMonth() ); ?></caption>
<?php
while ( $Day = $MonthDecorator->fetch() ) {
if ( $Day->isFirst() ) {
echo ( "\n<tr>\n" );
}
if ( $Day->isEmpty() ) {
echo ( "<td>&nbsp;</td>" );
} else {
echo ( "<td>".$Day->thisDay()."</td>" );
}
if ( $Day->isLast() ) {
echo ( "\n</tr>\n" );
}
}
?>
<tr>
<td><a href="<?php echo ($MonthDecorator->prevMonth()); ?>">Prev</a></td>
<td colspan="5">&nbsp;</td>
<td><a href="<?php echo ($MonthDecorator->nextMonth()); ?>">Next</a></td>
</tr>
</table>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/20.phps
New file
0,0 → 1,240
<?php
/**
* Description: demonstrates a decorator used to "attach a payload" to a selection
* to make it available when iterating over calendar children
*/
 
//if you use ISO-8601 dates, switch to PearDate engine
define('CALENDAR_ENGINE', 'PearDate');
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
 
require_once CALENDAR_ROOT . 'Month/Weekdays.php';
require_once CALENDAR_ROOT . 'Day.php';
require_once CALENDAR_ROOT . 'Decorator.php';
 
// accepts multiple entries
class DiaryEvent extends Calendar_Decorator
{
var $entries = array();
 
function DiaryEvent($calendar) {
Calendar_Decorator::Calendar_Decorator($calendar);
}
 
function addEntry($entry) {
$this->entries[] = $entry;
}
 
function getEntry() {
$entry = each($this->entries);
if ($entry) {
return $entry['value'];
} else {
reset($this->entries);
return false;
}
}
}
 
class MonthPayload_Decorator extends Calendar_Decorator
{
//Calendar engine
var $cE;
var $tableHelper;
 
var $year;
var $month;
var $firstDay = false;
 
function build($events=array())
{
require_once CALENDAR_ROOT . 'Day.php';
require_once CALENDAR_ROOT . 'Table/Helper.php';
 
$this->tableHelper = & new Calendar_Table_Helper($this, $this->firstDay);
$this->cE = & $this->getEngine();
$this->year = $this->thisYear();
$this->month = $this->thisMonth();
 
$daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month);
for ($i=1; $i<=$daysInMonth; $i++) {
$Day = new Calendar_Day(2000,1,1); // Create Day with dummy values
$Day->setTimeStamp($this->cE->dateToStamp($this->year, $this->month, $i));
$this->children[$i] = new DiaryEvent($Day);
}
if (count($events) > 0) {
$this->setSelection($events);
}
Calendar_Month_Weekdays::buildEmptyDaysBefore();
Calendar_Month_Weekdays::shiftDays();
Calendar_Month_Weekdays::buildEmptyDaysAfter();
Calendar_Month_Weekdays::setWeekMarkers();
return true;
}
 
function setSelection($events)
{
$daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month);
for ($i=1; $i<=$daysInMonth; $i++) {
$stamp1 = $this->cE->dateToStamp($this->year, $this->month, $i);
$stamp2 = $this->cE->dateToStamp($this->year, $this->month, $i+1);
foreach ($events as $event) {
if (($stamp1 >= $event['start'] && $stamp1 < $event['end']) ||
($stamp2 >= $event['start'] && $stamp2 < $event['end']) ||
($stamp1 <= $event['start'] && $stamp2 > $event['end'])
) {
$this->children[$i]->addEntry($event);
$this->children[$i]->setSelected();
}
}
}
}
 
function fetch()
{
$child = each($this->children);
if ($child) {
return $child['value'];
} else {
reset($this->children);
return false;
}
}
}
 
// Calendar instance used to get the dates in the preferred format:
// you can switch Calendar Engine and the example still works
$cal = new Calendar;
 
$events = array();
//add some events
$events[] = array(
'start' => $cal->cE->dateToStamp(2004, 6, 1, 10),
'end' => $cal->cE->dateToStamp(2004, 6, 1, 12),
'desc' => 'Important meeting'
);
$events[] = array(
'start' => $cal->cE->dateToStamp(2004, 6, 1, 21),
'end' => $cal->cE->dateToStamp(2004, 6, 1, 23, 59),
'desc' => 'Dinner with the boss'
);
$events[] = array(
'start' => $cal->cE->dateToStamp(2004, 6, 5),
'end' => $cal->cE->dateToStamp(2004, 6, 10, 23, 59),
'desc' => 'Holidays!'
);
 
 
 
$Month = & new Calendar_Month_Weekdays(2004, 6);
$MonthDecorator = new MonthPayload_Decorator($Month);
$MonthDecorator->build($events);
 
?>
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Calendar </title>
<style text="text/css">
table {
border-collapse: collapse;
}
caption {
font-family: verdana;
font-size: 14pt;
padding-bottom: 4pt;
}
th {
font-family: verdana;
font-size: 11px;
text-align: center;
background-color: #e7e3e7;
padding: 5pt;
line-height: 150%;
border: 1px solid #ccc;
}
td {
font-family: verdana;
font-size: 11px;
text-align: left;
vertical-align: top;
}
td.calCell {
border: 1px solid #b5bece;
padding: 3px;
}
td.calCellEmpty {
background-color: #f3f3f7;
}
td.calCellBusy {
background-color: #efeffa;
}
div.dayNumber {
text-align: right;
background-color: #f8f8f8;
border-bottom: 1px solid #ccc;
}
ul {
margin-left: 0;
margin-top: 5pt;
padding: 0 10pt 0 12pt;
list-style-type: square;
}
</style>
</head>
 
<body>
 
<h2>Sample Calendar Payload Decorator (using <?php echo CALENDAR_ENGINE; ?> engine)</h2>
<table class="calendar" width="98%" cellspacing="0" cellpadding="0">
<caption>
<?php echo $MonthDecorator->thisMonth().' / '.$MonthDecorator->thisYear(); ?>
</caption>
<tr>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
<?php
while ($Day = $MonthDecorator->fetch()) {
 
if ($Day->isFirst()) {
echo "<tr>\n";
}
 
echo '<td class="calCell';
if ($Day->isSelected()) {
echo ' calCellBusy';
} elseif ($Day->isEmpty()) {
echo ' calCellEmpty';
}
echo '">';
echo '<div class="dayNumber">'.$Day->thisDay().'</div>';
 
if ($Day->isEmpty()) {
echo '&nbsp;';
} else {
echo '<div class="dayContents"><ul>';
while ($entry = $Day->getEntry()) {
echo '<li>'.$entry['desc'].'</li>';
//you can print the time range as well
}
echo '</ul></div>';
}
echo '</td>';
 
if ($Day->isLast()) {
echo "</tr>\n";
}
}
?>
</table>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/12.phps
New file
0,0 → 1,116
<?php
/**
* Description: a complete year
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
 
require_once CALENDAR_ROOT.'Year.php';
 
define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKDAYS);
 
if ( !isset($_GET['year']) ) $_GET['year'] = date('Y');
 
$Year = new Calendar_Year($_GET['year']);
 
$Year->build();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> <?php echo ( $Year->thisYear() ); ?> </title>
<style type="text/css">
body {
font-family: Georgia, serif;
}
caption.year {
font-weight: bold;
font-size: 120%;
font-color: navy;
}
caption.month {
font-size: 110%;
font-color: navy;
}
table.month {
border: thin groove #800080
}
tr {
vertical-align: top;
}
th, td {
text-align: right;
font-size: 70%;
}
#prev {
float: left;
font-size: 70%;
}
#next {
float: right;
font-size: 70%;
}
</style>
</head>
<body>
<table>
<caption class="year">
<?php echo ( $Year->thisYear() ); ?>
<div id="next">
<a href="?year=<?php echo ( $Year->nextYear() ); ?>">>></a>
</div>
<div id="prev">
<a href="?year=<?php echo ( $Year->prevYear() ); ?>"><<</a>
</div>
</caption>
<?php
$i = 0;
while ( $Month = $Year->fetch() ) {
 
switch ( $i ) {
case 0:
echo ( "<tr>\n" );
break;
case 3:
case 6:
case 9:
echo ( "</tr>\n<tr>\n" );
break;
case 12:
echo ( "</tr>\n" );
break;
}
 
echo ( "<td>\n<table class=\"month\">\n" );
echo ( "<caption class=\"month\">".date('F',$Month->thisMonth(TRUE))."</caption>" );
echo ( "<tr>\n<th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th>\n</tr>" );
$Month->build();
while ( $Day = $Month->fetch() ) {
if ( $Day->isFirst() ) {
echo ( "<tr>\n" );
}
if ( $Day->isEmpty() ) {
echo ( "<td>&nbsp;</td>\n" );
} else {
echo ( "<td>".$Day->thisDay()."</td>\n" );
}
if ( $Day->isLast() ) {
echo ( "</tr>\n" );
}
}
echo ( "</table>\n</td>\n" );
 
$i++;
}
?>
</table>
<p>Took: <?php echo ((getmicrotime()-$start)); ?></p>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/22.phps
New file
0,0 → 1,46
<?php
/**
* Description: demonstrates using the Uri util
*/
if (!@include 'Calendar/Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Util/Uri.php';
 
if (!isset($_GET['jahr'])) $_GET['jahr'] = date('Y');
if (!isset($_GET['monat'])) $_GET['monat'] = date('m');
 
// Build the month
$Calendar = new Calendar_Month_Weekdays($_GET['jahr'], $_GET['monat']);
 
echo ( '<p>The current month is '
.$Calendar->thisMonth().' of year '.$Calendar->thisYear().'</p>');
 
$Uri = & new Calendar_Util_Uri('jahr','monat');
$Uri->setFragments('jahr','monat');
 
echo "\"Vector\" URIs<pre>";
echo ( "Previous Uri:\t".htmlentities($Uri->prev($Calendar, 'month'))."\n" );
echo ( "This Uri:\t".htmlentities($Uri->this($Calendar, 'month'))."\n" );
echo ( "Next Uri:\t".htmlentities($Uri->next($Calendar, 'month'))."\n" );
echo "</pre>";
 
// Switch to scalar URIs
$Uri->separator = '/'; // Default is &amp;
$Uri->scalar = true; // Omit variable names
 
echo "\"Scalar\" URIs<pre>";
echo ( "Previous Uri:\t".$Uri->prev($Calendar, 'month')."\n" );
echo ( "This Uri:\t".$Uri->this($Calendar, 'month')."\n" );
echo ( "Next Uri:\t".$Uri->next($Calendar, 'month')."\n" );
echo "</pre>";
 
// Restore the vector URIs
$Uri->separator = '&amp;';
$Uri->scalar = false;
?>
<p>
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->prev($Calendar, 'month'));?>">Prev</a> :
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->next($Calendar, 'month'));?>">Next</a>
</p>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/14.phps
New file
0,0 → 1,141
<?php
/**
* Description: same as 3.php, but using the PEAR::Date engine
* Note: make sure PEAR::Date is a stable release!!!
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
// Switch to PEAR::Date engine
define('CALENDAR_ENGINE', 'PearDate');
 
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Day.php';
 
// Initialize GET variables if not set
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('m');
if (!isset($_GET['d'])) $_GET['d'] = date('d');
 
// Build the month
$month = new Calendar_Month_Weekdays($_GET['y'], $_GET['m']);
 
// Create an array of days which are "selected"
// Used for Week::build() below
$selectedDays = array (
new Calendar_Day($_GET['y'], $_GET['m'], $_GET['d']),
new Calendar_Day($_GET['y'], 12, 25),
);
 
// Build the days in the month
$month->build($selectedDays);
 
// Construct strings for next/previous links
$PMonth = $month->prevMonth('object'); // Get previous month as object
$prev = $_SERVER['PHP_SELF'].'?y='.$PMonth->thisYear().'&m='.$PMonth->thisMonth().'&d='.$PMonth->thisDay();
$NMonth = $month->nextMonth('object');
$next = $_SERVER['PHP_SELF'].'?y='.$NMonth->thisYear().'&m='.$NMonth->thisMonth().'&d='.$NMonth->thisDay();
 
$thisDate = new Date($month->thisMonth('timestamp'));
?>
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Calendar using PEAR::Date Engine </title>
<style text="text/css">
table {
background-color: silver;
}
caption {
font-family: verdana;
font-size: 12px;
background-color: while;
}
.prevMonth {
font-size: 10px;
text-align: left;
}
.nextMonth {
font-size: 10px;
text-align: right;
}
th {
font-family: verdana;
font-size: 11px;
color: navy;
text-align: right;
}
td {
font-family: verdana;
font-size: 11px;
text-align: right;
}
.selected {
background-color: yellow;
}
</style>
</head>
 
<body>
 
<h2>Calendar using PEAR::Date Engine</h2>
<table class="calendar">
<caption>
<?php echo $thisDate->format('%B %Y'); ?>
</caption>
<tr>
<th>M</th>
<th>T</th>
<th>W</th>
<th>T</th>
<th>F</th>
<th>S</th>
<th>S</th>
</tr>
<?php
while ($day = $month->fetch()) {
// Build a link string for each day
$link = $_SERVER['PHP_SELF'].
'?y='.$day->thisYear().
'&m='.$day->thisMonth().
'&d='.$day->thisDay();
 
// isFirst() to find start of week
if ($day->isFirst())
echo "<tr>\n";
 
if ($day->isSelected()) {
echo '<td class="selected">'.$day->thisDay().'</td>'."\n";
} else if ($day->isEmpty()) {
echo '<td>&nbsp;</td>'."\n";
} else {
echo '<td><a href="'.$link.'">'.$day->thisDay().'</a></td>'."\n";
}
 
// isLast() to find end of week
if ($day->isLast()) {
echo "</tr>\n";
}
}
?>
<tr>
<td>
<a href="<?php echo $prev; ?>" class="prevMonth"><< </a>
</td>
<td colspan="5">&nbsp;</td>
<td>
<a href="<?php echo $next; ?>" class="nextMonth"> >></a>
</td>
</tr>
</table>
<?php
echo '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>';
?>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/16.phps
New file
0,0 → 1,31
<?php
/**
* Description: demonstrates using the Uri decorator
*/
if (!@include 'Calendar/Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Decorator/Uri.php';
 
if (!isset($_GET['jahr'])) $_GET['jahr'] = date('Y');
if (!isset($_GET['monat'])) $_GET['monat'] = date('m');
 
// Build the month
$Calendar = new Calendar_Month_Weekdays($_GET['jahr'], $_GET['monat']);
 
echo ( '<p>The current month is '
.$Calendar->thisMonth().' of year '.$Calendar->thisYear().'</p>');
 
$Uri = & new Calendar_Decorator_Uri($Calendar);
$Uri->setFragments('jahr','monat');
// $Uri->setSeperator('/'); // Default is &
// $Uri->setScalar(); // Omit variable names
echo ( "<pre>Previous Uri:\t".$Uri->prev('month')."\n" );
echo ( "This Uri:\t".$Uri->this('month')."\n" );
echo ( "Next Uri:\t".$Uri->next('month')."\n</pre>" );
?>
<p>
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->prev('month'));?>">Prev</a> :
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->next('month'));?>">Next</a>
</p>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/18.phps
New file
0,0 → 1,36
<?php
/**
* Description: demonstrates using the Wrapper decorator
*/
 
if (!@include 'Calendar/Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Month.php';
require_once CALENDAR_ROOT.'Decorator.php'; // Not really needed but added to help this make sense
require_once CALENDAR_ROOT.'Decorator/Wrapper.php';
 
class MyBoldDecorator extends Calendar_Decorator
{
function MyBoldDecorator(&$Calendar)
{
parent::Calendar_Decorator($Calendar);
}
 
function thisDay()
{
return '<b>'.parent::thisDay().'</b>';
}
}
 
$Month = new Calendar_Month(date('Y'), date('n'));
 
$Wrapper = & new Calendar_Decorator_Wrapper($Month);
$Wrapper->build();
 
echo '<h2>The Wrapper decorator</h2>';
echo '<i>Day numbers are rendered in bold</i><br /> <br />';
while ($DecoratedDay = $Wrapper->fetch('MyBoldDecorator')) {
echo $DecoratedDay->thisDay().'<br />';
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/10.php
New file
0,0 → 1,93
<?php
/**
* Description: demonstrates a decorator to provide simple output formatting
* on the month while still allowing the days to be accessed via the decorator
* In practice you _wouldn't_ do this - each decorator comes with a performance
* hit for extra method calls. For this example some simple functions could help
* format the month while the days are accessed via the normal Month object
*/
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Decorator.php';
 
// Decorate a Month with methods to improve formatting
class MonthDecorator extends Calendar_Decorator {
/**
* @param Calendar_Month
*/
function MonthDecorator(& $Month) {
parent::Calendar_Decorator($Month);
}
/**
* Override the prevMonth method to format the output
*/
function prevMonth() {
$prevStamp = parent::prevMonth(TRUE);
// Build the URL for the previous month
return $_SERVER['PHP_SELF'].'?y='.date('Y',$prevStamp).
'&m='.date('n',$prevStamp).'&d='.date('j',$prevStamp);
}
/**
* Override the thisMonth method to format the output
*/
function thisMonth() {
$thisStamp = parent::thisMonth(TRUE);
// A human readable string from this month
return date('F Y',$thisStamp);
}
/**
* Override the nextMonth method to format the output
*/
function nextMonth() {
$nextStamp = parent::nextMonth(TRUE);
// Build the URL for next month
return $_SERVER['PHP_SELF'].'?y='.date('Y',$nextStamp).
'&m='.date('n',$nextStamp).'&d='.date('j',$nextStamp);
}
}
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('n');
 
// Creata a month as usual
$Month = new Calendar_Month_Weekdays($_GET['y'],$_GET['m']);
 
// Pass it to the decorator and use the decorator from now on...
$MonthDecorator = new MonthDecorator($Month);
$MonthDecorator->build();
?>
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> A Simple Decorator </title>
</head>
<body>
<h1>A Simple Decorator</h1>
<table>
<caption><?php echo ( $MonthDecorator->thisMonth() ); ?></caption>
<?php
while ( $Day = $MonthDecorator->fetch() ) {
if ( $Day->isFirst() ) {
echo ( "\n<tr>\n" );
}
if ( $Day->isEmpty() ) {
echo ( "<td>&nbsp;</td>" );
} else {
echo ( "<td>".$Day->thisDay()."</td>" );
}
if ( $Day->isLast() ) {
echo ( "\n</tr>\n" );
}
}
?>
<tr>
<td><a href="<?php echo ($MonthDecorator->prevMonth()); ?>">Prev</a></td>
<td colspan="5">&nbsp;</td>
<td><a href="<?php echo ($MonthDecorator->nextMonth()); ?>">Next</a></td>
</tr>
</table>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/11.php
New file
0,0 → 1,109
<?php
/**
* Description: demonstrates a decorator used to "attach a payload" to a selection
* to make it available when iterating over calendar children
*/
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Day.php';
require_once CALENDAR_ROOT.'Hour.php';
require_once CALENDAR_ROOT.'Decorator.php';
 
// Decorator to "attach" functionality to selected hours
class DiaryEvent extends Calendar_Decorator {
var $entry;
function DiaryEvent($calendar) {
Calendar_Decorator::Calendar_Decorator($calendar);
}
function setEntry($entry) {
$this->entry = $entry;
}
function getEntry() {
return $this->entry;
}
}
 
// Create a day to view the hours for
$Day = & new Calendar_Day(2003,10,24);
 
// A sample query to get the data for today (NOT ACTUALLY USED HERE)
$sql = "
SELECT
*
FROM
diary
WHERE
eventtime >= '".$Day->thisDay(TRUE)."'
AND
eventtime < '".$Day->nextDay(TRUE)."';";
 
// An array simulating data from a database
$result = array (
array('eventtime'=>mktime(9,0,0,10,24,2003),'entry'=>'Meeting with sales team'),
array('eventtime'=>mktime(11,0,0,10,24,2003),'entry'=>'Conference call with Widget Inc.'),
array('eventtime'=>mktime(15,0,0,10,24,2003),'entry'=>'Presentation to board of directors')
);
 
// An array to place selected hours in
$selection = array();
 
// Loop through the "database result"
foreach ( $result as $row ) {
$Hour = new Calendar_Hour(2000,1,1,1); // Create Hour with dummy values
$Hour->setTimeStamp($row['eventtime']); // Set the real time with setTimeStamp
 
// Create the decorator, passing it the Hour
$DiaryEvent = new DiaryEvent($Hour);
 
// Attach the payload
$DiaryEvent->setEntry($row['entry']);
 
// Add the decorator to the selection
$selection[] = $DiaryEvent;
}
 
// Build the hours in that day, passing the selection
$Day->build($selection);
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Passing a Selection Payload with a Decorator </title>
</head>
<body>
<h1>Passing a Selection "Payload" using a Decorator</h1>
<table>
<caption><b>Your Schedule for <?php echo ( date('D nS F Y',$Day->thisDay(TRUE)) ); ?></b></caption>
<tr>
<th width="5%">Time</th>
<th>Entry</th>
</tr>
<?php
while ( $Hour = & $Day->fetch() ) {
 
$hour = $Hour->thisHour();
$minute = $Hour->thisMinute();
 
// Office hours only...
if ( $hour >= 8 && $hour <= 18 ) {
echo ( "<tr>\n" );
echo ( "<td>$hour:$minute</td>\n" );
 
// If the hour is selected, call the decorator method...
if ( $Hour->isSelected() ) {
echo ( "<td bgcolor=\"silver\">".$Hour->getEntry()."</td>\n" );
} else {
echo ( "<td>&nbsp;</td>\n" );
}
echo ( "</tr>\n" );
}
}
?>
</table>
<p>The query to fetch this data, with help from PEAR::Calendar, might be;</p>
<pre>
<?php echo ( $sql ); ?>
</pre>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/12.php
New file
0,0 → 1,116
<?php
/**
* Description: a complete year
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
 
require_once CALENDAR_ROOT.'Year.php';
 
define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKDAYS);
 
if ( !isset($_GET['year']) ) $_GET['year'] = date('Y');
 
$Year = new Calendar_Year($_GET['year']);
 
$Year->build();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> <?php echo ( $Year->thisYear() ); ?> </title>
<style type="text/css">
body {
font-family: Georgia, serif;
}
caption.year {
font-weight: bold;
font-size: 120%;
font-color: navy;
}
caption.month {
font-size: 110%;
font-color: navy;
}
table.month {
border: thin groove #800080
}
tr {
vertical-align: top;
}
th, td {
text-align: right;
font-size: 70%;
}
#prev {
float: left;
font-size: 70%;
}
#next {
float: right;
font-size: 70%;
}
</style>
</head>
<body>
<table>
<caption class="year">
<?php echo ( $Year->thisYear() ); ?>
<div id="next">
<a href="?year=<?php echo ( $Year->nextYear() ); ?>">>></a>
</div>
<div id="prev">
<a href="?year=<?php echo ( $Year->prevYear() ); ?>"><<</a>
</div>
</caption>
<?php
$i = 0;
while ( $Month = $Year->fetch() ) {
 
switch ( $i ) {
case 0:
echo ( "<tr>\n" );
break;
case 3:
case 6:
case 9:
echo ( "</tr>\n<tr>\n" );
break;
case 12:
echo ( "</tr>\n" );
break;
}
 
echo ( "<td>\n<table class=\"month\">\n" );
echo ( "<caption class=\"month\">".date('F',$Month->thisMonth(TRUE))."</caption>" );
echo ( "<tr>\n<th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th>\n</tr>" );
$Month->build();
while ( $Day = $Month->fetch() ) {
if ( $Day->isFirst() ) {
echo ( "<tr>\n" );
}
if ( $Day->isEmpty() ) {
echo ( "<td>&nbsp;</td>\n" );
} else {
echo ( "<td>".$Day->thisDay()."</td>\n" );
}
if ( $Day->isLast() ) {
echo ( "</tr>\n" );
}
}
echo ( "</table>\n</td>\n" );
 
$i++;
}
?>
</table>
<p>Took: <?php echo ((getmicrotime()-$start)); ?></p>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/1.phps
New file
0,0 → 1,92
<?php
/**
* Description: Passes through all main calendar classes, beginning with year
* and down to seconds, skipping weeks. Useful to test Calendar is (basically)
* working correctly
*
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
 
if (!isset($_GET['y'])) $_GET['y'] = 2003;
if (!isset($_GET['m'])) $_GET['m'] = 8;
if (!isset($_GET['d'])) $_GET['d'] = 9;
if (!isset($_GET['h'])) $_GET['h'] = 12;
if (!isset($_GET['i'])) $_GET['i'] = 34;
if (!isset($_GET['s'])) $_GET['s'] = 46;
 
switch ( @$_GET['view'] ) {
default:
$_GET['view'] = 'calendar_year';
case 'calendar_year':
require_once CALENDAR_ROOT.'Year.php';
$c = new Calendar_Year($_GET['y']);
break;
case 'calendar_month':
require_once CALENDAR_ROOT.'Month.php';
$c = new Calendar_Month($_GET['y'],$_GET['m']);
break;
case 'calendar_day':
require_once CALENDAR_ROOT.'Day.php';
$c = new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']);
break;
case 'calendar_hour':
require_once CALENDAR_ROOT.'Hour.php';
$c = new Calendar_Hour($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h']);
break;
case 'calendar_minute':
require_once CALENDAR_ROOT.'Minute.php';
$c = new Calendar_Minute($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i']);
break;
case 'calendar_second':
require_once CALENDAR_ROOT.'Second.php';
$c = new Calendar_Second($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i'],$_GET['s']);
break;
}
 
echo ( 'Viewing: '.@$_GET['view'].'<br />' );
echo ( 'The time is now: '.date('Y M d H:i:s',$c->getTimestamp()).'<br >' );
 
$i = 1;
echo ( '<h1>First Iteration</h1>' );
echo ( '<p>The first iteration is more "expensive", the calendar data
structures having to be built.</p>' );
$start = getmicrotime();
$c->build();
while ( $e = $c->fetch() ) {
$class = strtolower(get_class($e));
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay().
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond();
$method = 'this'.str_replace('calendar_','',$class);
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " );
if ( ($i % 10) == 0 ) {
echo ( '<br>' );
}
$i++;
}
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' );
 
$i = 1;
echo ( '<h1>Second Iteration</h1>' );
echo ( '<p>This second iteration is faster, the data structures
being re-used</p>' );
$start = getmicrotime();
while ( $e = $c->fetch() ) {
$class = strtolower(get_class($e));
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay().
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond();
$method = 'this'.str_replace('calendar_','',$class);
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " );
if ( ($i % 10) == 0 ) {
echo ( '<br>' );
}
$i++;
}
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' );
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/13.php
New file
0,0 → 1,99
<?php
/**
* Description: same as 1.php, but using the PEAR::Date engine
* Notice the use of the CALENDAR_ENGINE constant, which
* switches the calculation "engine"
* Note: make sure PEAR::Date is a stable release!!!
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
 
// Switch to PEAR::Date engine
define('CALENDAR_ENGINE','PearDate');
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
 
if (!isset($_GET['y'])) $_GET['y'] = 2003;
if (!isset($_GET['m'])) $_GET['m'] = 8;
if (!isset($_GET['d'])) $_GET['d'] = 9;
if (!isset($_GET['h'])) $_GET['h'] = 12;
if (!isset($_GET['i'])) $_GET['i'] = 34;
if (!isset($_GET['s'])) $_GET['s'] = 46;
 
switch ( @$_GET['view'] ) {
default:
$_GET['view'] = 'calendar_year';
case 'calendar_year':
require_once CALENDAR_ROOT.'Year.php';
$c = new Calendar_Year($_GET['y']);
break;
case 'calendar_month':
require_once CALENDAR_ROOT.'Month.php';
$c = new Calendar_Month($_GET['y'],$_GET['m']);
break;
case 'calendar_day':
require_once CALENDAR_ROOT.'Day.php';
$c = new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']);
break;
case 'calendar_hour':
require_once CALENDAR_ROOT.'Hour.php';
$c = new Calendar_Hour($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h']);
break;
case 'calendar_minute':
require_once CALENDAR_ROOT.'Minute.php';
$c = new Calendar_Minute($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i']);
break;
case 'calendar_second':
require_once CALENDAR_ROOT.'Second.php';
$c = new Calendar_Second($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i'],$_GET['s']);
break;
}
 
// Convert timestamp to human readable date
$date = new Date($c->getTimestamp());
 
echo ( '<h1>Using PEAR::Date engine</h1>' );
echo ( 'Viewing: '.@$_GET['view'].'<br />' );
echo ( 'The time is now: '.$date->format('%Y %a %e %T').'<br >' );
 
$i = 1;
echo ( '<h1>First Iteration</h1>' );
echo ( '<p>The first iteration is more "expensive", the calendar data
structures having to be built.</p>' );
$start = getmicrotime();
$c->build();
while ( $e = $c->fetch() ) {
$class = strtolower(get_class($e));
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay().
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond();
$method = 'this'.str_replace('calendar_','',$class);
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " );
if ( ($i % 10) == 0 ) {
echo ( '<br>' );
}
$i++;
}
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' );
 
$i = 1;
echo ( '<h1>Second Iteration</h1>' );
echo ( '<p>This second iteration is faster, the data structures
being re-used</p>' );
$start = getmicrotime();
while ( $e = $c->fetch() ) {
$class = strtolower(get_class($e));
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay().
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond();
$method = 'this'.str_replace('calendar_','',$class);
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " );
if ( ($i % 10) == 0 ) {
echo ( '<br>' );
}
$i++;
}
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' );
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/14.php
New file
0,0 → 1,141
<?php
/**
* Description: same as 3.php, but using the PEAR::Date engine
* Note: make sure PEAR::Date is a stable release!!!
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
// Switch to PEAR::Date engine
define('CALENDAR_ENGINE', 'PearDate');
 
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Day.php';
 
// Initialize GET variables if not set
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('m');
if (!isset($_GET['d'])) $_GET['d'] = date('d');
 
// Build the month
$month = new Calendar_Month_Weekdays($_GET['y'], $_GET['m']);
 
// Create an array of days which are "selected"
// Used for Week::build() below
$selectedDays = array (
new Calendar_Day($_GET['y'], $_GET['m'], $_GET['d']),
new Calendar_Day($_GET['y'], 12, 25),
);
 
// Build the days in the month
$month->build($selectedDays);
 
// Construct strings for next/previous links
$PMonth = $month->prevMonth('object'); // Get previous month as object
$prev = $_SERVER['PHP_SELF'].'?y='.$PMonth->thisYear().'&m='.$PMonth->thisMonth().'&d='.$PMonth->thisDay();
$NMonth = $month->nextMonth('object');
$next = $_SERVER['PHP_SELF'].'?y='.$NMonth->thisYear().'&m='.$NMonth->thisMonth().'&d='.$NMonth->thisDay();
 
$thisDate = new Date($month->thisMonth('timestamp'));
?>
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Calendar using PEAR::Date Engine </title>
<style text="text/css">
table {
background-color: silver;
}
caption {
font-family: verdana;
font-size: 12px;
background-color: while;
}
.prevMonth {
font-size: 10px;
text-align: left;
}
.nextMonth {
font-size: 10px;
text-align: right;
}
th {
font-family: verdana;
font-size: 11px;
color: navy;
text-align: right;
}
td {
font-family: verdana;
font-size: 11px;
text-align: right;
}
.selected {
background-color: yellow;
}
</style>
</head>
 
<body>
 
<h2>Calendar using PEAR::Date Engine</h2>
<table class="calendar">
<caption>
<?php echo $thisDate->format('%B %Y'); ?>
</caption>
<tr>
<th>M</th>
<th>T</th>
<th>W</th>
<th>T</th>
<th>F</th>
<th>S</th>
<th>S</th>
</tr>
<?php
while ($day = $month->fetch()) {
// Build a link string for each day
$link = $_SERVER['PHP_SELF'].
'?y='.$day->thisYear().
'&m='.$day->thisMonth().
'&d='.$day->thisDay();
 
// isFirst() to find start of week
if ($day->isFirst())
echo "<tr>\n";
 
if ($day->isSelected()) {
echo '<td class="selected">'.$day->thisDay().'</td>'."\n";
} else if ($day->isEmpty()) {
echo '<td>&nbsp;</td>'."\n";
} else {
echo '<td><a href="'.$link.'">'.$day->thisDay().'</a></td>'."\n";
}
 
// isLast() to find end of week
if ($day->isLast()) {
echo "</tr>\n";
}
}
?>
<tr>
<td>
<a href="<?php echo $prev; ?>" class="prevMonth"><< </a>
</td>
<td colspan="5">&nbsp;</td>
<td>
<a href="<?php echo $next; ?>" class="nextMonth"> >></a>
</td>
</tr>
</table>
<?php
echo '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>';
?>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/index.html
New file
0,0 → 1,50
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>PEAR::Calendar Examples</title>
<style type="text/css">
body {
font-family: georgia, serif;
}
pre {
background-color: silver;
}
code {
color: navy;
background-color: #e2e3e4;
}
</style>
</head>
 
<body>
<h1>PEAR::Calendar Examples</h1>
<p>$Id: index.html,v 1.6 2004/08/17 09:10:53 hfuecks Exp $</p>
<ul>
<li><a href="1.php">1.php</a> [<a href="1.phps">src</a>] - shows basic usage, passing all the way down from <code>Calendar_Year</code> to <code>Calendar_Second</code> - more of a quick test it's working</li>
<li><a href="2.php">2.php</a> [<a href="2.phps">src</a>] - shows how to build a tabular month using <code>Calendar_Month_Weeks</code>, <code>Calendar_Week</code>, <code>Calendar_Day</code> as well as selecting some dates.</li>
<li><a href="3.php">3.php</a> [<a href="3.phps">src</a>] - shows how to build a tabular month using <code>Calendar_Month_Weekdays</code> and <code>Calendar_Day</code>, as well as selecting some dates (this method is faster).</li>
<li><a href="4.php">4.php</a> [<a href="4.phps">src</a>] - shows how to use PEAR::Calendar for validation.</li>
<li><a href="5.php">5.php</a> [<a href="5.phps">src</a>] - shows PEAR::Calendar in use to help generate a form.</li>
<li><a href="6.php">6.php</a> [<a href="6.phps">src</a>] - a month and day "planner" calendar, which can be rendered both as HTML and WML.</li>
<li><a href="7.php">7.php</a> [<a href="7.phps">src</a>] - a simple SOAP Calendar Server, using PEAR::SOAP and PEAR::Calendar</li>
<li><a href="8.php">8.php</a> [<a href="8.phps">src</a>] - a WSDL SOAP client for the SOAP Calendar Server</li>
<li><a href="9.php">9.php</a> [<a href="9.phps">src</a>] - quick example of i18n with <code>setlocale</code> (not working on SF)</li>
<li><a href="10.php">10.php</a> [<a href="10.phps">src</a>] - an example of extending <code>Calendar_Decorator</code> to modify output</li>
<li><a href="11.php">11.php</a> [<a href="11.phps">src</a>] - attaching a "payload" (e.g. results of a DB query) to a calendar using <code>Calendar_Decorator</code> to allow the payload to be available inside the main loop.</li>
<li><a href="12.php">12.php</a> [<a href="12.phps">src</a>] - a complete year with months.</li>
<li><a href="13.php">13.php</a> [<a href="13.phps">src</a>] - same as 1.php but using <code>Calendar_Engine_PearDate</code>, (see <a href="http://pear.php.net/Date">PEAR::Date</a>).</li>
<li><a href="14.php">14.php</a> [<a href="14.phps">src</a>] - same as 3.php but using <code>Calendar_Engine_PearDate</code></li>
<li><a href="15.php">15.php</a> [<a href="15.phps">src</a>] - paging through weeks </li>
<li><a href="16.php">16.php</a> [<a href="16.phps">src</a>] - example of <code>Calendar_Decorator_Uri</code>. <i>Note</i> you should prefer <code>Calendar_Util_Uri</code> (see below) in most cases, for performance </li>
<li><a href="17.php">17.php</a> [<a href="17.phps">src</a>] - example of <code>Calendar_Decorator_Textual</code>. <i>Note</i> you should prefer <code>Calendar_Util_Textual</code> (see below) in most cases, for performance</li>
<li><a href="18.php">18.php</a> [<a href="18.phps">src</a>] - example of <code>Calendar_Decorator_Wrapper</code>.</li>
<li><a href="19.php">19.php</a> [<a href="19.phps">src</a>] - example of <code>Calendar_Decorator_Weekday</code>.</li>
<li><a href="20.php">20.php</a> [<a href="20.phps">src</a>] - shows how to attach a "payload" spanning multiple days, with more than one entry per day</li>
<li><a href="21.php">21.php</a> [<a href="21.phps">src</a>] - same as 12.php but using <code>Calendar_Month_Weeks</code> instead of <code>Calendar_Month_Weekdays</code> to allow the week in the year or week in the month to be displayed.</li>
<li><a href="22.php">22.php</a> [<a href="22.phps">src</a>] - demonstrates use of <code>Calendar_Util_Uri</code>.</li>
<li><a href="23.php">23.php</a> [<a href="23.phps">src</a>] - demonstrates use of <code>Calendar_Util_Textual</code>.</li>
<li><a href="24.php">24.php</a> [<a href="24.phps">src</a>] - <code>Calendar_Decorator_Weekday</code> combined with <code>Calendar_Decorator_Wrapper</code> to decorate days in the month.</li>
</ul>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/15.php
New file
0,0 → 1,58
<?php
/**
* Shows more on how a week can be used
*/
function getmicrotime() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if (!@include 'Calendar/Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Week.php';
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('m');
if (!isset($_GET['d'])) $_GET['d'] = 1;
 
// Build the month
$Week = new Calendar_Week($_GET['y'], $_GET['m'], $_GET['d']);
/*
$Validator = $Week->getValidator();
if (!$Validator->isValidWeek()) {
die ('Please enter a valid week!');
}
*/
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Paging Weeks </title>
</head>
<body>
<h1>Paging Weeks</h1>
<h2>Week: <?php echo $Week->thisWeek().' '.date('F Y',$Week->thisMonth(true)); ?></h2>
<?php
$Week->build();
while ($Day = $Week->fetch()) {
echo '<p>'.date('jS F',$Day->thisDay(true))."</p>\n";
}
$days = $Week->fetchAll();
 
$prevWeek = $Week->prevWeek('array');
$prevWeekLink = $_SERVER['PHP_SELF'].
'?y='.$prevWeek['year'].
'&m='.$prevWeek['month'].
'&d='.$prevWeek['day'];
 
$nextWeek = $Week->nextWeek('array');
$nextWeekLink = $_SERVER['PHP_SELF'].
'?y='.$nextWeek['year'].
'&m='.$nextWeek['month'].
'&d='.$nextWeek['day'];
?>
<p><a href="<?php echo $prevWeekLink; ?>"><<</a> | <a href="<?php echo $nextWeekLink; ?>">>></a></p>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/3.phps
New file
0,0 → 1,134
<?php
/**
* Description: Performs same behaviour as 2.php but uses Month::buildWeekDays()
* and is faster
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Day.php';
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('m');
if (!isset($_GET['d'])) $_GET['d'] = date('d');
 
// Build the month
$Month = new Calendar_Month_Weekdays($_GET['y'],$_GET['m']);
 
// Construct strings for next/previous links
$PMonth = $Month->prevMonth('object'); // Get previous month as object
$prev = $_SERVER['PHP_SELF'].'?y='.$PMonth->thisYear().'&m='.$PMonth->thisMonth().'&d='.$PMonth->thisDay();
$NMonth = $Month->nextMonth('object');
$next = $_SERVER['PHP_SELF'].'?y='.$NMonth->thisYear().'&m='.$NMonth->thisMonth().'&d='.$NMonth->thisDay();
?>
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Calendar </title>
<style text="text/css">
table {
background-color: silver;
}
caption {
font-family: verdana;
font-size: 12px;
background-color: while;
}
.prevMonth {
font-size: 10px;
text-align: left;
}
.nextMonth {
font-size: 10px;
text-align: right;
}
th {
font-family: verdana;
font-size: 11px;
color: navy;
text-align: right;
}
td {
font-family: verdana;
font-size: 11px;
text-align: right;
}
.selected {
background-color: yellow;
}
</style>
</head>
 
<body>
 
<?php
$selectedDays = array (
new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']),
new Calendar_Day($_GET['y'],12,25),
);
 
// Build the days in the month
$Month->build($selectedDays);
?>
<h2>Built with Calendar_Month_Weekday::build()</h2>
<table class="calendar">
<caption>
<?php echo ( date('F Y',$Month->getTimeStamp())); ?>
</caption>
<tr>
<th>M</th>
<th>T</th>
<th>W</th>
<th>T</th>
<th>F</th>
<th>S</th>
<th>S</th>
</tr>
<?php
while ( $Day = $Month->fetch() ) {
 
// Build a link string for each day
$link = $_SERVER['PHP_SELF'].
'?y='.$Day->thisYear().
'&m='.$Day->thisMonth().
'&d='.$Day->thisDay();
 
// isFirst() to find start of week
if ( $Day->isFirst() )
echo ( "<tr>\n" );
 
if ( $Day->isSelected() ) {
echo ( "<td class=\"selected\">".$Day->thisDay()."</td>\n" );
} else if ( $Day->isEmpty() ) {
echo ( "<td>&nbsp;</td>\n" );
} else {
echo ( "<td><a href=\"".$link."\">".$Day->thisDay()."</a></td>\n" );
}
 
// isLast() to find end of week
if ( $Day->isLast() )
echo ( "</tr>\n" );
}
?>
<tr>
<td>
<a href="<?php echo ($prev);?>" class="prevMonth"><< </a>
</td>
<td colspan="5">&nbsp;</td>
<td>
<a href="<?php echo ($next);?>" class="nextMonth"> >></a>
</td>
</tr>
</table>
<?php
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' );
?>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/16.php
New file
0,0 → 1,31
<?php
/**
* Description: demonstrates using the Uri decorator
*/
if (!@include 'Calendar/Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Decorator/Uri.php';
 
if (!isset($_GET['jahr'])) $_GET['jahr'] = date('Y');
if (!isset($_GET['monat'])) $_GET['monat'] = date('m');
 
// Build the month
$Calendar = new Calendar_Month_Weekdays($_GET['jahr'], $_GET['monat']);
 
echo ( '<p>The current month is '
.$Calendar->thisMonth().' of year '.$Calendar->thisYear().'</p>');
 
$Uri = & new Calendar_Decorator_Uri($Calendar);
$Uri->setFragments('jahr','monat');
// $Uri->setSeperator('/'); // Default is &
// $Uri->setScalar(); // Omit variable names
echo ( "<pre>Previous Uri:\t".$Uri->prev('month')."\n" );
echo ( "This Uri:\t".$Uri->this('month')."\n" );
echo ( "Next Uri:\t".$Uri->next('month')."\n</pre>" );
?>
<p>
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->prev('month'));?>">Prev</a> :
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->next('month'));?>">Next</a>
</p>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/17.php
New file
0,0 → 1,71
<?php
/**
* Description: demonstrates using the Textual decorator
*/
 
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Day.php';
require_once CALENDAR_ROOT.'Month'.DIRECTORY_SEPARATOR.'Weekdays.php';
require_once CALENDAR_ROOT.'Decorator'.DIRECTORY_SEPARATOR.'Textual.php';
 
// Could change language like this
// setlocale (LC_TIME, "de_DE"); // Unix based (probably)
// setlocale (LC_TIME, "ge"); // Windows
 
echo "<hr>Calling: Calendar_Decorator_Textual::monthNames('long');<pre>";
print_r(Calendar_Decorator_Textual::monthNames('long'));
echo '</pre>';
 
echo "<hr>Calling: Calendar_Decorator_Textual::weekdayNames('two');<pre>";
print_r(Calendar_Decorator_Textual::weekdayNames('two'));
echo '</pre>';
 
echo "<hr>Creating: new Calendar_Day(date('Y'), date('n'), date('d'));<br />";
$Calendar = new Calendar_Day(date('Y'), date('n'), date('d'));
 
// Decorate
$Textual = & new Calendar_Decorator_Textual($Calendar);
 
echo '<hr>Previous month is: '.$Textual->prevMonthName('two').'<br />';
echo 'This month is: '.$Textual->thisMonthName('short').'<br />';
echo 'Next month is: '.$Textual->nextMonthName().'<br /><hr />';
echo 'Previous day is: '.$Textual->prevDayName().'<br />';
echo 'This day is: '.$Textual->thisDayName('short').'<br />';
echo 'Next day is: '.$Textual->nextDayName('one').'<br /><hr />';
 
echo "Creating: new Calendar_Month_Weekdays(date('Y'), date('n'), 6); - Saturday is first day of week<br />";
$Calendar = new Calendar_Month_Weekdays(date('Y'), date('n'), 6);
 
// Decorate
$Textual = & new Calendar_Decorator_Textual($Calendar);
?>
<p>Rendering calendar....</p>
<table>
<caption><?php echo $Textual->thisMonthName().' '.$Textual->thisYear(); ?></caption>
<tr>
<?php
$dayheaders = $Textual->orderedWeekdays('short');
foreach ($dayheaders as $dayheader) {
echo '<th>'.$dayheader.'</th>';
}
?>
</tr>
<?php
$Calendar->build();
while ($Day = $Calendar->fetch()) {
if ($Day->isFirst()) {
echo "<tr>\n";
}
if ($Day->isEmpty()) {
echo '<td>&nbsp;</td>';
} else {
echo '<td>'.$Day->thisDay().'</td>';
}
if ($Day->isLast()) {
echo "</tr>\n";
}
}
?>
</table>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/5.phps
New file
0,0 → 1,132
<?php
/**
* Description: generating elements of a form with PEAR::Calendar, using
* selections as well as validating the submission
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Year.php';
require_once CALENDAR_ROOT.'Month.php';
require_once CALENDAR_ROOT.'Day.php';
require_once CALENDAR_ROOT.'Hour.php';
require_once CALENDAR_ROOT.'Minute.php';
require_once CALENDAR_ROOT.'Second.php';
 
// Initialize if not set
if (!isset($_POST['y'])) $_POST['y'] = date('Y');
if (!isset($_POST['m'])) $_POST['m'] = date('n');
if (!isset($_POST['d'])) $_POST['d'] = date('j');
if (!isset($_POST['h'])) $_POST['h'] = date('H');
if (!isset($_POST['i'])) $_POST['i'] = date('i');
if (!isset($_POST['s'])) $_POST['s'] = date('s');
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Select and Update </title>
</head>
<body>
<h1>Select and Update</h1>
<?php
if ( isset($_POST['update']) ) {
$Second = & new Calendar_Second($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h'],$_POST['i'],$_POST['s']);
if ( !$Second->isValid() ) {
$V= & $Second->getValidator();
echo ('<p>Validation failed:</p>' );
while ( $error = $V->fetch() ) {
echo ( $error->toString() .'<br>' );
}
} else {
echo ('<p>Validation success.</p>' );
echo ( '<p>New timestamp is: '.$Second->getTimeStamp().' which could be used to update a database, for example');
}
} else {
$Year = new Calendar_Year($_POST['y']);
$Month = new Calendar_Month($_POST['y'],$_POST['m']);
$Day = new Calendar_Day($_POST['y'],$_POST['m'],$_POST['d']);
$Hour = new Calendar_Hour($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h']);
$Minute = new Calendar_Minute($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h'],$_POST['i']);
$Second = new Calendar_Second($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h'],$_POST['i'],$_POST['s']);
?>
<p><b>Set the alarm clock</p></p>
<form action="<?php echo ( $_SERVER['PHP_SELF'] ); ?>" method="post">
Year: <input type="text" name="y" value="<?php echo ( $_POST['y'] ); ?>" size="4">&nbsp;
Month:<select name="m">
<?php
$selection = array($Month);
$Year->build($selection);
while ( $Child = & $Year->fetch() ) {
if ( $Child->isSelected() ) {
echo ( "<option value=\"".$Child->thisMonth()."\" selected>".$Child->thisMonth()."\n" );
} else {
echo ( "<option value=\"".$Child->thisMonth()."\">".$Child->thisMonth()."\n" );
}
}
?>
</select>&nbsp;
Day:<select name="d">
<?php
$selection = array($Day);
$Month->build($selection);
while ( $Child = & $Month->fetch() ) {
if ( $Child->isSelected() ) {
echo ( "<option value=\"".$Child->thisDay()."\" selected>".$Child->thisDay()."\n" );
} else {
echo ( "<option value=\"".$Child->thisDay()."\">".$Child->thisDay()."\n" );
}
}
?>
</select>&nbsp;
Hour:<select name="h">
<?php
$selection = array($Hour);
$Day->build($selection);
while ( $Child = & $Day->fetch() ) {
if ( $Child->isSelected() ) {
echo ( "<option value=\"".$Child->thisHour()."\" selected>".$Child->thisHour()."\n" );
} else {
echo ( "<option value=\"".$Child->thisHour()."\">".$Child->thisHour()."\n" );
}
}
?>
</select>&nbsp;
Minute:<select name="i">
<?php
$selection = array($Minute);
$Hour->build($selection);
while ( $Child = & $Hour->fetch() ) {
if ( $Child->isSelected() ) {
echo ( "<option value=\"".$Child->thisMinute()."\" selected>".$Child->thisMinute()."\n" );
} else {
echo ( "<option value=\"".$Child->thisMinute()."\">".$Child->thisMinute()."\n" );
}
}
?>
</select>&nbsp;
Second:<select name="s">
<?php
$selection = array($Second);
$Minute->build($selection);
while ( $Child = & $Minute->fetch() ) {
if ( $Child->isSelected() ) {
echo ( "<option value=\"".$Child->thisSecond()."\" selected>".$Child->thisSecond()."\n" );
} else {
echo ( "<option value=\"".$Child->thisSecond()."\">".$Child->thisSecond()."\n" );
}
}
?>
</select>&nbsp;
<input type="submit" name="update" value="Set Alarm"><br>
<?php
}
?>
<?php echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); ?>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/18.php
New file
0,0 → 1,36
<?php
/**
* Description: demonstrates using the Wrapper decorator
*/
 
if (!@include 'Calendar/Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Month.php';
require_once CALENDAR_ROOT.'Decorator.php'; // Not really needed but added to help this make sense
require_once CALENDAR_ROOT.'Decorator/Wrapper.php';
 
class MyBoldDecorator extends Calendar_Decorator
{
function MyBoldDecorator(&$Calendar)
{
parent::Calendar_Decorator($Calendar);
}
 
function thisDay()
{
return '<b>'.parent::thisDay().'</b>';
}
}
 
$Month = new Calendar_Month(date('Y'), date('n'));
 
$Wrapper = & new Calendar_Decorator_Wrapper($Month);
$Wrapper->build();
 
echo '<h2>The Wrapper decorator</h2>';
echo '<i>Day numbers are rendered in bold</i><br /> <br />';
while ($DecoratedDay = $Wrapper->fetch('MyBoldDecorator')) {
echo $DecoratedDay->thisDay().'<br />';
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/19.php
New file
0,0 → 1,24
<?php
/**
* Description: demonstrates using the Weekday decorator
*/
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Day.php';
require_once CALENDAR_ROOT.'Decorator/Weekday.php';
 
$Day = new Calendar_Day(date('Y'), date('n'),date('d'));
$WeekDay = & new Calendar_Decorator_Weekday($Day);
// $WeekDay->setFirstDay(0); // Make Sunday first Day
 
echo 'Yesterday: '.$WeekDay->prevWeekDay().'<br>';
echo 'Today: '.$WeekDay->thisWeekDay().'<br>';
echo 'Tomorrow: '.$WeekDay->nextWeekDay().'<br>';
 
$WeekDay->build();
echo 'Hours today:<br>';
while ( $Hour = $WeekDay->fetch() ) {
echo $Hour->thisHour().'<br>';
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/7.phps
New file
0,0 → 1,92
<?php
/**
* Description: a SOAP Calendar Server
*/
if (!@include('SOAP'.DIRECTORY_SEPARATOR.'Server.php')) {
die('You must have PEAR::SOAP installed');
}
 
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
 
class Calendar_Server
{
var $__dispatch_map = array();
var $__typedef = array();
 
function Calendar_Server()
{
$this->__dispatch_map['getMonth'] =
array('in' => array('year' => 'int', 'month'=>'int'),
'out' => array('month' => '{urn:PEAR_SOAP_Calendar}Month'),
);
$this->__typedef['Month'] = array (
'monthname' => 'string',
'days' => '{urn:PEAR_SOAP_Calendar}MonthDays'
);
$this->__typedef['MonthDays'] = array (array ('{urn:PEAR_SOAP_Calendar}Day'));
$this->__typedef['Day'] = array (
'isFirst' => 'int',
'isLast' => 'int',
'isEmpty' => 'int',
'day' => 'int' );
}
 
function __dispatch($methodname)
{
if (isset($this->__dispatch_map[$methodname]))
return $this->__dispatch_map[$methodname];
return NULL;
}
 
function getMonth($year, $month)
{
require_once(CALENDAR_ROOT.'Month'.DIRECTORY_SEPARATOR.'Weekdays.php');
$Month = & new Calendar_Month_Weekdays($year,$month);
if (!$Month->isValid()) {
$V = & $Month->getValidator();
$errorMsg = '';
while ($error = $V->fetch()) {
$errorMsg .= $error->toString()."\n";
}
return new SOAP_Fault($errorMsg, 'Client');
} else {
$monthname = date('F Y', $Month->getTimeStamp());
$days = array();
$Month->build();
while ($Day = & $Month->fetch()) {
$day = array(
'isFirst' => (int)$Day->isFirst(),
'isLast' => (int)$Day->isLast(),
'isEmpty' => (int)$Day->isEmpty(),
'day' => (int)$Day->thisDay(),
);
$days[] = $day;
}
return array('monthname' => $monthname, 'days' => $days);
}
}
}
 
$server = new SOAP_Server();
$server->_auto_translation = true;
$calendar = new Calendar_Server();
$server->addObjectMap($calendar, 'urn:PEAR_SOAP_Calendar');
 
if (strtoupper($_SERVER['REQUEST_METHOD'])=='POST') {
$server->service($GLOBALS['HTTP_RAW_POST_DATA']);
} else {
require_once 'SOAP'.DIRECTORY_SEPARATOR.'Disco.php';
$disco = new SOAP_DISCO_Server($server, "PEAR_SOAP_Calendar");
if (isset($_SERVER['QUERY_STRING']) &&
strcasecmp($_SERVER['QUERY_STRING'], 'wsdl')==0) {
header("Content-type: text/xml");
echo $disco->getWSDL();
} else {
echo 'This is a PEAR::SOAP Calendar Server. For client try <a href="8.php">here</a><br />';
echo 'For WSDL try <a href="?wsdl">here</a>';
}
exit;
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/9.phps
New file
0,0 → 1,16
<?php
/**
* Description: simple example on i18N
*/
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Day.php';
 
$Day = & new Calendar_Day(2003,10,23);
 
setlocale (LC_TIME, "de_DE"); // Unix based (probably)
// setlocale (LC_TIME, "ge"); // Windows
 
echo ( strftime('%A %d %B %Y',$Day->getTimeStamp()));
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/1.php
New file
0,0 → 1,92
<?php
/**
* Description: Passes through all main calendar classes, beginning with year
* and down to seconds, skipping weeks. Useful to test Calendar is (basically)
* working correctly
*
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
 
if (!isset($_GET['y'])) $_GET['y'] = 2003;
if (!isset($_GET['m'])) $_GET['m'] = 8;
if (!isset($_GET['d'])) $_GET['d'] = 9;
if (!isset($_GET['h'])) $_GET['h'] = 12;
if (!isset($_GET['i'])) $_GET['i'] = 34;
if (!isset($_GET['s'])) $_GET['s'] = 46;
 
switch ( @$_GET['view'] ) {
default:
$_GET['view'] = 'calendar_year';
case 'calendar_year':
require_once CALENDAR_ROOT.'Year.php';
$c = new Calendar_Year($_GET['y']);
break;
case 'calendar_month':
require_once CALENDAR_ROOT.'Month.php';
$c = new Calendar_Month($_GET['y'],$_GET['m']);
break;
case 'calendar_day':
require_once CALENDAR_ROOT.'Day.php';
$c = new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']);
break;
case 'calendar_hour':
require_once CALENDAR_ROOT.'Hour.php';
$c = new Calendar_Hour($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h']);
break;
case 'calendar_minute':
require_once CALENDAR_ROOT.'Minute.php';
$c = new Calendar_Minute($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i']);
break;
case 'calendar_second':
require_once CALENDAR_ROOT.'Second.php';
$c = new Calendar_Second($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i'],$_GET['s']);
break;
}
 
echo ( 'Viewing: '.@$_GET['view'].'<br />' );
echo ( 'The time is now: '.date('Y M d H:i:s',$c->getTimestamp()).'<br >' );
 
$i = 1;
echo ( '<h1>First Iteration</h1>' );
echo ( '<p>The first iteration is more "expensive", the calendar data
structures having to be built.</p>' );
$start = getmicrotime();
$c->build();
while ( $e = $c->fetch() ) {
$class = strtolower(get_class($e));
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay().
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond();
$method = 'this'.str_replace('calendar_','',$class);
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " );
if ( ($i % 10) == 0 ) {
echo ( '<br>' );
}
$i++;
}
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' );
 
$i = 1;
echo ( '<h1>Second Iteration</h1>' );
echo ( '<p>This second iteration is faster, the data structures
being re-used</p>' );
$start = getmicrotime();
while ( $e = $c->fetch() ) {
$class = strtolower(get_class($e));
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay().
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond();
$method = 'this'.str_replace('calendar_','',$class);
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " );
if ( ($i % 10) == 0 ) {
echo ( '<br>' );
}
$i++;
}
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' );
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/2.php
New file
0,0 → 1,142
<?php
/**
* Description: Demonstrates building a calendar for a month using the Week class
* Uses UnixTs engine
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
// Force UnixTs engine (default setting)
define('CALENDAR_ENGINE','UnixTS');
 
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Month/Weeks.php';
require_once CALENDAR_ROOT.'Day.php';
 
// Initialize GET variables if not set
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('m');
if (!isset($_GET['d'])) $_GET['d'] = date('d');
 
// Build a month object
$Month = new Calendar_Month_Weeks($_GET['y'], $_GET['m']);
 
// Create an array of days which are "selected"
// Used for Week::build() below
$selectedDays = array (
new Calendar_Day($_GET['y'],$_GET['m'], $_GET['d']),
new Calendar_Day($_GET['y'], 12, 25),
new Calendar_Day(date('Y'), date('m'), date('d')),
);
 
// Instruct month to build Week objects
$Month->build();
 
// Construct strings for next/previous links
$PMonth = $Month->prevMonth('object'); // Get previous month as object
$prev = $_SERVER['PHP_SELF'].'?y='.$PMonth->thisYear().'&m='.$PMonth->thisMonth().'&d='.$PMonth->thisDay();
$NMonth = $Month->nextMonth('object');
$next = $_SERVER['PHP_SELF'].'?y='.$NMonth->thisYear().'&m='.$NMonth->thisMonth().'&d='.$NMonth->thisDay();
?>
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Calendar </title>
<style text="text/css">
table {
background-color: silver;
}
caption {
font-family: verdana;
font-size: 12px;
background-color: while;
}
.prevMonth {
font-size: 10px;
text-align: left;
}
.nextMonth {
font-size: 10px;
text-align: right;
}
th {
font-family: verdana;
font-size: 11px;
color: navy;
text-align: right;
}
td {
font-family: verdana;
font-size: 11px;
text-align: right;
}
.selected {
background-color: yellow;
}
.empty {
color: white;
}
</style>
</head>
 
<body>
<h2>Build with Calendar_Month_Weeks::build() then Calendar_Week::build()</h2>
<table class="calendar">
<caption>
<?php echo date('F Y', $Month->getTimeStamp()); ?>
</caption>
<tr>
<th>M</th>
<th>T</th>
<th>W</th>
<th>T</th>
<th>F</th>
<th>S</th>
<th>S</th>
</tr>
<?php
while ($Week = $Month->fetch()) {
echo "<tr>\n";
// Build the days in the week, passing the selected days
$Week->build($selectedDays);
while ($Day = $Week->fetch()) {
 
// Build a link string for each day
$link = $_SERVER['PHP_SELF'].
'?y='.$Day->thisYear().
'&m='.$Day->thisMonth().
'&d='.$Day->thisDay();
 
// Check to see if day is selected
if ($Day->isSelected()) {
echo '<td class="selected">'.$Day->thisDay().'</td>'."\n";
// Check to see if day is empty
} else if ($Day->isEmpty()) {
echo '<td class="empty">'.$Day->thisDay().'</td>'."\n";
} else {
echo '<td><a href="'.$link.'">'.$Day->thisDay().'</a></td>'."\n";
}
}
echo '</tr>'."\n";
}
?>
<tr>
<td>
<a href="<?php echo $prev; ?>" class="prevMonth"><< </a>
</td>
<td colspan="5">&nbsp;</td>
<td>
<a href="<?php echo $next; ?>" class="nextMonth"> >></a>
</td>
</tr>
</table>
<?php
echo '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>';
?>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/3.php
New file
0,0 → 1,134
<?php
/**
* Description: Performs same behaviour as 2.php but uses Month::buildWeekDays()
* and is faster
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Day.php';
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('m');
if (!isset($_GET['d'])) $_GET['d'] = date('d');
 
// Build the month
$Month = new Calendar_Month_Weekdays($_GET['y'],$_GET['m']);
 
// Construct strings for next/previous links
$PMonth = $Month->prevMonth('object'); // Get previous month as object
$prev = $_SERVER['PHP_SELF'].'?y='.$PMonth->thisYear().'&m='.$PMonth->thisMonth().'&d='.$PMonth->thisDay();
$NMonth = $Month->nextMonth('object');
$next = $_SERVER['PHP_SELF'].'?y='.$NMonth->thisYear().'&m='.$NMonth->thisMonth().'&d='.$NMonth->thisDay();
?>
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Calendar </title>
<style text="text/css">
table {
background-color: silver;
}
caption {
font-family: verdana;
font-size: 12px;
background-color: while;
}
.prevMonth {
font-size: 10px;
text-align: left;
}
.nextMonth {
font-size: 10px;
text-align: right;
}
th {
font-family: verdana;
font-size: 11px;
color: navy;
text-align: right;
}
td {
font-family: verdana;
font-size: 11px;
text-align: right;
}
.selected {
background-color: yellow;
}
</style>
</head>
 
<body>
 
<?php
$selectedDays = array (
new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']),
new Calendar_Day($_GET['y'],12,25),
);
 
// Build the days in the month
$Month->build($selectedDays);
?>
<h2>Built with Calendar_Month_Weekday::build()</h2>
<table class="calendar">
<caption>
<?php echo ( date('F Y',$Month->getTimeStamp())); ?>
</caption>
<tr>
<th>M</th>
<th>T</th>
<th>W</th>
<th>T</th>
<th>F</th>
<th>S</th>
<th>S</th>
</tr>
<?php
while ( $Day = $Month->fetch() ) {
 
// Build a link string for each day
$link = $_SERVER['PHP_SELF'].
'?y='.$Day->thisYear().
'&m='.$Day->thisMonth().
'&d='.$Day->thisDay();
 
// isFirst() to find start of week
if ( $Day->isFirst() )
echo ( "<tr>\n" );
 
if ( $Day->isSelected() ) {
echo ( "<td class=\"selected\">".$Day->thisDay()."</td>\n" );
} else if ( $Day->isEmpty() ) {
echo ( "<td>&nbsp;</td>\n" );
} else {
echo ( "<td><a href=\"".$link."\">".$Day->thisDay()."</a></td>\n" );
}
 
// isLast() to find end of week
if ( $Day->isLast() )
echo ( "</tr>\n" );
}
?>
<tr>
<td>
<a href="<?php echo ($prev);?>" class="prevMonth"><< </a>
</td>
<td colspan="5">&nbsp;</td>
<td>
<a href="<?php echo ($next);?>" class="nextMonth"> >></a>
</td>
</tr>
</table>
<?php
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' );
?>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/4.php
New file
0,0 → 1,49
<?php
/**
* Description: shows how to perform validation with PEAR::Calendar
*/
function getmicrotime(){
list($usec, $sec) = explode(' ', microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Second.php';
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('n');
if (!isset($_GET['d'])) $_GET['d'] = date('j');
if (!isset($_GET['h'])) $_GET['h'] = date('H');
if (!isset($_GET['i'])) $_GET['i'] = date('i');
if (!isset($_GET['s'])) $_GET['s'] = date('s');
 
$Unit = & new Calendar_Second($_GET['y'], $_GET['m'], $_GET['d'], $_GET['h'], $_GET['i'], $_GET['s']);
 
echo '<p><b>Result:</b> '.$Unit->thisYear().'-'.$Unit->thisMonth().'-'.$Unit->thisDay().
' '.$Unit->thisHour().':'.$Unit->thisMinute().':'.$Unit->thisSecond();
if ($Unit->isValid()) {
echo ' is valid!</p>';
} else {
$V= & $Unit->getValidator();
echo ' is invalid:</p>';
while ($error = $V->fetch()) {
echo $error->toString() .'<br />';
}
}
?>
<p>Enter a date / time to validate:</p>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
Year: <input type="text" name="y" value="2039"><br />
Month: <input type="text" name="m" value="13"><br />
Day: <input type="text" name="d" value="32"><br />
Hour: <input type="text" name="h" value="24"><br />
Minute: <input type="text" name="i" value="-1"><br />
Second: <input type="text" name="s" value="60"><br />
<input type="submit" value="Validate">
</form>
<p><b>Note:</b> Error messages can be controlled with the constants <code>CALENDAR_VALUE_TOOSMALL</code> and <code>CALENDAR_VALUE_TOOLARGE</code> - see <code>Calendar_Validator.php</code></p>
 
<?php echo '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>'; ?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/5.php
New file
0,0 → 1,132
<?php
/**
* Description: generating elements of a form with PEAR::Calendar, using
* selections as well as validating the submission
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Year.php';
require_once CALENDAR_ROOT.'Month.php';
require_once CALENDAR_ROOT.'Day.php';
require_once CALENDAR_ROOT.'Hour.php';
require_once CALENDAR_ROOT.'Minute.php';
require_once CALENDAR_ROOT.'Second.php';
 
// Initialize if not set
if (!isset($_POST['y'])) $_POST['y'] = date('Y');
if (!isset($_POST['m'])) $_POST['m'] = date('n');
if (!isset($_POST['d'])) $_POST['d'] = date('j');
if (!isset($_POST['h'])) $_POST['h'] = date('H');
if (!isset($_POST['i'])) $_POST['i'] = date('i');
if (!isset($_POST['s'])) $_POST['s'] = date('s');
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Select and Update </title>
</head>
<body>
<h1>Select and Update</h1>
<?php
if ( isset($_POST['update']) ) {
$Second = & new Calendar_Second($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h'],$_POST['i'],$_POST['s']);
if ( !$Second->isValid() ) {
$V= & $Second->getValidator();
echo ('<p>Validation failed:</p>' );
while ( $error = $V->fetch() ) {
echo ( $error->toString() .'<br>' );
}
} else {
echo ('<p>Validation success.</p>' );
echo ( '<p>New timestamp is: '.$Second->getTimeStamp().' which could be used to update a database, for example');
}
} else {
$Year = new Calendar_Year($_POST['y']);
$Month = new Calendar_Month($_POST['y'],$_POST['m']);
$Day = new Calendar_Day($_POST['y'],$_POST['m'],$_POST['d']);
$Hour = new Calendar_Hour($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h']);
$Minute = new Calendar_Minute($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h'],$_POST['i']);
$Second = new Calendar_Second($_POST['y'],$_POST['m'],$_POST['d'],$_POST['h'],$_POST['i'],$_POST['s']);
?>
<p><b>Set the alarm clock</p></p>
<form action="<?php echo ( $_SERVER['PHP_SELF'] ); ?>" method="post">
Year: <input type="text" name="y" value="<?php echo ( $_POST['y'] ); ?>" size="4">&nbsp;
Month:<select name="m">
<?php
$selection = array($Month);
$Year->build($selection);
while ( $Child = & $Year->fetch() ) {
if ( $Child->isSelected() ) {
echo ( "<option value=\"".$Child->thisMonth()."\" selected>".$Child->thisMonth()."\n" );
} else {
echo ( "<option value=\"".$Child->thisMonth()."\">".$Child->thisMonth()."\n" );
}
}
?>
</select>&nbsp;
Day:<select name="d">
<?php
$selection = array($Day);
$Month->build($selection);
while ( $Child = & $Month->fetch() ) {
if ( $Child->isSelected() ) {
echo ( "<option value=\"".$Child->thisDay()."\" selected>".$Child->thisDay()."\n" );
} else {
echo ( "<option value=\"".$Child->thisDay()."\">".$Child->thisDay()."\n" );
}
}
?>
</select>&nbsp;
Hour:<select name="h">
<?php
$selection = array($Hour);
$Day->build($selection);
while ( $Child = & $Day->fetch() ) {
if ( $Child->isSelected() ) {
echo ( "<option value=\"".$Child->thisHour()."\" selected>".$Child->thisHour()."\n" );
} else {
echo ( "<option value=\"".$Child->thisHour()."\">".$Child->thisHour()."\n" );
}
}
?>
</select>&nbsp;
Minute:<select name="i">
<?php
$selection = array($Minute);
$Hour->build($selection);
while ( $Child = & $Hour->fetch() ) {
if ( $Child->isSelected() ) {
echo ( "<option value=\"".$Child->thisMinute()."\" selected>".$Child->thisMinute()."\n" );
} else {
echo ( "<option value=\"".$Child->thisMinute()."\">".$Child->thisMinute()."\n" );
}
}
?>
</select>&nbsp;
Second:<select name="s">
<?php
$selection = array($Second);
$Minute->build($selection);
while ( $Child = & $Minute->fetch() ) {
if ( $Child->isSelected() ) {
echo ( "<option value=\"".$Child->thisSecond()."\" selected>".$Child->thisSecond()."\n" );
} else {
echo ( "<option value=\"".$Child->thisSecond()."\">".$Child->thisSecond()."\n" );
}
}
?>
</select>&nbsp;
<input type="submit" name="update" value="Set Alarm"><br>
<?php
}
?>
<?php echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); ?>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/11.phps
New file
0,0 → 1,109
<?php
/**
* Description: demonstrates a decorator used to "attach a payload" to a selection
* to make it available when iterating over calendar children
*/
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Day.php';
require_once CALENDAR_ROOT.'Hour.php';
require_once CALENDAR_ROOT.'Decorator.php';
 
// Decorator to "attach" functionality to selected hours
class DiaryEvent extends Calendar_Decorator {
var $entry;
function DiaryEvent($calendar) {
Calendar_Decorator::Calendar_Decorator($calendar);
}
function setEntry($entry) {
$this->entry = $entry;
}
function getEntry() {
return $this->entry;
}
}
 
// Create a day to view the hours for
$Day = & new Calendar_Day(2003,10,24);
 
// A sample query to get the data for today (NOT ACTUALLY USED HERE)
$sql = "
SELECT
*
FROM
diary
WHERE
eventtime >= '".$Day->thisDay(TRUE)."'
AND
eventtime < '".$Day->nextDay(TRUE)."';";
 
// An array simulating data from a database
$result = array (
array('eventtime'=>mktime(9,0,0,10,24,2003),'entry'=>'Meeting with sales team'),
array('eventtime'=>mktime(11,0,0,10,24,2003),'entry'=>'Conference call with Widget Inc.'),
array('eventtime'=>mktime(15,0,0,10,24,2003),'entry'=>'Presentation to board of directors')
);
 
// An array to place selected hours in
$selection = array();
 
// Loop through the "database result"
foreach ( $result as $row ) {
$Hour = new Calendar_Hour(2000,1,1,1); // Create Hour with dummy values
$Hour->setTimeStamp($row['eventtime']); // Set the real time with setTimeStamp
 
// Create the decorator, passing it the Hour
$DiaryEvent = new DiaryEvent($Hour);
 
// Attach the payload
$DiaryEvent->setEntry($row['entry']);
 
// Add the decorator to the selection
$selection[] = $DiaryEvent;
}
 
// Build the hours in that day, passing the selection
$Day->build($selection);
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Passing a Selection Payload with a Decorator </title>
</head>
<body>
<h1>Passing a Selection "Payload" using a Decorator</h1>
<table>
<caption><b>Your Schedule for <?php echo ( date('D nS F Y',$Day->thisDay(TRUE)) ); ?></b></caption>
<tr>
<th width="5%">Time</th>
<th>Entry</th>
</tr>
<?php
while ( $Hour = & $Day->fetch() ) {
 
$hour = $Hour->thisHour();
$minute = $Hour->thisMinute();
 
// Office hours only...
if ( $hour >= 8 && $hour <= 18 ) {
echo ( "<tr>\n" );
echo ( "<td>$hour:$minute</td>\n" );
 
// If the hour is selected, call the decorator method...
if ( $Hour->isSelected() ) {
echo ( "<td bgcolor=\"silver\">".$Hour->getEntry()."</td>\n" );
} else {
echo ( "<td>&nbsp;</td>\n" );
}
echo ( "</tr>\n" );
}
}
?>
</table>
<p>The query to fetch this data, with help from PEAR::Calendar, might be;</p>
<pre>
<?php echo ( $sql ); ?>
</pre>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/6.php
New file
0,0 → 1,210
<?php
/**
* Description: A "personal planner" with some WML for fun
* Note this is done the stupid way - a giant if/else for WML or HTML
* could be greatly simplified with some HTML/WML rendering classes...
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Day.php';
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('n');
if (!isset($_GET['d'])) $_GET['d'] = date('j');
 
$Month = & new Calendar_Month_Weekdays($_GET['y'],$_GET['m']);
$Day = & new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']);
$selection = array($Day);
 
#-----------------------------------------------------------------------------#
if ( isset($_GET['mime']) && $_GET['mime']=='wml' ) {
header ('Content-Type: text/vnd.wap.wml');
echo ( '<?xml version="1.0"?>' );
?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<big><strong>Personal Planner Rendered with WML</strong></big>
<?php
if ( isset($_GET['viewday']) ) {
?>
<p><strong>Viewing <?php echo ( date('l, jS of F, Y',$Day->getTimeStamp()) ); ?></strong></p>
<p>
<anchor>
Back to Month View
<go href="<?php
echo ( "?y=".$Day->thisYear()."&amp;m=".
$Day->thisMonth()."&amp;d=".$Day->thisDay()."&amp;mime=wml" );
?>"/>
</anchor>
</p>
<table>
<?php
$Day->build();
while ( $Hour = & $Day->fetch() ) {
echo ( "<tr>\n" );
echo ( "<td>".date('g a',$Hour->getTimeStamp())."</td><td>Free time!</td>\n" );
echo ( "</tr>\n" );
}
?>
</table>
<?php
} else {
?>
<p><strong><?php echo ( date('F Y',$Month->getTimeStamp()) ); ?></strong></p>
<table>
<tr>
<td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td><td>S</td>
</tr>
<?php
$Month->build($selection);
while ( $Day = $Month->fetch() ) {
if ( $Day->isFirst() ) {
echo ( "<tr>\n" );
}
if ( $Day->isEmpty() ) {
echo ( "<td></td>\n" );
} else if ( $Day->isSelected() ) {
echo ( "<td><anchor><strong><u>".$Day->thisDay()."</u></strong>\n<go href=\"".$_SERVER['PHP_SELF']."?viewday=true&amp;y=".
$Day->thisYear()."&amp;m=".$Day->thisMonth()."&amp;d=".$Day->thisDay().
"&amp;mime=wml\" />\n</anchor></td>\n" );
} else {
echo ( "<td><anchor>".$Day->thisDay()."\n<go href=\"?viewday=true&amp;y=".
$Day->thisYear()."&amp;m=".$Day->thisMonth()."&amp;d=".$Day->thisDay().
"&amp;mime=wml\" /></anchor></td>\n" );
}
if ( $Day->isLast() ) {
echo ( "</tr>\n" );
}
}
?>
<tr>
<td>
<anchor>
&lt;&lt;
<go href="<?php
echo ( "?y=".$Month->thisYear()."&amp;m=".
$Month->prevMonth()."&amp;d=".$Month->thisDay()."&amp;mime=wml" );
?>"/>
</anchor>
</td>
<td></td><td></td><td></td><td></td><td></td>
<td>
<anchor>
&gt;&gt;
<go href="<?php
echo ( "?y=".$Month->thisYear()."&amp;m=".
$Month->nextMonth()."&amp;d=".$Month->thisDay()."&amp;mime=wml" );
?>"/>
</anchor>
</td>
</tr>
</table>
 
<?php
}
?>
<p><a href="<?php echo ( $_SERVER['PHP_SELF'] ); ?>">Back to HTML</a></p>
<?php echo ( '<p>Took: '.(getmicrotime()-$start).' seconds</p>' ); ?>
</wml>
<?php
#-----------------------------------------------------------------------------#
} else {
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> HTML (+WML) Personal Planner </title>
</head>
<body>
<h1>Personal Planner Rendered with HTML</h1>
<p>To view in WML, click <a href="<?php echo ( $_SERVER['PHP_SELF'] ); ?>?mime=wml">here</a> or place a ?mime=wml at the end of any URL.
Note that <a href="http://www.opera.com/download">Opera</a> supports WML natively and Mozilla / Firefox has the WMLBrowser
plugin: <a href="http://wmlbrowser.mozdev.org">wmlbrowser.mozdev.org</a></p>
<?php
if ( isset($_GET['viewday']) ) {
?>
<p><strong>Viewing <?php echo ( date('l, jS of F, Y',$Day->getTimeStamp()) ); ?></strong></p>
<p>
<anchor>
<a href="<?php
echo ( "?y=".$Day->thisYear()."&amp;m=".
$Day->thisMonth()."&amp;d=".$Day->thisDay());
?>">Back to Month View</a>
</p>
<table>
<?php
$Day->build();
while ( $Hour = & $Day->fetch() ) {
echo ( "<tr>\n" );
echo ( "<td>".date('g a',$Hour->getTimeStamp())."</td><td>Free time!</td>\n" );
echo ( "</tr>\n" );
}
?>
</table>
<?php
} else {
?>
<p><strong><?php echo ( date('F Y',$Month->getTimeStamp()) ); ?></strong></p>
<table>
<tr>
<td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td><td>S</td>
</tr>
<?php
$Month->build($selection);
while ( $Day = $Month->fetch() ) {
if ( $Day->isFirst() ) {
echo ( "<tr>\n" );
}
if ( $Day->isEmpty() ) {
echo ( "<td></td>\n" );
} else if ( $Day->isSelected() ) {
echo ( "<td><a href=\"".$_SERVER['PHP_SELF']."?viewday=true&amp;y=".
$Day->thisYear()."&amp;m=".$Day->thisMonth()."&amp;d=".$Day->thisDay().
"&amp;wml\"><strong><u>".$Day->thisDay()."</u></strong></a></td>\n" );
} else {
echo ( "<td><a href=\"".$_SERVER['PHP_SELF']."?viewday=true&amp;y=".
$Day->thisYear()."&amp;m=".$Day->thisMonth()."&amp;d=".$Day->thisDay().
"\">".$Day->thisDay()."</a></td>\n" );
}
if ( $Day->isLast() ) {
echo ( "</tr>\n" );
}
}
?>
<tr>
<td>
<a href="<?php
echo ( "?y=".$Month->thisYear()."&amp;m=".
$Month->prevMonth()."&amp;d=".$Month->thisDay() );
?>">
&lt;&lt;</a>
</td>
<td></td><td></td><td></td><td></td><td></td>
<td>
<a href="<?php
echo ( "?y=".$Month->thisYear()."&amp;m=".
$Month->nextMonth()."&amp;d=".$Month->thisDay() );
?>">&gt;&gt;</a>
</td>
</tr>
</table>
 
<?php
}
?>
 
 
<?php echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' ); ?>
</body>
</html>
<?php
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/21.phps
New file
0,0 → 1,139
<?php
/**
* Description: a complete year with numeric week numbers
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if (!@include 'Calendar/Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
 
require_once CALENDAR_ROOT.'Year.php';
require_once CALENDAR_ROOT.'Month/Weeks.php';
 
define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKS);
 
if (!isset($_GET['year'])) $_GET['year'] = date('Y');
 
$week_types = array(
'n_in_year',
'n_in_month',
);
 
if (!isset($_GET['week_type']) || !in_array($_GET['week_type'],$week_types) ) {
$_GET['week_type'] = 'n_in_year';
}
 
$Year = new Calendar_Year($_GET['year']);
 
$Year->build();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> <?php echo $Year->thisYear(); ?> </title>
<style type="text/css">
body {
font-family: Georgia, serif;
}
caption.year {
font-weight: bold;
font-size: 120%;
font-color: navy;
}
caption.month {
font-size: 110%;
font-color: navy;
}
table.month {
border: thin groove #800080
}
tr {
vertical-align: top;
}
th, td {
text-align: right;
font-size: 70%;
}
#prev {
float: left;
font-size: 70%;
}
#next {
float: right;
font-size: 70%;
}
#week_type {
float: none;
font-size: 70%;
}
.weekNumbers {
background-color: #e5e5f5;
padding-right: 3pt;
}
</style>
</head>
<body>
<table>
<caption class="year">
<?php echo $Year->thisYear(); ?>
<div id="next">
<a href="?year=<?php echo $Year->nextYear(); ?>&week_type=<?php echo $_GET['week_type']; ?>">>></a>
</div>
<div id="prev">
<a href="?year=<?php echo $Year->prevYear(); ?>&week_type=<?php echo $_GET['week_type']; ?>"><<</a>
</div>
<div id="week_type">
<a href="?year=<?php echo $Year->thisYear(); ?>&week_type=n_in_year">Weeks by Year</a> :
<a href="?year=<?php echo $Year->thisYear(); ?>&week_type=n_in_month">Weeks by Month</a>
</div>
</caption>
<?php
$i = 0;
while ($Month = $Year->fetch()) {
 
switch ($i) {
case 0:
echo "<tr>\n";
break;
case 3:
case 6:
case 9:
echo "</tr>\n<tr>\n";
break;
case 12:
echo "</tr>\n";
break;
}
 
echo "<td>\n<table class=\"month\">\n";
echo '<caption class="month">'.date('F', $Month->thisMonth(TRUE)).'</caption>';
echo '<colgroup><col class="weekNumbers"><col span="7"></colgroup>'."\n";
echo "<tr>\n<th>Week</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th>\n</tr>";
$Month->build();
while ($Week = $Month->fetch()) {
echo "<tr>\n";
echo '<td>'.$Week->thisWeek($_GET['week_type'])."</td>\n";
$Week->build();
 
while ($Day = $Week->fetch()) {
if ($Day->isEmpty()) {
echo "<td>&nbsp;</td>\n";
} else {
echo "<td>".$Day->thisDay()."</td>\n";
}
}
}
echo "</table>\n</td>\n";
 
$i++;
}
?>
</table>
<p>Took: <?php echo ((getmicrotime()-$start)); ?></p>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/7.php
New file
0,0 → 1,92
<?php
/**
* Description: a SOAP Calendar Server
*/
if (!@include('SOAP'.DIRECTORY_SEPARATOR.'Server.php')) {
die('You must have PEAR::SOAP installed');
}
 
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
 
class Calendar_Server
{
var $__dispatch_map = array();
var $__typedef = array();
 
function Calendar_Server()
{
$this->__dispatch_map['getMonth'] =
array('in' => array('year' => 'int', 'month'=>'int'),
'out' => array('month' => '{urn:PEAR_SOAP_Calendar}Month'),
);
$this->__typedef['Month'] = array (
'monthname' => 'string',
'days' => '{urn:PEAR_SOAP_Calendar}MonthDays'
);
$this->__typedef['MonthDays'] = array (array ('{urn:PEAR_SOAP_Calendar}Day'));
$this->__typedef['Day'] = array (
'isFirst' => 'int',
'isLast' => 'int',
'isEmpty' => 'int',
'day' => 'int' );
}
 
function __dispatch($methodname)
{
if (isset($this->__dispatch_map[$methodname]))
return $this->__dispatch_map[$methodname];
return NULL;
}
 
function getMonth($year, $month)
{
require_once(CALENDAR_ROOT.'Month'.DIRECTORY_SEPARATOR.'Weekdays.php');
$Month = & new Calendar_Month_Weekdays($year,$month);
if (!$Month->isValid()) {
$V = & $Month->getValidator();
$errorMsg = '';
while ($error = $V->fetch()) {
$errorMsg .= $error->toString()."\n";
}
return new SOAP_Fault($errorMsg, 'Client');
} else {
$monthname = date('F Y', $Month->getTimeStamp());
$days = array();
$Month->build();
while ($Day = & $Month->fetch()) {
$day = array(
'isFirst' => (int)$Day->isFirst(),
'isLast' => (int)$Day->isLast(),
'isEmpty' => (int)$Day->isEmpty(),
'day' => (int)$Day->thisDay(),
);
$days[] = $day;
}
return array('monthname' => $monthname, 'days' => $days);
}
}
}
 
$server = new SOAP_Server();
$server->_auto_translation = true;
$calendar = new Calendar_Server();
$server->addObjectMap($calendar, 'urn:PEAR_SOAP_Calendar');
 
if (strtoupper($_SERVER['REQUEST_METHOD'])=='POST') {
$server->service($GLOBALS['HTTP_RAW_POST_DATA']);
} else {
require_once 'SOAP'.DIRECTORY_SEPARATOR.'Disco.php';
$disco = new SOAP_DISCO_Server($server, "PEAR_SOAP_Calendar");
if (isset($_SERVER['QUERY_STRING']) &&
strcasecmp($_SERVER['QUERY_STRING'], 'wsdl')==0) {
header("Content-type: text/xml");
echo $disco->getWSDL();
} else {
echo 'This is a PEAR::SOAP Calendar Server. For client try <a href="8.php">here</a><br />';
echo 'For WSDL try <a href="?wsdl">here</a>';
}
exit;
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/13.phps
New file
0,0 → 1,99
<?php
/**
* Description: same as 1.php, but using the PEAR::Date engine
* Notice the use of the CALENDAR_ENGINE constant, which
* switches the calculation "engine"
* Note: make sure PEAR::Date is a stable release!!!
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
 
// Switch to PEAR::Date engine
define('CALENDAR_ENGINE','PearDate');
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
 
if (!isset($_GET['y'])) $_GET['y'] = 2003;
if (!isset($_GET['m'])) $_GET['m'] = 8;
if (!isset($_GET['d'])) $_GET['d'] = 9;
if (!isset($_GET['h'])) $_GET['h'] = 12;
if (!isset($_GET['i'])) $_GET['i'] = 34;
if (!isset($_GET['s'])) $_GET['s'] = 46;
 
switch ( @$_GET['view'] ) {
default:
$_GET['view'] = 'calendar_year';
case 'calendar_year':
require_once CALENDAR_ROOT.'Year.php';
$c = new Calendar_Year($_GET['y']);
break;
case 'calendar_month':
require_once CALENDAR_ROOT.'Month.php';
$c = new Calendar_Month($_GET['y'],$_GET['m']);
break;
case 'calendar_day':
require_once CALENDAR_ROOT.'Day.php';
$c = new Calendar_Day($_GET['y'],$_GET['m'],$_GET['d']);
break;
case 'calendar_hour':
require_once CALENDAR_ROOT.'Hour.php';
$c = new Calendar_Hour($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h']);
break;
case 'calendar_minute':
require_once CALENDAR_ROOT.'Minute.php';
$c = new Calendar_Minute($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i']);
break;
case 'calendar_second':
require_once CALENDAR_ROOT.'Second.php';
$c = new Calendar_Second($_GET['y'],$_GET['m'],$_GET['d'],$_GET['h'],$_GET['i'],$_GET['s']);
break;
}
 
// Convert timestamp to human readable date
$date = new Date($c->getTimestamp());
 
echo ( '<h1>Using PEAR::Date engine</h1>' );
echo ( 'Viewing: '.@$_GET['view'].'<br />' );
echo ( 'The time is now: '.$date->format('%Y %a %e %T').'<br >' );
 
$i = 1;
echo ( '<h1>First Iteration</h1>' );
echo ( '<p>The first iteration is more "expensive", the calendar data
structures having to be built.</p>' );
$start = getmicrotime();
$c->build();
while ( $e = $c->fetch() ) {
$class = strtolower(get_class($e));
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay().
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond();
$method = 'this'.str_replace('calendar_','',$class);
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " );
if ( ($i % 10) == 0 ) {
echo ( '<br>' );
}
$i++;
}
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' );
 
$i = 1;
echo ( '<h1>Second Iteration</h1>' );
echo ( '<p>This second iteration is faster, the data structures
being re-used</p>' );
$start = getmicrotime();
while ( $e = $c->fetch() ) {
$class = strtolower(get_class($e));
$link ="&y=".$e->thisYear()."&m=".$e->thisMonth()."&d=".$e->thisDay().
"&h=".$e->thisHour()."&i=".$e->thisMinute()."&s=".$e->thisSecond();
$method = 'this'.str_replace('calendar_','',$class);
echo ( "<a href=\"".$_SERVER['PHP_SELF']."?view=".$class.$link."\">".$e->{$method}()."</a> : " );
if ( ($i % 10) == 0 ) {
echo ( '<br>' );
}
$i++;
}
echo ( '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>' );
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/8.php
New file
0,0 → 1,70
<?php
/**
* Description: client for the SOAP Calendar Server
*/
if ( version_compare(phpversion(), "5.0.0", ">") ) {
die('PHP 5 has problems with PEAR::SOAP Client (8.0RC3)
- remove @ before include below to see why');
}
 
if (!@include('SOAP'.DIRECTORY_SEPARATOR.'Client.php')) {
die('You must have PEAR::SOAP installed');
}
 
// Just to save manaul modification...
$basePath = explode('/', $_SERVER['SCRIPT_NAME']);
array_pop($basePath);
$basePath = implode('/', $basePath);
$url = 'http://'.$_SERVER['SERVER_NAME'].$basePath.'/7.php?wsdl';
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('n');
 
$wsdl = new SOAP_WSDL ($url);
 
echo ( '<pre>'.$wsdl->generateProxyCode().'</pre>' );
 
$calendarClient = $wsdl->getProxy();
 
$month = $calendarClient->getMonth((int)$_GET['y'],(int)$_GET['m']);
 
if ( PEAR::isError($month) ) {
die ( $month->toString() );
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Calendar over the Wire </title>
</head>
<body>
<h1>Calendar Over the Wire (featuring PEAR::SOAP)</h1>
<table>
<caption><b><?php echo ( $month->monthname );?></b></caption>
<tr>
<th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th>
</tr>
<?php
foreach ( $month->days as $day ) {
 
if ( $day->isFirst === 1 )
echo ( "<tr>\n" );
if ( $day->isEmpty === 1 ) {
echo ( "<td></td>" );
} else {
echo ( "<td>".$day->day."</td>" );
}
if ( $day->isLast === 1 )
echo ( "</tr>\n" );
}
?>
<tr>
</table>
<p>Enter Year and Month to View:</p>
<form action="<?php echo ( $_SERVER['PHP_SELF'] ); ?>" method="get">
Year: <input type="text" size="4" name="y" value="<?php echo ( $_GET['y'] ); ?>">&nbsp;
Month: <input type="text" size="2" name="m" value="<?php echo ( $_GET['m'] ); ?>">&nbsp;
<input type="submit" value="Fetch Calendar">
</form>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/23.phps
New file
0,0 → 1,66
<?php
/**
* Description: demonstrates using the Textual util
*/
 
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Day.php';
require_once CALENDAR_ROOT.'Month'.DIRECTORY_SEPARATOR.'Weekdays.php';
require_once CALENDAR_ROOT.'Util'.DIRECTORY_SEPARATOR.'Textual.php';
 
// Could change language like this
// setlocale (LC_TIME, "de_DE"); // Unix based (probably)
// setlocale (LC_TIME, "ge"); // Windows
 
echo "<hr>Calling: Calendar_Util_Textual::monthNames('long');<pre>";
print_r(Calendar_Util_Textual::monthNames('long'));
echo '</pre>';
 
echo "<hr>Calling: Calendar_Util_Textual::weekdayNames('two');<pre>";
print_r(Calendar_Util_Textual::weekdayNames('two'));
echo '</pre>';
 
echo "<hr>Creating: new Calendar_Day(date('Y'), date('n'), date('d'));<br />";
$Calendar = new Calendar_Day(date('Y'), date('n'), date('d'));
 
echo '<hr>Previous month is: '.Calendar_Util_Textual::prevMonthName($Calendar,'two').'<br />';
echo 'This month is: '.Calendar_Util_Textual::thisMonthName($Calendar,'short').'<br />';
echo 'Next month is: '.Calendar_Util_Textual::nextMonthName($Calendar).'<br /><hr />';
echo 'Previous day is: '.Calendar_Util_Textual::prevDayName($Calendar).'<br />';
echo 'This day is: '.Calendar_Util_Textual::thisDayName($Calendar,'short').'<br />';
echo 'Next day is: '.Calendar_Util_Textual::nextDayName($Calendar,'one').'<br /><hr />';
 
echo "Creating: new Calendar_Month_Weekdays(date('Y'), date('n'), 6); - Saturday is first day of week<br />";
$Calendar = new Calendar_Month_Weekdays(date('Y'), date('n'), 6);
 
?>
<p>Rendering calendar....</p>
<table>
<caption><?php echo Calendar_Util_Textual::thisMonthName($Calendar).' '.$Calendar->thisYear(); ?></caption>
<tr>
<?php
$dayheaders = Calendar_Util_Textual::orderedWeekdays($Calendar,'short');
foreach ($dayheaders as $dayheader) {
echo '<th>'.$dayheader.'</th>';
}
?>
</tr>
<?php
$Calendar->build();
while ($Day = $Calendar->fetch()) {
if ($Day->isFirst()) {
echo "<tr>\n";
}
if ($Day->isEmpty()) {
echo '<td>&nbsp;</td>';
} else {
echo '<td>'.$Day->thisDay().'</td>';
}
if ($Day->isLast()) {
echo "</tr>\n";
}
}
?>
</table>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/9.php
New file
0,0 → 1,16
<?php
/**
* Description: simple example on i18N
*/
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
require_once CALENDAR_ROOT.'Day.php';
 
$Day = & new Calendar_Day(2003,10,23);
 
setlocale (LC_TIME, "de_DE"); // Unix based (probably)
// setlocale (LC_TIME, "ge"); // Windows
 
echo ( strftime('%A %d %B %Y',$Day->getTimeStamp()));
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/15.phps
New file
0,0 → 1,58
<?php
/**
* Shows more on how a week can be used
*/
function getmicrotime() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if (!@include 'Calendar/Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Week.php';
 
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('m');
if (!isset($_GET['d'])) $_GET['d'] = 1;
 
// Build the month
$Week = new Calendar_Week($_GET['y'], $_GET['m'], $_GET['d']);
/*
$Validator = $Week->getValidator();
if (!$Validator->isValidWeek()) {
die ('Please enter a valid week!');
}
*/
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Paging Weeks </title>
</head>
<body>
<h1>Paging Weeks</h1>
<h2>Week: <?php echo $Week->thisWeek().' '.date('F Y',$Week->thisMonth(true)); ?></h2>
<?php
$Week->build();
while ($Day = $Week->fetch()) {
echo '<p>'.date('jS F',$Day->thisDay(true))."</p>\n";
}
$days = $Week->fetchAll();
 
$prevWeek = $Week->prevWeek('array');
$prevWeekLink = $_SERVER['PHP_SELF'].
'?y='.$prevWeek['year'].
'&m='.$prevWeek['month'].
'&d='.$prevWeek['day'];
 
$nextWeek = $Week->nextWeek('array');
$nextWeekLink = $_SERVER['PHP_SELF'].
'?y='.$nextWeek['year'].
'&m='.$nextWeek['month'].
'&d='.$nextWeek['day'];
?>
<p><a href="<?php echo $prevWeekLink; ?>"><<</a> | <a href="<?php echo $nextWeekLink; ?>">>></a></p>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/17.phps
New file
0,0 → 1,71
<?php
/**
* Description: demonstrates using the Textual decorator
*/
 
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Day.php';
require_once CALENDAR_ROOT.'Month'.DIRECTORY_SEPARATOR.'Weekdays.php';
require_once CALENDAR_ROOT.'Decorator'.DIRECTORY_SEPARATOR.'Textual.php';
 
// Could change language like this
// setlocale (LC_TIME, "de_DE"); // Unix based (probably)
// setlocale (LC_TIME, "ge"); // Windows
 
echo "<hr>Calling: Calendar_Decorator_Textual::monthNames('long');<pre>";
print_r(Calendar_Decorator_Textual::monthNames('long'));
echo '</pre>';
 
echo "<hr>Calling: Calendar_Decorator_Textual::weekdayNames('two');<pre>";
print_r(Calendar_Decorator_Textual::weekdayNames('two'));
echo '</pre>';
 
echo "<hr>Creating: new Calendar_Day(date('Y'), date('n'), date('d'));<br />";
$Calendar = new Calendar_Day(date('Y'), date('n'), date('d'));
 
// Decorate
$Textual = & new Calendar_Decorator_Textual($Calendar);
 
echo '<hr>Previous month is: '.$Textual->prevMonthName('two').'<br />';
echo 'This month is: '.$Textual->thisMonthName('short').'<br />';
echo 'Next month is: '.$Textual->nextMonthName().'<br /><hr />';
echo 'Previous day is: '.$Textual->prevDayName().'<br />';
echo 'This day is: '.$Textual->thisDayName('short').'<br />';
echo 'Next day is: '.$Textual->nextDayName('one').'<br /><hr />';
 
echo "Creating: new Calendar_Month_Weekdays(date('Y'), date('n'), 6); - Saturday is first day of week<br />";
$Calendar = new Calendar_Month_Weekdays(date('Y'), date('n'), 6);
 
// Decorate
$Textual = & new Calendar_Decorator_Textual($Calendar);
?>
<p>Rendering calendar....</p>
<table>
<caption><?php echo $Textual->thisMonthName().' '.$Textual->thisYear(); ?></caption>
<tr>
<?php
$dayheaders = $Textual->orderedWeekdays('short');
foreach ($dayheaders as $dayheader) {
echo '<th>'.$dayheader.'</th>';
}
?>
</tr>
<?php
$Calendar->build();
while ($Day = $Calendar->fetch()) {
if ($Day->isFirst()) {
echo "<tr>\n";
}
if ($Day->isEmpty()) {
echo '<td>&nbsp;</td>';
} else {
echo '<td>'.$Day->thisDay().'</td>';
}
if ($Day->isLast()) {
echo "</tr>\n";
}
}
?>
</table>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/19.phps
New file
0,0 → 1,24
<?php
/**
* Description: demonstrates using the Weekday decorator
*/
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Day.php';
require_once CALENDAR_ROOT.'Decorator/Weekday.php';
 
$Day = new Calendar_Day(date('Y'), date('n'),date('d'));
$WeekDay = & new Calendar_Decorator_Weekday($Day);
// $WeekDay->setFirstDay(0); // Make Sunday first Day
 
echo 'Yesterday: '.$WeekDay->prevWeekDay().'<br>';
echo 'Today: '.$WeekDay->thisWeekDay().'<br>';
echo 'Tomorrow: '.$WeekDay->nextWeekDay().'<br>';
 
$WeekDay->build();
echo 'Hours today:<br>';
while ( $Hour = $WeekDay->fetch() ) {
echo $Hour->thisHour().'<br>';
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/20.php
New file
0,0 → 1,240
<?php
/**
* Description: demonstrates a decorator used to "attach a payload" to a selection
* to make it available when iterating over calendar children
*/
 
//if you use ISO-8601 dates, switch to PearDate engine
define('CALENDAR_ENGINE', 'PearDate');
 
if ( !@include 'Calendar/Calendar.php' ) {
define('CALENDAR_ROOT','../../');
}
 
require_once CALENDAR_ROOT . 'Month/Weekdays.php';
require_once CALENDAR_ROOT . 'Day.php';
require_once CALENDAR_ROOT . 'Decorator.php';
 
// accepts multiple entries
class DiaryEvent extends Calendar_Decorator
{
var $entries = array();
 
function DiaryEvent($calendar) {
Calendar_Decorator::Calendar_Decorator($calendar);
}
 
function addEntry($entry) {
$this->entries[] = $entry;
}
 
function getEntry() {
$entry = each($this->entries);
if ($entry) {
return $entry['value'];
} else {
reset($this->entries);
return false;
}
}
}
 
class MonthPayload_Decorator extends Calendar_Decorator
{
//Calendar engine
var $cE;
var $tableHelper;
 
var $year;
var $month;
var $firstDay = false;
 
function build($events=array())
{
require_once CALENDAR_ROOT . 'Day.php';
require_once CALENDAR_ROOT . 'Table/Helper.php';
 
$this->tableHelper = & new Calendar_Table_Helper($this, $this->firstDay);
$this->cE = & $this->getEngine();
$this->year = $this->thisYear();
$this->month = $this->thisMonth();
 
$daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month);
for ($i=1; $i<=$daysInMonth; $i++) {
$Day = new Calendar_Day(2000,1,1); // Create Day with dummy values
$Day->setTimeStamp($this->cE->dateToStamp($this->year, $this->month, $i));
$this->children[$i] = new DiaryEvent($Day);
}
if (count($events) > 0) {
$this->setSelection($events);
}
Calendar_Month_Weekdays::buildEmptyDaysBefore();
Calendar_Month_Weekdays::shiftDays();
Calendar_Month_Weekdays::buildEmptyDaysAfter();
Calendar_Month_Weekdays::setWeekMarkers();
return true;
}
 
function setSelection($events)
{
$daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month);
for ($i=1; $i<=$daysInMonth; $i++) {
$stamp1 = $this->cE->dateToStamp($this->year, $this->month, $i);
$stamp2 = $this->cE->dateToStamp($this->year, $this->month, $i+1);
foreach ($events as $event) {
if (($stamp1 >= $event['start'] && $stamp1 < $event['end']) ||
($stamp2 >= $event['start'] && $stamp2 < $event['end']) ||
($stamp1 <= $event['start'] && $stamp2 > $event['end'])
) {
$this->children[$i]->addEntry($event);
$this->children[$i]->setSelected();
}
}
}
}
 
function fetch()
{
$child = each($this->children);
if ($child) {
return $child['value'];
} else {
reset($this->children);
return false;
}
}
}
 
// Calendar instance used to get the dates in the preferred format:
// you can switch Calendar Engine and the example still works
$cal = new Calendar;
 
$events = array();
//add some events
$events[] = array(
'start' => $cal->cE->dateToStamp(2004, 6, 1, 10),
'end' => $cal->cE->dateToStamp(2004, 6, 1, 12),
'desc' => 'Important meeting'
);
$events[] = array(
'start' => $cal->cE->dateToStamp(2004, 6, 1, 21),
'end' => $cal->cE->dateToStamp(2004, 6, 1, 23, 59),
'desc' => 'Dinner with the boss'
);
$events[] = array(
'start' => $cal->cE->dateToStamp(2004, 6, 5),
'end' => $cal->cE->dateToStamp(2004, 6, 10, 23, 59),
'desc' => 'Holidays!'
);
 
 
 
$Month = & new Calendar_Month_Weekdays(2004, 6);
$MonthDecorator = new MonthPayload_Decorator($Month);
$MonthDecorator->build($events);
 
?>
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Calendar </title>
<style text="text/css">
table {
border-collapse: collapse;
}
caption {
font-family: verdana;
font-size: 14pt;
padding-bottom: 4pt;
}
th {
font-family: verdana;
font-size: 11px;
text-align: center;
background-color: #e7e3e7;
padding: 5pt;
line-height: 150%;
border: 1px solid #ccc;
}
td {
font-family: verdana;
font-size: 11px;
text-align: left;
vertical-align: top;
}
td.calCell {
border: 1px solid #b5bece;
padding: 3px;
}
td.calCellEmpty {
background-color: #f3f3f7;
}
td.calCellBusy {
background-color: #efeffa;
}
div.dayNumber {
text-align: right;
background-color: #f8f8f8;
border-bottom: 1px solid #ccc;
}
ul {
margin-left: 0;
margin-top: 5pt;
padding: 0 10pt 0 12pt;
list-style-type: square;
}
</style>
</head>
 
<body>
 
<h2>Sample Calendar Payload Decorator (using <?php echo CALENDAR_ENGINE; ?> engine)</h2>
<table class="calendar" width="98%" cellspacing="0" cellpadding="0">
<caption>
<?php echo $MonthDecorator->thisMonth().' / '.$MonthDecorator->thisYear(); ?>
</caption>
<tr>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
<?php
while ($Day = $MonthDecorator->fetch()) {
 
if ($Day->isFirst()) {
echo "<tr>\n";
}
 
echo '<td class="calCell';
if ($Day->isSelected()) {
echo ' calCellBusy';
} elseif ($Day->isEmpty()) {
echo ' calCellEmpty';
}
echo '">';
echo '<div class="dayNumber">'.$Day->thisDay().'</div>';
 
if ($Day->isEmpty()) {
echo '&nbsp;';
} else {
echo '<div class="dayContents"><ul>';
while ($entry = $Day->getEntry()) {
echo '<li>'.$entry['desc'].'</li>';
//you can print the time range as well
}
echo '</ul></div>';
}
echo '</td>';
 
if ($Day->isLast()) {
echo "</tr>\n";
}
}
?>
</table>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/21.php
New file
0,0 → 1,139
<?php
/**
* Description: a complete year with numeric week numbers
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
if (!@include 'Calendar/Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
 
require_once CALENDAR_ROOT.'Year.php';
require_once CALENDAR_ROOT.'Month/Weeks.php';
 
define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKS);
 
if (!isset($_GET['year'])) $_GET['year'] = date('Y');
 
$week_types = array(
'n_in_year',
'n_in_month',
);
 
if (!isset($_GET['week_type']) || !in_array($_GET['week_type'],$week_types) ) {
$_GET['week_type'] = 'n_in_year';
}
 
$Year = new Calendar_Year($_GET['year']);
 
$Year->build();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> <?php echo $Year->thisYear(); ?> </title>
<style type="text/css">
body {
font-family: Georgia, serif;
}
caption.year {
font-weight: bold;
font-size: 120%;
font-color: navy;
}
caption.month {
font-size: 110%;
font-color: navy;
}
table.month {
border: thin groove #800080
}
tr {
vertical-align: top;
}
th, td {
text-align: right;
font-size: 70%;
}
#prev {
float: left;
font-size: 70%;
}
#next {
float: right;
font-size: 70%;
}
#week_type {
float: none;
font-size: 70%;
}
.weekNumbers {
background-color: #e5e5f5;
padding-right: 3pt;
}
</style>
</head>
<body>
<table>
<caption class="year">
<?php echo $Year->thisYear(); ?>
<div id="next">
<a href="?year=<?php echo $Year->nextYear(); ?>&week_type=<?php echo $_GET['week_type']; ?>">>></a>
</div>
<div id="prev">
<a href="?year=<?php echo $Year->prevYear(); ?>&week_type=<?php echo $_GET['week_type']; ?>"><<</a>
</div>
<div id="week_type">
<a href="?year=<?php echo $Year->thisYear(); ?>&week_type=n_in_year">Weeks by Year</a> :
<a href="?year=<?php echo $Year->thisYear(); ?>&week_type=n_in_month">Weeks by Month</a>
</div>
</caption>
<?php
$i = 0;
while ($Month = $Year->fetch()) {
 
switch ($i) {
case 0:
echo "<tr>\n";
break;
case 3:
case 6:
case 9:
echo "</tr>\n<tr>\n";
break;
case 12:
echo "</tr>\n";
break;
}
 
echo "<td>\n<table class=\"month\">\n";
echo '<caption class="month">'.date('F', $Month->thisMonth(TRUE)).'</caption>';
echo '<colgroup><col class="weekNumbers"><col span="7"></colgroup>'."\n";
echo "<tr>\n<th>Week</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th>\n</tr>";
$Month->build();
while ($Week = $Month->fetch()) {
echo "<tr>\n";
echo '<td>'.$Week->thisWeek($_GET['week_type'])."</td>\n";
$Week->build();
 
while ($Day = $Week->fetch()) {
if ($Day->isEmpty()) {
echo "<td>&nbsp;</td>\n";
} else {
echo "<td>".$Day->thisDay()."</td>\n";
}
}
}
echo "</table>\n</td>\n";
 
$i++;
}
?>
</table>
<p>Took: <?php echo ((getmicrotime()-$start)); ?></p>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/22.php
New file
0,0 → 1,46
<?php
/**
* Description: demonstrates using the Uri util
*/
if (!@include 'Calendar/Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Month/Weekdays.php';
require_once CALENDAR_ROOT.'Util/Uri.php';
 
if (!isset($_GET['jahr'])) $_GET['jahr'] = date('Y');
if (!isset($_GET['monat'])) $_GET['monat'] = date('m');
 
// Build the month
$Calendar = new Calendar_Month_Weekdays($_GET['jahr'], $_GET['monat']);
 
echo ( '<p>The current month is '
.$Calendar->thisMonth().' of year '.$Calendar->thisYear().'</p>');
 
$Uri = & new Calendar_Util_Uri('jahr','monat');
$Uri->setFragments('jahr','monat');
 
echo "\"Vector\" URIs<pre>";
echo ( "Previous Uri:\t".htmlentities($Uri->prev($Calendar, 'month'))."\n" );
echo ( "This Uri:\t".htmlentities($Uri->this($Calendar, 'month'))."\n" );
echo ( "Next Uri:\t".htmlentities($Uri->next($Calendar, 'month'))."\n" );
echo "</pre>";
 
// Switch to scalar URIs
$Uri->separator = '/'; // Default is &amp;
$Uri->scalar = true; // Omit variable names
 
echo "\"Scalar\" URIs<pre>";
echo ( "Previous Uri:\t".$Uri->prev($Calendar, 'month')."\n" );
echo ( "This Uri:\t".$Uri->this($Calendar, 'month')."\n" );
echo ( "Next Uri:\t".$Uri->next($Calendar, 'month')."\n" );
echo "</pre>";
 
// Restore the vector URIs
$Uri->separator = '&amp;';
$Uri->scalar = false;
?>
<p>
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->prev($Calendar, 'month'));?>">Prev</a> :
<a href="<?php echo($_SERVER['PHP_SELF'].'?'.$Uri->next($Calendar, 'month'));?>">Next</a>
</p>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/23.php
New file
0,0 → 1,66
<?php
/**
* Description: demonstrates using the Textual util
*/
 
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Day.php';
require_once CALENDAR_ROOT.'Month'.DIRECTORY_SEPARATOR.'Weekdays.php';
require_once CALENDAR_ROOT.'Util'.DIRECTORY_SEPARATOR.'Textual.php';
 
// Could change language like this
// setlocale (LC_TIME, "de_DE"); // Unix based (probably)
// setlocale (LC_TIME, "ge"); // Windows
 
echo "<hr>Calling: Calendar_Util_Textual::monthNames('long');<pre>";
print_r(Calendar_Util_Textual::monthNames('long'));
echo '</pre>';
 
echo "<hr>Calling: Calendar_Util_Textual::weekdayNames('two');<pre>";
print_r(Calendar_Util_Textual::weekdayNames('two'));
echo '</pre>';
 
echo "<hr>Creating: new Calendar_Day(date('Y'), date('n'), date('d'));<br />";
$Calendar = new Calendar_Day(date('Y'), date('n'), date('d'));
 
echo '<hr>Previous month is: '.Calendar_Util_Textual::prevMonthName($Calendar,'two').'<br />';
echo 'This month is: '.Calendar_Util_Textual::thisMonthName($Calendar,'short').'<br />';
echo 'Next month is: '.Calendar_Util_Textual::nextMonthName($Calendar).'<br /><hr />';
echo 'Previous day is: '.Calendar_Util_Textual::prevDayName($Calendar).'<br />';
echo 'This day is: '.Calendar_Util_Textual::thisDayName($Calendar,'short').'<br />';
echo 'Next day is: '.Calendar_Util_Textual::nextDayName($Calendar,'one').'<br /><hr />';
 
echo "Creating: new Calendar_Month_Weekdays(date('Y'), date('n'), 6); - Saturday is first day of week<br />";
$Calendar = new Calendar_Month_Weekdays(date('Y'), date('n'), 6);
 
?>
<p>Rendering calendar....</p>
<table>
<caption><?php echo Calendar_Util_Textual::thisMonthName($Calendar).' '.$Calendar->thisYear(); ?></caption>
<tr>
<?php
$dayheaders = Calendar_Util_Textual::orderedWeekdays($Calendar,'short');
foreach ($dayheaders as $dayheader) {
echo '<th>'.$dayheader.'</th>';
}
?>
</tr>
<?php
$Calendar->build();
while ($Day = $Calendar->fetch()) {
if ($Day->isFirst()) {
echo "<tr>\n";
}
if ($Day->isEmpty()) {
echo '<td>&nbsp;</td>';
} else {
echo '<td>'.$Day->thisDay().'</td>';
}
if ($Day->isLast()) {
echo "</tr>\n";
}
}
?>
</table>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/docs/examples/2.phps
New file
0,0 → 1,142
<?php
/**
* Description: Demonstrates building a calendar for a month using the Week class
* Uses UnixTs engine
*/
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
$start = getmicrotime();
 
// Force UnixTs engine (default setting)
define('CALENDAR_ENGINE','UnixTS');
 
if (!@include 'Calendar'.DIRECTORY_SEPARATOR.'Calendar.php') {
define('CALENDAR_ROOT', '../../');
}
require_once CALENDAR_ROOT.'Month/Weeks.php';
require_once CALENDAR_ROOT.'Day.php';
 
// Initialize GET variables if not set
if (!isset($_GET['y'])) $_GET['y'] = date('Y');
if (!isset($_GET['m'])) $_GET['m'] = date('m');
if (!isset($_GET['d'])) $_GET['d'] = date('d');
 
// Build a month object
$Month = new Calendar_Month_Weeks($_GET['y'], $_GET['m']);
 
// Create an array of days which are "selected"
// Used for Week::build() below
$selectedDays = array (
new Calendar_Day($_GET['y'],$_GET['m'], $_GET['d']),
new Calendar_Day($_GET['y'], 12, 25),
new Calendar_Day(date('Y'), date('m'), date('d')),
);
 
// Instruct month to build Week objects
$Month->build();
 
// Construct strings for next/previous links
$PMonth = $Month->prevMonth('object'); // Get previous month as object
$prev = $_SERVER['PHP_SELF'].'?y='.$PMonth->thisYear().'&m='.$PMonth->thisMonth().'&d='.$PMonth->thisDay();
$NMonth = $Month->nextMonth('object');
$next = $_SERVER['PHP_SELF'].'?y='.$NMonth->thisYear().'&m='.$NMonth->thisMonth().'&d='.$NMonth->thisDay();
?>
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Calendar </title>
<style text="text/css">
table {
background-color: silver;
}
caption {
font-family: verdana;
font-size: 12px;
background-color: while;
}
.prevMonth {
font-size: 10px;
text-align: left;
}
.nextMonth {
font-size: 10px;
text-align: right;
}
th {
font-family: verdana;
font-size: 11px;
color: navy;
text-align: right;
}
td {
font-family: verdana;
font-size: 11px;
text-align: right;
}
.selected {
background-color: yellow;
}
.empty {
color: white;
}
</style>
</head>
 
<body>
<h2>Build with Calendar_Month_Weeks::build() then Calendar_Week::build()</h2>
<table class="calendar">
<caption>
<?php echo date('F Y', $Month->getTimeStamp()); ?>
</caption>
<tr>
<th>M</th>
<th>T</th>
<th>W</th>
<th>T</th>
<th>F</th>
<th>S</th>
<th>S</th>
</tr>
<?php
while ($Week = $Month->fetch()) {
echo "<tr>\n";
// Build the days in the week, passing the selected days
$Week->build($selectedDays);
while ($Day = $Week->fetch()) {
 
// Build a link string for each day
$link = $_SERVER['PHP_SELF'].
'?y='.$Day->thisYear().
'&m='.$Day->thisMonth().
'&d='.$Day->thisDay();
 
// Check to see if day is selected
if ($Day->isSelected()) {
echo '<td class="selected">'.$Day->thisDay().'</td>'."\n";
// Check to see if day is empty
} else if ($Day->isEmpty()) {
echo '<td class="empty">'.$Day->thisDay().'</td>'."\n";
} else {
echo '<td><a href="'.$link.'">'.$Day->thisDay().'</a></td>'."\n";
}
}
echo '</tr>'."\n";
}
?>
<tr>
<td>
<a href="<?php echo $prev; ?>" class="prevMonth"><< </a>
</td>
<td colspan="5">&nbsp;</td>
<td>
<a href="<?php echo $next; ?>" class="nextMonth"> >></a>
</td>
</tr>
</table>
<?php
echo '<p><b>Took: '.(getmicrotime()-$start).' seconds</b></p>';
?>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Factory.php
New file
0,0 → 1,145
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: Factory.php,v 1.3 2005/10/22 10:08:47 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Factory.php,v 1.3 2005/10/22 10:08:47 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar base class
*/
require_once CALENDAR_ROOT.'Calendar.php';
 
/**
* Contains a factory method to return a Singleton instance of a class
* implementing the Calendar_Engine_Interface.<br>
* For Month objects, to control type of month returned, use CALENDAR_MONTH_STATE
* constact e.g.;
* <code>
* require_once 'Calendar/Factory.php';
* define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKDAYS); // Use Calendar_Month_Weekdays
* // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKS); // Use Calendar_Month_Weeks
* // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH); // Use Calendar_Month
* </code>
* It defaults to building Calendar_Month objects.<br>
* Use the constract CALENDAR_FIRST_DAY_OF_WEEK to control the first day of the week
* for Month or Week objects (e.g. 0 = Sunday, 6 = Saturday)
* @package Calendar
* @access protected
*/
class Calendar_Factory
{
/**
* Creates a calendar object given the type and units
* @param string class of calendar object to create
* @param int year
* @param int month
* @param int day
* @param int hour
* @param int minute
* @param int second
* @return object subclass of Calendar
* @access public
* @static
*/
function create($type, $y = 2000, $m = 1, $d = 1, $h = 0, $i = 0, $s = 0)
{
$firstDay = defined('CALENDAR_FIRST_DAY_OF_WEEK') ? CALENDAR_FIRST_DAY_OF_WEEK : 1;
switch ($type) {
case 'Day':
require_once CALENDAR_ROOT.'Day.php';
return new Calendar_Day($y,$m,$d);
case 'Month':
// Set default state for which month type to build
if (!defined('CALENDAR_MONTH_STATE')) {
define('CALENDAR_MONTH_STATE', CALENDAR_USE_MONTH);
}
switch (CALENDAR_MONTH_STATE) {
case CALENDAR_USE_MONTH_WEEKDAYS:
require_once CALENDAR_ROOT.'Month/Weekdays.php';
$class = 'Calendar_Month_Weekdays';
break;
case CALENDAR_USE_MONTH_WEEKS:
require_once CALENDAR_ROOT.'Month/Weeks.php';
$class = 'Calendar_Month_Weeks';
break;
case CALENDAR_USE_MONTH:
default:
require_once CALENDAR_ROOT.'Month.php';
$class = 'Calendar_Month';
break;
}
return new $class($y, $m, $firstDay);
case 'Week':
require_once CALENDAR_ROOT.'Week.php';
return new Calendar_Week($y, $m, $d, $firstDay);
case 'Hour':
require_once CALENDAR_ROOT.'Hour.php';
return new Calendar_Hour($y, $m, $d, $h);
case 'Minute':
require_once CALENDAR_ROOT.'Minute.php';
return new Calendar_Minute($y, $m, $d, $h, $i);
case 'Second':
require_once CALENDAR_ROOT.'Second.php';
return new Calendar_Second($y,$m,$d,$h,$i,$s);
case 'Year':
require_once CALENDAR_ROOT.'Year.php';
return new Calendar_Year($y);
default:
require_once 'PEAR.php';
PEAR::raiseError(
'Calendar_Factory::create() unrecognised type: '.$type, null, PEAR_ERROR_TRIGGER,
E_USER_NOTICE, 'Calendar_Factory::create()');
return false;
}
}
/**
* Creates an instance of a calendar object, given a type and timestamp
* @param string type of object to create
* @param mixed timestamp (depending on Calendar engine being used)
* @return object subclass of Calendar
* @access public
* @static
*/
function & createByTimestamp($type, $stamp)
{
$cE = & Calendar_Engine_Factory::getEngine();
$y = $cE->stampToYear($stamp);
$m = $cE->stampToMonth($stamp);
$d = $cE->stampToDay($stamp);
$h = $cE->stampToHour($stamp);
$i = $cE->stampToMinute($stamp);
$s = $cE->stampToSecond($stamp);
$cal = Calendar_Factory::create($type, $y, $m, $d, $h, $i, $s);
return $cal;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Calendar.php
New file
0,0 → 1,685
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// | Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: Calendar.php,v 1.3 2005/10/22 10:07:11 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Calendar.php,v 1.3 2005/10/22 10:07:11 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Constant which defines the calculation engine to use
*/
if (!defined('CALENDAR_ENGINE')) {
define('CALENDAR_ENGINE', 'UnixTS');
}
 
/**
* Define Calendar Month states
*/
define('CALENDAR_USE_MONTH', 1);
define('CALENDAR_USE_MONTH_WEEKDAYS', 2);
define('CALENDAR_USE_MONTH_WEEKS', 3);
 
/**
* Contains a factory method to return a Singleton instance of a class
* implementing the Calendar_Engine_Interface.<br>
* <b>Note:</b> this class must be modified to "register" alternative
* Calendar_Engines. The engine used can be controlled with the constant
* CALENDAR_ENGINE
* @see Calendar_Engine_Interface
* @package Calendar
* @access protected
*/
class Calendar_Engine_Factory
{
/**
* Returns an instance of the engine
* @return object instance of a calendar calculation engine
* @access protected
*/
function & getEngine()
{
static $engine = false;
switch (CALENDAR_ENGINE) {
case 'PearDate':
$class = 'Calendar_Engine_PearDate';
break;
case 'UnixTS':
default:
$class = 'Calendar_Engine_UnixTS';
break;
}
if (!$engine) {
if (!class_exists($class)) {
require_once CALENDAR_ROOT.'Engine'.DIRECTORY_SEPARATOR.CALENDAR_ENGINE.'.php';
}
$engine = new $class;
}
return $engine;
}
}
 
/**
* Base class for Calendar API. This class should not be instantiated
* directly.
* @abstract
* @package Calendar
*/
class Calendar
{
/**
* Instance of class implementing calendar engine interface
* @var object
* @access private
*/
var $cE;
 
/**
* Instance of Calendar_Validator (lazy initialized when isValid() or
* getValidor() is called
* @var Calendar_Validator
* @access private
*/
var $validator;
 
/**
* Year for this calendar object e.g. 2003
* @access private
* @var int
*/
var $year;
 
/**
* Month for this calendar object e.g. 9
* @access private
* @var int
*/
var $month;
 
/**
* Day of month for this calendar object e.g. 23
* @access private
* @var int
*/
var $day;
 
/**
* Hour of day for this calendar object e.g. 13
* @access private
* @var int
*/
var $hour;
 
/**
* Minute of hour this calendar object e.g. 46
* @access private
* @var int
*/
var $minute;
 
/**
* Second of minute this calendar object e.g. 34
* @access private
* @var int
*/
var $second;
 
/**
* Marks this calendar object as selected (e.g. 'today')
* @access private
* @var boolean
*/
var $selected = false;
 
/**
* Collection of child calendar objects created from subclasses
* of Calendar. Type depends on the object which created them.
* @access private
* @var array
*/
var $children = array();
 
/**
* Constructs the Calendar
* @param int year
* @param int month
* @param int day
* @param int hour
* @param int minute
* @param int second
* @access protected
*/
function Calendar($y = 2000, $m = 1, $d = 1, $h = 0, $i = 0, $s = 0)
{
static $cE = null;
if (!isset($cE)) {
$cE = & Calendar_Engine_Factory::getEngine();
}
$this->cE = & $cE;
$this->year = (int)$y;
$this->month = (int)$m;
$this->day = (int)$d;
$this->hour = (int)$h;
$this->minute = (int)$i;
$this->second = (int)$s;
}
 
/**
* Defines the calendar by a timestamp (Unix or ISO-8601), replacing values
* passed to the constructor
* @param int|string Unix or ISO-8601 timestamp
* @return void
* @access public
*/
function setTimestamp($ts)
{
$this->year = $this->cE->stampToYear($ts);
$this->month = $this->cE->stampToMonth($ts);
$this->day = $this->cE->stampToDay($ts);
$this->hour = $this->cE->stampToHour($ts);
$this->minute = $this->cE->stampToMinute($ts);
$this->second = $this->cE->stampToSecond($ts);
}
 
/**
* Returns a timestamp from the current date / time values. Format of
* timestamp depends on Calendar_Engine implementation being used
* @return int|string timestamp
* @access public
*/
function getTimestamp()
{
return $this->cE->dateToStamp(
$this->year, $this->month, $this->day,
$this->hour, $this->minute, $this->second);
}
 
/**
* Defines calendar object as selected (e.g. for today)
* @param boolean state whether Calendar subclass
* @return void
* @access public
*/
function setSelected($state = true)
{
$this->selected = $state;
}
 
/**
* True if the calendar subclass object is selected (e.g. today)
* @return boolean
* @access public
*/
function isSelected()
{
return $this->selected;
}
 
/**
* Adjusts the date (helper method)
* @return void
* @access public
*/
function adjust()
{
$stamp = $this->getTimeStamp();
$this->year = $this->cE->stampToYear($stamp);
$this->month = $this->cE->stampToMonth($stamp);
$this->day = $this->cE->stampToDay($stamp);
$this->hour = $this->cE->stampToHour($stamp);
$this->minute = $this->cE->stampToMinute($stamp);
$this->second = $this->cE->stampToSecond($stamp);
}
 
/**
* Returns the date as an associative array (helper method)
* @param mixed timestamp (leave empty for current timestamp)
* @return array
* @access public
*/
function toArray($stamp=null)
{
if (is_null($stamp)) {
$stamp = $this->getTimeStamp();
}
return array(
'year' => $this->cE->stampToYear($stamp),
'month' => $this->cE->stampToMonth($stamp),
'day' => $this->cE->stampToDay($stamp),
'hour' => $this->cE->stampToHour($stamp),
'minute' => $this->cE->stampToMinute($stamp),
'second' => $this->cE->stampToSecond($stamp)
);
}
 
/**
* Returns the value as an associative array (helper method)
* @param string type of date object that return value represents
* @param string $format ['int' | 'array' | 'timestamp' | 'object']
* @param mixed timestamp (depending on Calendar engine being used)
* @param int integer default value (i.e. give me the answer quick)
* @return mixed
* @access private
*/
function returnValue($returnType, $format, $stamp, $default)
{
switch (strtolower($format)) {
case 'int':
return $default;
case 'array':
return $this->toArray($stamp);
break;
case 'object':
require_once CALENDAR_ROOT.'Factory.php';
return Calendar_Factory::createByTimestamp($returnType,$stamp);
break;
case 'timestamp':
default:
return $stamp;
break;
}
}
 
/**
* Abstract method for building the children of a calendar object.
* Implemented by Calendar subclasses
* @param array containing Calendar objects to select (optional)
* @return boolean
* @access public
* @abstract
*/
function build($sDates = array())
{
require_once 'PEAR.php';
PEAR::raiseError(
'Calendar::build is abstract', null, PEAR_ERROR_TRIGGER,
E_USER_NOTICE, 'Calendar::build()');
return false;
}
 
/**
* Abstract method for selected data objects called from build
* @param array
* @return boolean
* @access public
* @abstract
*/
function setSelection($sDates)
{
require_once 'PEAR.php';
PEAR::raiseError(
'Calendar::setSelection is abstract', null, PEAR_ERROR_TRIGGER,
E_USER_NOTICE, 'Calendar::setSelection()');
return false;
}
 
/**
* Iterator method for fetching child Calendar subclass objects
* (e.g. a minute from an hour object). On reaching the end of
* the collection, returns false and resets the collection for
* further iteratations.
* @return mixed either an object subclass of Calendar or false
* @access public
*/
function fetch()
{
$child = each($this->children);
if ($child) {
return $child['value'];
} else {
reset($this->children);
return false;
}
}
 
/**
* Fetches all child from the current collection of children
* @return array
* @access public
*/
function fetchAll()
{
return $this->children;
}
 
/**
* Get the number Calendar subclass objects stored in the internal
* collection.
* @return int
* @access public
*/
function size()
{
return count($this->children);
}
 
/**
* Determine whether this date is valid, with the bounds determined by
* the Calendar_Engine. The call is passed on to
* Calendar_Validator::isValid
* @return boolean
* @access public
*/
function isValid()
{
$validator = & $this->getValidator();
return $validator->isValid();
}
 
/**
* Returns an instance of Calendar_Validator
* @return Calendar_Validator
* @access public
*/
function & getValidator()
{
if (!isset($this->validator)) {
require_once CALENDAR_ROOT.'Validator.php';
$this->validator = new Calendar_Validator($this);
}
return $this->validator;
}
 
/**
* Returns a reference to the current Calendar_Engine being used. Useful
* for Calendar_Table_Helper and Calendar_Validator
* @return object implementing Calendar_Engine_Inteface
* @access protected
*/
function & getEngine()
{
return $this->cE;
}
 
/**
* Set the CALENDAR_FIRST_DAY_OF_WEEK constant to the $firstDay value
* if the constant is not set yet.
* @throws E_USER_WARNING this method throws a WARNING if the
* CALENDAR_FIRST_DAY_OF_WEEK constant is already defined and
* the $firstDay parameter is set to a different value
* @param integer $firstDay first day of the week (0=sunday, 1=monday, ...)
* @return integer
* @access protected
*/
function defineFirstDayOfWeek($firstDay = null)
{
if (defined('CALENDAR_FIRST_DAY_OF_WEEK')) {
if (!is_null($firstDay) && ($firstDay != CALENDAR_FIRST_DAY_OF_WEEK)) {
$msg = 'CALENDAR_FIRST_DAY_OF_WEEK constant already defined.'
.' The $firstDay parameter will be ignored.';
trigger_error($msg, E_USER_WARNING);
}
return CALENDAR_FIRST_DAY_OF_WEEK;
}
if (is_null($firstDay)) {
$firstDay = $this->cE->getFirstDayOfWeek(
$this->thisYear(),
$this->thisMonth(),
$this->thisDay()
);
}
define ('CALENDAR_FIRST_DAY_OF_WEEK', $firstDay);
return CALENDAR_FIRST_DAY_OF_WEEK;
}
 
/**
* Returns the value for the previous year
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 2002 or timestamp
* @access public
*/
function prevYear($format = 'int')
{
$ts = $this->cE->dateToStamp($this->year-1, 1, 1, 0, 0, 0);
return $this->returnValue('Year', $format, $ts, $this->year-1);
}
 
/**
* Returns the value for this year
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 2003 or timestamp
* @access public
*/
function thisYear($format = 'int')
{
$ts = $this->cE->dateToStamp($this->year, 1, 1, 0, 0, 0);
return $this->returnValue('Year', $format, $ts, $this->year);
}
 
/**
* Returns the value for next year
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 2004 or timestamp
* @access public
*/
function nextYear($format = 'int')
{
$ts = $this->cE->dateToStamp($this->year+1, 1, 1, 0, 0, 0);
return $this->returnValue('Year', $format, $ts, $this->year+1);
}
 
/**
* Returns the value for the previous month
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 4 or Unix timestamp
* @access public
*/
function prevMonth($format = 'int')
{
$ts = $this->cE->dateToStamp($this->year, $this->month-1, 1, 0, 0, 0);
return $this->returnValue('Month', $format, $ts, $this->cE->stampToMonth($ts));
}
 
/**
* Returns the value for this month
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 5 or timestamp
* @access public
*/
function thisMonth($format = 'int')
{
$ts = $this->cE->dateToStamp($this->year, $this->month, 1, 0, 0, 0);
return $this->returnValue('Month', $format, $ts, $this->month);
}
 
/**
* Returns the value for next month
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 6 or timestamp
* @access public
*/
function nextMonth($format = 'int')
{
$ts = $this->cE->dateToStamp($this->year, $this->month+1, 1, 0, 0, 0);
return $this->returnValue('Month', $format, $ts, $this->cE->stampToMonth($ts));
}
 
/**
* Returns the value for the previous day
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 10 or timestamp
* @access public
*/
function prevDay($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day-1, 0, 0, 0);
return $this->returnValue('Day', $format, $ts, $this->cE->stampToDay($ts));
}
 
/**
* Returns the value for this day
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 11 or timestamp
* @access public
*/
function thisDay($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day, 0, 0, 0);
return $this->returnValue('Day', $format, $ts, $this->day);
}
 
/**
* Returns the value for the next day
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 12 or timestamp
* @access public
*/
function nextDay($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day+1, 0, 0, 0);
return $this->returnValue('Day', $format, $ts, $this->cE->stampToDay($ts));
}
 
/**
* Returns the value for the previous hour
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 13 or timestamp
* @access public
*/
function prevHour($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day, $this->hour-1, 0, 0);
return $this->returnValue('Hour', $format, $ts, $this->cE->stampToHour($ts));
}
 
/**
* Returns the value for this hour
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 14 or timestamp
* @access public
*/
function thisHour($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day, $this->hour, 0, 0);
return $this->returnValue('Hour', $format, $ts, $this->hour);
}
 
/**
* Returns the value for the next hour
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 14 or timestamp
* @access public
*/
function nextHour($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day, $this->hour+1, 0, 0);
return $this->returnValue('Hour', $format, $ts, $this->cE->stampToHour($ts));
}
 
/**
* Returns the value for the previous minute
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 23 or timestamp
* @access public
*/
function prevMinute($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day,
$this->hour, $this->minute-1, 0);
return $this->returnValue('Minute', $format, $ts, $this->cE->stampToMinute($ts));
}
 
/**
* Returns the value for this minute
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 24 or timestamp
* @access public
*/
function thisMinute($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day,
$this->hour, $this->minute, 0);
return $this->returnValue('Minute', $format, $ts, $this->minute);
}
 
/**
* Returns the value for the next minute
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 25 or timestamp
* @access public
*/
function nextMinute($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day,
$this->hour, $this->minute+1, 0);
return $this->returnValue('Minute', $format, $ts, $this->cE->stampToMinute($ts));
}
 
/**
* Returns the value for the previous second
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 43 or timestamp
* @access public
*/
function prevSecond($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day,
$this->hour, $this->minute, $this->second-1);
return $this->returnValue('Second', $format, $ts, $this->cE->stampToSecond($ts));
}
 
/**
* Returns the value for this second
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 44 or timestamp
* @access public
*/
function thisSecond($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day,
$this->hour, $this->minute, $this->second);
return $this->returnValue('Second', $format, $ts, $this->second);
}
 
/**
* Returns the value for the next second
* @param string return value format ['int' | 'timestamp' | 'object' | 'array']
* @return int e.g. 45 or timestamp
* @access public
*/
function nextSecond($format = 'int')
{
$ts = $this->cE->dateToStamp(
$this->year, $this->month, $this->day,
$this->hour, $this->minute, $this->second+1);
return $this->returnValue('Second', $format, $ts, $this->cE->stampToSecond($ts));
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Second.php
New file
0,0 → 1,98
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Second.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Second.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar base class
*/
require_once CALENDAR_ROOT.'Calendar.php';
 
/**
* Represents a Second<br />
* <b>Note:</b> Seconds do not build other objects
* so related methods are overridden to return NULL
* @package Calendar
*/
class Calendar_Second extends Calendar
{
/**
* Constructs Second
* @param int year e.g. 2003
* @param int month e.g. 5
* @param int day e.g. 11
* @param int hour e.g. 13
* @param int minute e.g. 31
* @param int second e.g. 45
*/
function Calendar_Second($y, $m, $d, $h, $i, $s)
{
Calendar::Calendar($y, $m, $d, $h, $i, $s);
}
 
/**
* Overwrite build
* @return NULL
*/
function build()
{
return null;
}
 
/**
* Overwrite fetch
* @return NULL
*/
function fetch()
{
return null;
}
 
/**
* Overwrite fetchAll
* @return NULL
*/
function fetchAll()
{
return null;
}
 
/**
* Overwrite size
* @return NULL
*/
function size()
{
return null;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/week_test.php
New file
0,0 → 1,241
<?php
// $Id: week_test.php,v 1.4 2005/10/20 18:56:21 quipo Exp $
define('CALENDAR_FIRST_DAY_OF_WEEK', 1); //force firstDay = monday
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./calendar_test.php');
 
class TestOfWeek extends TestOfCalendar {
function TestOfWeek() {
$this->UnitTestCase('Test of Week');
}
function setUp() {
$this->cal = Calendar_Factory::create('Week', 2003, 10, 9);
//print_r($this->cal);
}
function testPrevDay () {
$this->assertEqual(8, $this->cal->prevDay());
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 10,
'day' => 8,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
function testThisDay () {
$this->assertEqual(9, $this->cal->thisDay());
}
function testNextDay () {
$this->assertEqual(10, $this->cal->nextDay());
}
function testPrevHour () {
$this->assertEqual(23, $this->cal->prevHour());
}
function testThisHour () {
$this->assertEqual(0, $this->cal->thisHour());
}
function testNextHour () {
$this->assertEqual(1, $this->cal->nextHour());
}
function testPrevMinute () {
$this->assertEqual(59, $this->cal->prevMinute());
}
function testThisMinute () {
$this->assertEqual(0, $this->cal->thisMinute());
}
function testNextMinute () {
$this->assertEqual(1, $this->cal->nextMinute());
}
function testPrevSecond () {
$this->assertEqual(59, $this->cal->prevSecond());
}
function testThisSecond () {
$this->assertEqual(0, $this->cal->thisSecond());
}
function testNextSecond () {
$this->assertEqual(1, $this->cal->nextSecond());
}
function testGetTimeStamp() {
$stamp = mktime(0,0,0,10,9,2003);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
function testNewTimeStamp() {
$stamp = mktime(0,0,0,7,28,2004);
$this->cal->setTimestamp($stamp);
$this->assertEqual('30 2004', date('W Y', $this->cal->prevWeek(true)));
$this->assertEqual('31 2004', date('W Y', $this->cal->thisWeek(true)));
$this->assertEqual('32 2004', date('W Y', $this->cal->nextWeek(true)));
}
function testPrevWeekInMonth() {
$this->assertEqual(1, $this->cal->prevWeek());
$stamp = mktime(0,0,0,2,3,2005);
$this->cal->setTimestamp($stamp);
$this->assertEqual(0, $this->cal->prevWeek());
}
function testThisWeekInMonth() {
$this->assertEqual(2, $this->cal->thisWeek());
$stamp = mktime(0,0,0,2,3,2005);
$this->cal->setTimestamp($stamp);
$this->assertEqual(1, $this->cal->thisWeek());
$stamp = mktime(0,0,0,1,1,2005);
$this->cal->setTimestamp($stamp);
$this->assertEqual(1, $this->cal->thisWeek());
$stamp = mktime(0,0,0,1,3,2005);
$this->cal->setTimestamp($stamp);
$this->assertEqual(2, $this->cal->thisWeek());
}
function testNextWeekInMonth() {
$this->assertEqual(3, $this->cal->nextWeek());
$stamp = mktime(0,0,0,2,3,2005);
$this->cal->setTimestamp($stamp);
$this->assertEqual(2, $this->cal->nextWeek());
}
function testPrevWeekInYear() {
$this->assertEqual(date('W', $this->cal->prevWeek('timestamp')), $this->cal->prevWeek('n_in_year'));
$stamp = mktime(0,0,0,1,1,2004);
$this->cal->setTimestamp($stamp);
$this->assertEqual(date('W', $this->cal->nextWeek('timestamp')), $this->cal->nextWeek('n_in_year'));
}
function testThisWeekInYear() {
$this->assertEqual(date('W', $this->cal->thisWeek('timestamp')), $this->cal->thisWeek('n_in_year'));
$stamp = mktime(0,0,0,1,1,2004);
$this->cal->setTimestamp($stamp);
$this->assertEqual(date('W', $this->cal->thisWeek('timestamp')), $this->cal->thisWeek('n_in_year'));
}
function testFirstWeekInYear() {
$stamp = mktime(0,0,0,1,4,2004);
$this->cal->setTimestamp($stamp);
$this->assertEqual(1, $this->cal->thisWeek('n_in_year'));
}
function testNextWeekInYear() {
$this->assertEqual(date('W', $this->cal->nextWeek('timestamp')), $this->cal->nextWeek('n_in_year'));
}
function testPrevWeekArray() {
$testArray = array(
'year'=>2003,
'month'=>9,
'day'=>29,
'hour'=>0,
'minute'=>0,
'second'=>0
);
$this->assertEqual($testArray, $this->cal->prevWeek('array'));
}
function testThisWeekArray() {
$testArray = array(
'year'=>2003,
'month'=>10,
'day'=>6,
'hour'=>0,
'minute'=>0,
'second'=>0
);
$this->assertEqual($testArray, $this->cal->thisWeek('array'));
}
function testNextWeekArray() {
$testArray = array(
'year'=>2003,
'month'=>10,
'day'=>13,
'hour'=>0,
'minute'=>0,
'second'=>0
);
$this->assertEqual($testArray, $this->cal->nextWeek('array'));
}
function testPrevWeekObject() {
$testWeek = Calendar_Factory::create('Week', 2003, 9, 29); //week starts on monday
$Week = $this->cal->prevWeek('object');
$this->assertEqual($testWeek->getTimeStamp(), $Week->getTimeStamp());
}
function testThisWeekObject() {
$testWeek = Calendar_Factory::create('Week', 2003, 10, 6); //week starts on monday
$Week = $this->cal->thisWeek('object');
$this->assertEqual($testWeek->getTimeStamp(), $Week->getTimeStamp());
}
function testNextWeekObject() {
$testWeek = Calendar_Factory::create('Week', 2003, 10, 13); //week starts on monday
$Week = $this->cal->nextWeek('object');
$this->assertEqual($testWeek->getTimeStamp(), $Week->getTimeStamp());
}
}
 
class TestOfWeekBuild extends TestOfWeek {
function TestOfWeekBuild() {
$this->UnitTestCase('Test of Week::build()');
}
function testSize() {
$this->cal->build();
$this->assertEqual(7, $this->cal->size());
}
 
function testFetch() {
$this->cal->build();
$i=0;
while ($Child = $this->cal->fetch()) {
$i++;
}
$this->assertEqual(7, $i);
}
function testFetchAll() {
$this->cal->build();
$children = array();
$i = 1;
while ( $Child = $this->cal->fetch() ) {
$children[$i]=$Child;
$i++;
}
$this->assertEqual($children,$this->cal->fetchAll());
}
 
function testSelection() {
require_once(CALENDAR_ROOT . 'Day.php');
$selection = array(Calendar_Factory::create('Day', 2003, 10, 7));
$this->cal->build($selection);
$i = 1;
while ($Child = $this->cal->fetch()) {
if ($i == 2) {
break; //07-10-2003 is the 2nd day of the week (starting on monday)
}
$i++;
}
$this->assertTrue($Child->isSelected());
}
function testSelectionCornerCase() {
require_once(CALENDAR_ROOT . 'Day.php');
$selectedDays = array(
Calendar_Factory::create('Day', 2003, 12, 29),
Calendar_Factory::create('Day', 2003, 12, 30),
Calendar_Factory::create('Day', 2003, 12, 31),
Calendar_Factory::create('Day', 2004, 01, 01),
Calendar_Factory::create('Day', 2004, 01, 02),
Calendar_Factory::create('Day', 2004, 01, 03),
Calendar_Factory::create('Day', 2004, 01, 04)
);
$this->cal = Calendar_Factory::create('Week', 2003, 12, 31, 0);
$this->cal->build($selectedDays);
while ($Day = $this->cal->fetch()) {
$this->assertTrue($Day->isSelected());
}
$this->cal = Calendar_Factory::create('Week', 2004, 1, 1, 0);
$this->cal->build($selectedDays);
while ($Day = $this->cal->fetch()) {
$this->assertTrue($Day->isSelected());
}
}
}
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfWeek();
$test->run(new HtmlReporter());
$test = &new TestOfWeekBuild();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/util_uri_test.php
New file
0,0 → 1,54
<?php
// $Id: util_uri_test.php,v 1.1 2004/08/16 08:55:24 hfuecks Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
Mock::generate('Calendar_Day','Mock_Calendar_Day');
Mock::generate('Calendar_Engine_Interface','Mock_Calendar_Engine');
 
class TestOfUtilUri extends UnitTestCase {
 
var $MockCal;
function TestOfUtilUri() {
$this->UnitTestCase('Test of Calendar_Util_Uri');
}
function setUp() {
$this->MockCal = & new Mock_Calendar_Day($this);
$this->MockCal->setReturnValue('getEngine',new Mock_Calendar_Engine($this));
}
function testFragments() {
$Uri = new Calendar_Util_Uri('y','m','d','h','m','s');
$Uri->setFragments('year','month','day','hour','minute','second');
$this->assertEqual(
'year=&amp;month=&amp;day=&amp;hour=&amp;minute=&amp;second=',
$Uri->this($this->MockCal, 'second')
);
}
function testScalarFragments() {
$Uri = new Calendar_Util_Uri('year','month','day','hour','minute','second');
$Uri->scalar = true;
$this->assertEqual(
'&amp;&amp;&amp;&amp;&amp;',
$Uri->this($this->MockCal, 'second')
);
}
function testSetSeperator() {
$Uri = new Calendar_Util_Uri('year','month','day','hour','minute','second');
$Uri->separator = '/';
$this->assertEqual(
'year=/month=/day=/hour=/minute=/second=',
$Uri->this($this->MockCal, 'second')
);
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfUtilUri();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/calendar_tests.php
New file
0,0 → 1,25
<?php
// $Id: calendar_tests.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class CalendarTests extends GroupTest {
function CalendarTests() {
$this->GroupTest('Calendar Tests');
$this->addTestFile('calendar_test.php');
$this->addTestFile('year_test.php');
$this->addTestFile('month_test.php');
$this->addTestFile('day_test.php');
$this->addTestFile('hour_test.php');
$this->addTestFile('minute_test.php');
$this->addTestFile('second_test.php');
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new CalendarTests();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/util_tests.php
New file
0,0 → 1,20
<?php
// $Id: util_tests.php,v 1.2 2004/08/16 12:56:10 hfuecks Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class UtilTests extends GroupTest {
function UtilTests() {
$this->GroupTest('Util Tests');
$this->addTestFile('util_uri_test.php');
$this->addTestFile('util_textual_test.php');
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new UtilTests();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/decorator_uri_test.php
New file
0,0 → 1,37
<?php
// $Id: decorator_uri_test.php,v 1.2 2004/07/08 10:18:48 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./decorator_test.php');
 
class TestOfDecoratorUri extends TestOfDecorator {
function TestOfDecoratorUri() {
$this->UnitTestCase('Test of Calendar_Decorator_Uri');
}
function testFragments() {
$Uri = new Calendar_Decorator_Uri($this->mockcal);
$Uri->setFragments('year','month','day','hour','minute','second');
$this->assertEqual('year=&amp;month=&amp;day=&amp;hour=&amp;minute=&amp;second=',$Uri->this('second'));
}
function testScalarFragments() {
$Uri = new Calendar_Decorator_Uri($this->mockcal);
$Uri->setFragments('year','month','day','hour','minute','second');
$Uri->setScalar();
$this->assertEqual('&amp;&amp;&amp;&amp;&amp;',$Uri->this('second'));
}
function testSetSeperator() {
$Uri = new Calendar_Decorator_Uri($this->mockcal);
$Uri->setFragments('year','month','day','hour','minute','second');
$Uri->setSeparator('/');
$this->assertEqual('year=/month=/day=/hour=/minute=/second=',$Uri->this('second'));
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfDecoratorUri();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/minute_test.php
New file
0,0 → 1,99
<?php
// $Id: minute_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./calendar_test.php');
 
class TestOfMinute extends TestOfCalendar {
function TestOfMinute() {
$this->UnitTestCase('Test of Minute');
}
function setUp() {
$this->cal = new Calendar_Minute(2003,10,25,13,32);
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 10,
'day' => 24,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
function testPrevSecond () {
$this->assertEqual(59,$this->cal->prevSecond());
}
function testThisSecond () {
$this->assertEqual(0,$this->cal->thisSecond());
}
function testThisSecond_Timestamp () {
$this->assertEqual($this->cal->cE->dateToStamp(
2003, 10, 25, 13, 32, 0),
$this->cal->thisSecond('timestamp'));
}
function testNextSecond () {
$this->assertEqual(1,$this->cal->nextSecond());
}
function testNextSecond_Timestamp () {
$this->assertEqual($this->cal->cE->dateToStamp(
2003, 10, 25, 13, 32, 1),
$this->cal->nextSecond('timestamp'));
}
function testGetTimeStamp() {
$stamp = mktime(13,32,0,10,25,2003);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
}
 
class TestOfMinuteBuild extends TestOfMinute {
function TestOfMinuteBuild() {
$this->UnitTestCase('Test of Minute::build()');
}
function testSize() {
$this->cal->build();
$this->assertEqual(60,$this->cal->size());
}
function testFetch() {
$this->cal->build();
$i=0;
while ( $Child = $this->cal->fetch() ) {
$i++;
}
$this->assertEqual(60,$i);
}
function testFetchAll() {
$this->cal->build();
$children = array();
$i = 0;
while ( $Child = $this->cal->fetch() ) {
$children[$i]=$Child;
$i++;
}
$this->assertEqual($children,$this->cal->fetchAll());
}
function testSelection() {
require_once(CALENDAR_ROOT . 'Second.php');
$selection = array(new Calendar_Second(2003,10,25,13,32,43));
$this->cal->build($selection);
$i = 0;
while ( $Child = $this->cal->fetch() ) {
if ( $i == 43 )
break;
$i++;
}
$this->assertTrue($Child->isSelected());
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfMinute();
$test->run(new HtmlReporter());
$test = &new TestOfMinuteBuild();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/calendar_tabular_tests.php
New file
0,0 → 1,22
<?php
// $Id: calendar_tabular_tests.php,v 1.2 2005/10/20 18:59:45 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class CalendarTabularTests extends GroupTest {
function CalendarTabularTests() {
$this->GroupTest('Calendar Tabular Tests');
$this->addTestFile('month_weekdays_test.php');
$this->addTestFile('month_weeks_test.php');
$this->addTestFile('week_test.php');
//$this->addTestFile('week_firstday_0_test.php'); //switch with the above
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new CalendarTabularTests();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/calendar_test.php
New file
0,0 → 1,115
<?php
// $Id: calendar_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class TestOfCalendar extends UnitTestCase {
var $cal;
function TestOfCalendar($name='Test of Calendar') {
$this->UnitTestCase($name);
}
function setUp() {
$this->cal = new Calendar(2003,10,25,13,32,43);
}
function tearDown() {
unset($this->cal);
}
function testPrevYear () {
$this->assertEqual(2002,$this->cal->prevYear());
}
function testPrevYear_Array () {
$this->assertEqual(
array(
'year' => 2002,
'month' => 1,
'day' => 1,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevYear('array'));
}
function testThisYear () {
$this->assertEqual(2003,$this->cal->thisYear());
}
function testNextYear () {
$this->assertEqual(2004,$this->cal->nextYear());
}
function testPrevMonth () {
$this->assertEqual(9,$this->cal->prevMonth());
}
function testPrevMonth_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 9,
'day' => 1,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevMonth('array'));
}
function testThisMonth () {
$this->assertEqual(10,$this->cal->thisMonth());
}
function testNextMonth () {
$this->assertEqual(11,$this->cal->nextMonth());
}
function testPrevDay () {
$this->assertEqual(24,$this->cal->prevDay());
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 10,
'day' => 24,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
function testThisDay () {
$this->assertEqual(25,$this->cal->thisDay());
}
function testNextDay () {
$this->assertEqual(26,$this->cal->nextDay());
}
function testPrevHour () {
$this->assertEqual(12,$this->cal->prevHour());
}
function testThisHour () {
$this->assertEqual(13,$this->cal->thisHour());
}
function testNextHour () {
$this->assertEqual(14,$this->cal->nextHour());
}
function testPrevMinute () {
$this->assertEqual(31,$this->cal->prevMinute());
}
function testThisMinute () {
$this->assertEqual(32,$this->cal->thisMinute());
}
function testNextMinute () {
$this->assertEqual(33,$this->cal->nextMinute());
}
function testPrevSecond () {
$this->assertEqual(42,$this->cal->prevSecond());
}
function testThisSecond () {
$this->assertEqual(43,$this->cal->thisSecond());
}
function testNextSecond () {
$this->assertEqual(44,$this->cal->nextSecond());
}
function testSetTimeStamp() {
$stamp = mktime(13,32,43,10,25,2003);
$this->cal->setTimeStamp($stamp);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
function testGetTimeStamp() {
$stamp = mktime(13,32,43,10,25,2003);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/peardate_engine_test.php
New file
0,0 → 1,124
<?php
// $Id: peardate_engine_test.php,v 1.2 2004/08/16 11:36:51 hfuecks Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class TestOfPearDateEngine extends UnitTestCase {
var $engine;
function TestOfPearDateEngine() {
$this->UnitTestCase('Test of Calendar_Engine_PearDate');
}
function setUp() {
$this->engine = new Calendar_Engine_PearDate();
}
function testGetSecondsInMinute() {
$this->assertEqual($this->engine->getSecondsInMinute(),60);
}
function testGetMinutesInHour() {
$this->assertEqual($this->engine->getMinutesInHour(),60);
}
function testGetHoursInDay() {
$this->assertEqual($this->engine->getHoursInDay(),24);
}
function testGetFirstDayOfWeek() {
$this->assertEqual($this->engine->getFirstDayOfWeek(),1);
}
function testGetWeekDays() {
$this->assertEqual($this->engine->getWeekDays(),array(0,1,2,3,4,5,6));
}
function testGetDaysInWeek() {
$this->assertEqual($this->engine->getDaysInWeek(),7);
}
function testGetWeekNInYear() {
$this->assertEqual($this->engine->getWeekNInYear(2003, 11, 3), 45);
}
function testGetWeekNInMonth() {
$this->assertEqual($this->engine->getWeekNInMonth(2003, 11, 3), 2);
}
function testGetWeeksInMonth0() {
$this->assertEqual($this->engine->getWeeksInMonth(2003, 11, 0), 6); //week starts on sunday
}
function testGetWeeksInMonth1() {
$this->assertEqual($this->engine->getWeeksInMonth(2003, 11, 1), 5); //week starts on monday
}
function testGetWeeksInMonth2() {
$this->assertEqual($this->engine->getWeeksInMonth(2003, 2, 6), 4); //week starts on saturday
}
function testGetWeeksInMonth3() {
// Unusual cases that can cause fails (shows up with example 21.php)
$this->assertEqual($this->engine->getWeeksInMonth(2004,2,1),5);
$this->assertEqual($this->engine->getWeeksInMonth(2004,8,1),6);
}
function testGetDayOfWeek() {
$this->assertEqual($this->engine->getDayOfWeek(2003, 11, 18), 2);
}
function testGetFirstDayInMonth() {
$this->assertEqual($this->engine->getFirstDayInMonth(2003,10),3);
}
function testGetDaysInMonth() {
$this->assertEqual($this->engine->getDaysInMonth(2003,10),31);
}
function testGetMinYears() {
$this->assertEqual($this->engine->getMinYears(),0);
}
function testGetMaxYears() {
$this->assertEqual($this->engine->getMaxYears(),9999);
}
function testDateToStamp() {
$stamp = '2003-10-15 13:30:45';
$this->assertEqual($this->engine->dateToStamp(2003,10,15,13,30,45),$stamp);
}
function testStampToSecond() {
$stamp = '2003-10-15 13:30:45';
$this->assertEqual($this->engine->stampToSecond($stamp),45);
}
function testStampToMinute() {
$stamp = '2003-10-15 13:30:45';
$this->assertEqual($this->engine->stampToMinute($stamp),30);
}
function testStampToHour() {
$stamp = '2003-10-15 13:30:45';
$this->assertEqual($this->engine->stampToHour($stamp),13);
}
function testStampToDay() {
$stamp = '2003-10-15 13:30:45';
$this->assertEqual($this->engine->stampToDay($stamp),15);
}
function testStampToMonth() {
$stamp = '2003-10-15 13:30:45';
$this->assertEqual($this->engine->stampToMonth($stamp),10);
}
function testStampToYear() {
$stamp = '2003-10-15 13:30:45';
$this->assertEqual($this->engine->stampToYear($stamp),2003);
}
function testAdjustDate() {
$stamp = '2004-01-01 13:30:45';
$y = $this->engine->stampToYear($stamp);
$m = $this->engine->stampToMonth($stamp);
$d = $this->engine->stampToDay($stamp);
 
//the first day of the month should be thursday
$this->assertEqual($this->engine->getDayOfWeek($y, $m, $d), 4);
 
$m--; // 2004-00-01 => 2003-12-01
$this->engine->adjustDate($y, $m, $d, $dummy, $dummy, $dummy);
 
$this->assertEqual($y, 2003);
$this->assertEqual($m, 12);
$this->assertEqual($d, 1);
 
// get last day and check if it's wednesday
$d = $this->engine->getDaysInMonth($y, $m);
 
$this->assertEqual($this->engine->getDayOfWeek($y, $m, $d), 3);
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfPearDateEngine();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/second_test.php
New file
0,0 → 1,34
<?php
// $Id: second_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./calendar_test.php');
 
class TestOfSecond extends TestOfCalendar {
function TestOfSecond() {
$this->UnitTestCase('Test of Second');
}
function setUp() {
$this->cal = new Calendar_Second(2003,10,25,13,32,43);
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 10,
'day' => 24,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfSecond();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/calendar_include.php
New file
0,0 → 1,28
<?php
// $Id: calendar_include.php,v 1.4 2004/08/16 12:56:10 hfuecks Exp $
if ( !@include 'Calendar/Calendar.php' ) {
@define('CALENDAR_ROOT','../');
}
require_once(CALENDAR_ROOT . 'Year.php');
require_once(CALENDAR_ROOT . 'Month.php');
require_once(CALENDAR_ROOT . 'Day.php');
require_once(CALENDAR_ROOT . 'Week.php');
require_once(CALENDAR_ROOT . 'Hour.php');
require_once(CALENDAR_ROOT . 'Minute.php');
require_once(CALENDAR_ROOT . 'Second.php');
require_once(CALENDAR_ROOT . 'Month.php');
require_once(CALENDAR_ROOT . 'Decorator.php');
require_once(CALENDAR_ROOT . 'Month/Weekdays.php');
require_once(CALENDAR_ROOT . 'Month/Weeks.php');
require_once(CALENDAR_ROOT . 'Validator.php');
require_once(CALENDAR_ROOT . 'Engine/Interface.php');
require_once(CALENDAR_ROOT . 'Engine/UnixTs.php');
require_once(CALENDAR_ROOT . 'Engine/PearDate.php');
require_once(CALENDAR_ROOT . 'Table/Helper.php');
require_once(CALENDAR_ROOT . 'Decorator/Textual.php');
require_once(CALENDAR_ROOT . 'Decorator/Uri.php');
require_once(CALENDAR_ROOT . 'Decorator/Weekday.php');
require_once(CALENDAR_ROOT . 'Decorator/Wrapper.php');
require_once(CALENDAR_ROOT . 'Util/Uri.php');
require_once(CALENDAR_ROOT . 'Util/Textual.php');
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/day_test.php
New file
0,0 → 1,107
<?php
// $Id: day_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./calendar_test.php');
 
class TestOfDay extends TestOfCalendar {
function TestOfDay() {
$this->UnitTestCase('Test of Day');
}
function setUp() {
$this->cal = new Calendar_Day(2003,10,25);
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 10,
'day' => 24,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
function testPrevHour () {
$this->assertEqual(23,$this->cal->prevHour());
}
function testThisHour () {
$this->assertEqual(0,$this->cal->thisHour());
}
function testNextHour () {
$this->assertEqual(1,$this->cal->nextHour());
}
function testPrevMinute () {
$this->assertEqual(59,$this->cal->prevMinute());
}
function testThisMinute () {
$this->assertEqual(0,$this->cal->thisMinute());
}
function testNextMinute () {
$this->assertEqual(1,$this->cal->nextMinute());
}
function testPrevSecond () {
$this->assertEqual(59,$this->cal->prevSecond());
}
function testThisSecond () {
$this->assertEqual(0,$this->cal->thisSecond());
}
function testNextSecond () {
$this->assertEqual(1,$this->cal->nextSecond());
}
function testGetTimeStamp() {
$stamp = mktime(0,0,0,10,25,2003);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
}
 
class TestOfDayBuild extends TestOfDay {
function TestOfDayBuild() {
$this->UnitTestCase('Test of Day::build()');
}
function testSize() {
$this->cal->build();
$this->assertEqual(24,$this->cal->size());
}
function testFetch() {
$this->cal->build();
$i=0;
while ( $Child = $this->cal->fetch() ) {
$i++;
}
$this->assertEqual(24,$i);
}
function testFetchAll() {
$this->cal->build();
$children = array();
$i = 0;
while ( $Child = $this->cal->fetch() ) {
$children[$i]=$Child;
$i++;
}
$this->assertEqual($children,$this->cal->fetchAll());
}
function testSelection() {
require_once(CALENDAR_ROOT . 'Hour.php');
$selection = array(new Calendar_Hour(2003,10,25,13));
$this->cal->build($selection);
$i = 0;
while ( $Child = $this->cal->fetch() ) {
if ( $i == 13 )
break;
$i++;
}
$this->assertTrue($Child->isSelected());
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfDay();
$test->run(new HtmlReporter());
$test = &new TestOfDayBuild();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/unixts_engine_test.php
New file
0,0 → 1,104
<?php
// $Id: unixts_engine_test.php,v 1.2 2004/08/16 11:36:51 hfuecks Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class TestOfUnixTsEngine extends UnitTestCase {
var $engine;
function TestOfUnixTsEngine() {
$this->UnitTestCase('Test of Calendar_Engine_UnixTs');
}
function setUp() {
$this->engine = new Calendar_Engine_UnixTs();
}
function testGetSecondsInMinute() {
$this->assertEqual($this->engine->getSecondsInMinute(),60);
}
function testGetMinutesInHour() {
$this->assertEqual($this->engine->getMinutesInHour(),60);
}
function testGetHoursInDay() {
$this->assertEqual($this->engine->getHoursInDay(),24);
}
function testGetFirstDayOfWeek() {
$this->assertEqual($this->engine->getFirstDayOfWeek(),1);
}
function testGetWeekDays() {
$this->assertEqual($this->engine->getWeekDays(),array(0,1,2,3,4,5,6));
}
function testGetDaysInWeek() {
$this->assertEqual($this->engine->getDaysInWeek(),7);
}
function testGetWeekNInYear() {
$this->assertEqual($this->engine->getWeekNInYear(2003, 11, 3), 45);
}
function testGetWeekNInMonth() {
$this->assertEqual($this->engine->getWeekNInMonth(2003, 11, 3), 2);
}
function testGetWeeksInMonth0() {
$this->assertEqual($this->engine->getWeeksInMonth(2003, 11, 0), 6); //week starts on sunday
}
function testGetWeeksInMonth1() {
$this->assertEqual($this->engine->getWeeksInMonth(2003, 11, 1), 5); //week starts on monday
}
function testGetWeeksInMonth2() {
$this->assertEqual($this->engine->getWeeksInMonth(2003, 2, 6), 4); //week starts on saturday
}
function testGetWeeksInMonth3() {
// Unusual cases that can cause fails (shows up with example 21.php)
$this->assertEqual($this->engine->getWeeksInMonth(2004,2,1),5);
$this->assertEqual($this->engine->getWeeksInMonth(2004,8,1),6);
}
function testGetDayOfWeek() {
$this->assertEqual($this->engine->getDayOfWeek(2003, 11, 18), 2);
}
function testGetFirstDayInMonth() {
$this->assertEqual($this->engine->getFirstDayInMonth(2003,10),3);
}
function testGetDaysInMonth() {
$this->assertEqual($this->engine->getDaysInMonth(2003,10),31);
}
function testGetMinYears() {
$test = strpos(PHP_OS, 'WIN') >= 0 ? 1970 : 1902;
$this->assertEqual($this->engine->getMinYears(),$test);
}
function testGetMaxYears() {
$this->assertEqual($this->engine->getMaxYears(),2037);
}
function testDateToStamp() {
$stamp = mktime(0,0,0,10,15,2003);
$this->assertEqual($this->engine->dateToStamp(2003,10,15,0,0,0),$stamp);
}
function testStampToSecond() {
$stamp = mktime(13,30,45,10,15,2003);
$this->assertEqual($this->engine->stampToSecond($stamp),45);
}
function testStampToMinute() {
$stamp = mktime(13,30,45,10,15,2003);
$this->assertEqual($this->engine->stampToMinute($stamp),30);
}
function testStampToHour() {
$stamp = mktime(13,30,45,10,15,2003);
$this->assertEqual($this->engine->stampToHour($stamp),13);
}
function testStampToDay() {
$stamp = mktime(13,30,45,10,15,2003);
$this->assertEqual($this->engine->stampToDay($stamp),15);
}
function testStampToMonth() {
$stamp = mktime(13,30,45,10,15,2003);
$this->assertEqual($this->engine->stampToMonth($stamp),10);
}
function testStampToYear() {
$stamp = mktime(13,30,45,10,15,2003);
$this->assertEqual($this->engine->stampToYear($stamp),2003);
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfUnixTsEngine();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/decorator_test.php
New file
0,0 → 1,268
<?php
// $Id: decorator_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
Mock::generate('Calendar_Engine_Interface','Mock_Calendar_Engine');
Mock::generate('Calendar_Second','Mock_Calendar_Second');
Mock::generate('Calendar_Week','Mock_Calendar_Week');
Mock::generate('Calendar_Day','Mock_Calendar_Day');
 
class TestOfDecorator extends UnitTestCase {
var $mockengine;
var $mockcal;
var $decorator;
function TestOfDecorator() {
$this->UnitTestCase('Test of Calendar_Decorator');
}
function setUp() {
$this->mockengine = new Mock_Calendar_Engine($this);
$this->mockcal = new Mock_Calendar_Second($this);
$this->mockcal->setReturnValue('prevYear',2002);
$this->mockcal->setReturnValue('thisYear',2003);
$this->mockcal->setReturnValue('nextYear',2004);
$this->mockcal->setReturnValue('prevMonth',9);
$this->mockcal->setReturnValue('thisMonth',10);
$this->mockcal->setReturnValue('nextMonth',11);
$this->mockcal->setReturnValue('prevDay',14);
$this->mockcal->setReturnValue('thisDay',15);
$this->mockcal->setReturnValue('nextDay',16);
$this->mockcal->setReturnValue('prevHour',12);
$this->mockcal->setReturnValue('thisHour',13);
$this->mockcal->setReturnValue('nextHour',14);
$this->mockcal->setReturnValue('prevMinute',29);
$this->mockcal->setReturnValue('thisMinute',30);
$this->mockcal->setReturnValue('nextMinute',31);
$this->mockcal->setReturnValue('prevSecond',44);
$this->mockcal->setReturnValue('thisSecond',45);
$this->mockcal->setReturnValue('nextSecond',46);
$this->mockcal->setReturnValue('getEngine',$this->mockengine);
$this->mockcal->setReturnValue('getTimestamp',12345);
 
}
function tearDown() {
unset ( $this->engine );
unset ( $this->mockcal );
}
function testPrevYear() {
$this->mockcal->expectOnce('prevYear',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(2002,$Decorator->prevYear());
}
function testThisYear() {
$this->mockcal->expectOnce('thisYear',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(2003,$Decorator->thisYear());
}
function testNextYear() {
$this->mockcal->expectOnce('nextYear',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(2004,$Decorator->nextYear());
}
function testPrevMonth() {
$this->mockcal->expectOnce('prevMonth',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(9,$Decorator->prevMonth());
}
function testThisMonth() {
$this->mockcal->expectOnce('thisMonth',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(10,$Decorator->thisMonth());
}
function testNextMonth() {
$this->mockcal->expectOnce('nextMonth',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(11,$Decorator->nextMonth());
}
function testPrevWeek() {
$mockweek = & new Mock_Calendar_Week($this);
$mockweek->setReturnValue('prevWeek',1);
$mockweek->expectOnce('prevWeek',array('n_in_month'));
$Decorator =& new Calendar_Decorator($mockweek);
$this->assertEqual(1,$Decorator->prevWeek());
}
function testThisWeek() {
$mockweek = & new Mock_Calendar_Week($this);
$mockweek->setReturnValue('thisWeek',2);
$mockweek->expectOnce('thisWeek',array('n_in_month'));
$Decorator =& new Calendar_Decorator($mockweek);
$this->assertEqual(2,$Decorator->thisWeek());
}
function testNextWeek() {
$mockweek = & new Mock_Calendar_Week($this);
$mockweek->setReturnValue('nextWeek',3);
$mockweek->expectOnce('nextWeek',array('n_in_month'));
$Decorator =& new Calendar_Decorator($mockweek);
$this->assertEqual(3,$Decorator->nextWeek());
}
function testPrevDay() {
$this->mockcal->expectOnce('prevDay',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(14,$Decorator->prevDay());
}
function testThisDay() {
$this->mockcal->expectOnce('thisDay',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(15,$Decorator->thisDay());
}
function testNextDay() {
$this->mockcal->expectOnce('nextDay',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(16,$Decorator->nextDay());
}
function testPrevHour() {
$this->mockcal->expectOnce('prevHour',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(12,$Decorator->prevHour());
}
function testThisHour() {
$this->mockcal->expectOnce('thisHour',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(13,$Decorator->thisHour());
}
function testNextHour() {
$this->mockcal->expectOnce('nextHour',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(14,$Decorator->nextHour());
}
function testPrevMinute() {
$this->mockcal->expectOnce('prevMinute',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(29,$Decorator->prevMinute());
}
function testThisMinute() {
$this->mockcal->expectOnce('thisMinute',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(30,$Decorator->thisMinute());
}
function testNextMinute() {
$this->mockcal->expectOnce('nextMinute',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(31,$Decorator->nextMinute());
}
function testPrevSecond() {
$this->mockcal->expectOnce('prevSecond',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(44,$Decorator->prevSecond());
}
function testThisSecond() {
$this->mockcal->expectOnce('thisSecond',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(45,$Decorator->thisSecond());
}
function testNextSecond() {
$this->mockcal->expectOnce('nextSecond',array('int'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(46,$Decorator->nextSecond());
}
function testGetEngine() {
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertIsA($Decorator->getEngine(),'Mock_Calendar_Engine');
}
function testSetTimestamp() {
$this->mockcal->expectOnce('setTimestamp',array('12345'));
$Decorator =& new Calendar_Decorator($this->mockcal);
$Decorator->setTimestamp('12345');
}
function testGetTimestamp() {
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual(12345,$Decorator->getTimestamp());
}
function testSetSelected() {
$this->mockcal->expectOnce('setSelected',array(true));
$Decorator =& new Calendar_Decorator($this->mockcal);
$Decorator->setSelected();
}
function testIsSelected() {
$this->mockcal->setReturnValue('isSelected',true);
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertTrue($Decorator->isSelected());
}
function testAdjust() {
$this->mockcal->expectOnce('adjust',array());
$Decorator =& new Calendar_Decorator($this->mockcal);
$Decorator->adjust();
}
function testToArray() {
$this->mockcal->expectOnce('toArray',array(12345));
$testArray = array('foo'=>'bar');
$this->mockcal->setReturnValue('toArray',$testArray);
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual($testArray,$Decorator->toArray(12345));
}
function testReturnValue() {
$this->mockcal->expectOnce('returnValue',array('a','b','c','d'));
$this->mockcal->setReturnValue('returnValue','foo');
$Decorator =& new Calendar_Decorator($this->mockcal);
$this->assertEqual('foo',$Decorator->returnValue('a','b','c','d'));
}
function testSetFirst() {
$mockday = & new Mock_Calendar_Day($this);
$mockday->expectOnce('setFirst',array(true));
$Decorator =& new Calendar_Decorator($mockday);
$Decorator->setFirst();
}
function testSetLast() {
$mockday = & new Mock_Calendar_Day($this);
$mockday->expectOnce('setLast',array(true));
$Decorator =& new Calendar_Decorator($mockday);
$Decorator->setLast();
}
function testIsFirst() {
$mockday = & new Mock_Calendar_Day($this);
$mockday->setReturnValue('isFirst',TRUE);
$Decorator =& new Calendar_Decorator($mockday);
$this->assertTrue($Decorator->isFirst());
}
function testIsLast() {
$mockday = & new Mock_Calendar_Day($this);
$mockday->setReturnValue('isLast',TRUE);
$Decorator =& new Calendar_Decorator($mockday);
$this->assertTrue($Decorator->isLast());
}
function testSetEmpty() {
$mockday = & new Mock_Calendar_Day($this);
$mockday->expectOnce('setEmpty',array(true));
$Decorator =& new Calendar_Decorator($mockday);
$Decorator->setEmpty();
}
function testIsEmpty() {
$mockday = & new Mock_Calendar_Day($this);
$mockday->setReturnValue('isEmpty',TRUE);
$Decorator =& new Calendar_Decorator($mockday);
$this->assertTrue($Decorator->isEmpty());
}
function testBuild() {
$testArray=array('foo'=>'bar');
$this->mockcal->expectOnce('build',array($testArray));
$Decorator =& new Calendar_Decorator($this->mockcal);
$Decorator->build($testArray);
}
function testFetch() {
$this->mockcal->expectOnce('fetch',array());
$Decorator =& new Calendar_Decorator($this->mockcal);
$Decorator->fetch();
}
function testFetchAll() {
$this->mockcal->expectOnce('fetchAll',array());
$Decorator =& new Calendar_Decorator($this->mockcal);
$Decorator->fetchAll();
}
function testSize() {
$this->mockcal->expectOnce('size',array());
$Decorator =& new Calendar_Decorator($this->mockcal);
$Decorator->size();
}
function testIsValid() {
$this->mockcal->expectOnce('isValid',array());
$Decorator =& new Calendar_Decorator($this->mockcal);
$Decorator->isValid();
}
function testGetValidator() {
$this->mockcal->expectOnce('getValidator',array());
$Decorator =& new Calendar_Decorator($this->mockcal);
$Decorator->getValidator();
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/month_weeks_test.php
New file
0,0 → 1,125
<?php
// $Id: month_weeks_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./calendar_test.php');
 
class TestOfMonthWeeks extends TestOfCalendar {
function TestOfMonthWeeks() {
$this->UnitTestCase('Test of Month Weeks');
}
function setUp() {
$this->cal = new Calendar_Month_Weeks(2003,10);
}
function testPrevDay () {
$this->assertEqual(30,$this->cal->prevDay());
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 9,
'day' => 30,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
function testThisDay () {
$this->assertEqual(1,$this->cal->thisDay());
}
function testNextDay () {
$this->assertEqual(2,$this->cal->nextDay());
}
function testPrevHour () {
$this->assertEqual(23,$this->cal->prevHour());
}
function testThisHour () {
$this->assertEqual(0,$this->cal->thisHour());
}
function testNextHour () {
$this->assertEqual(1,$this->cal->nextHour());
}
function testPrevMinute () {
$this->assertEqual(59,$this->cal->prevMinute());
}
function testThisMinute () {
$this->assertEqual(0,$this->cal->thisMinute());
}
function testNextMinute () {
$this->assertEqual(1,$this->cal->nextMinute());
}
function testPrevSecond () {
$this->assertEqual(59,$this->cal->prevSecond());
}
function testThisSecond () {
$this->assertEqual(0,$this->cal->thisSecond());
}
function testNextSecond () {
$this->assertEqual(1,$this->cal->nextSecond());
}
function testGetTimeStamp() {
$stamp = mktime(0,0,0,10,1,2003);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
}
 
class TestOfMonthWeeksBuild extends TestOfMonthWeeks {
function TestOfMonthWeeksBuild() {
$this->UnitTestCase('Test of Month_Weeks::build()');
}
function testSize() {
$this->cal->build();
$this->assertEqual(5,$this->cal->size());
}
 
function testFetch() {
$this->cal->build();
$i=0;
while ( $Child = $this->cal->fetch() ) {
$i++;
}
$this->assertEqual(5,$i);
}
/* Recusive dependency issue with SimpleTest
function testFetchAll() {
$this->cal->build();
$children = array();
$i = 1;
while ( $Child = $this->cal->fetch() ) {
$children[$i]=$Child;
$i++;
}
$this->assertEqual($children,$this->cal->fetchAll());
}
*/
function testSelection() {
require_once(CALENDAR_ROOT . 'Week.php');
$selection = array(new Calendar_Week(2003, 10, 12));
$this->cal->build($selection);
$i = 1;
while ($Child = $this->cal->fetch()) {
if ($i == 2) {
break; //12-10-2003 is the 2nd day of the week
}
$i++;
}
$this->assertTrue($Child->isSelected());
}
function testEmptyDaysBefore_AfterAdjust() {
$this->cal = new Calendar_Month_Weeks(2004,0);
$this->cal->build();
$this->assertEqual(0,$this->cal->tableHelper->getEmptyDaysBefore());
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfMonthWeeks();
$test->run(new HtmlReporter());
$test = &new TestOfMonthWeeksBuild();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/util_textual_test.php
New file
0,0 → 1,191
<?php
// $Id: util_textual_test.php,v 1.1 2004/08/16 12:56:10 hfuecks Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./decorator_test.php');
 
class TestOfUtilTextual extends UnitTestCase {
var $mockengine;
var $mockcal;
function TestOfUtilTextual() {
$this->UnitTestCase('Test of Calendar_Util_Textual');
}
function setUp() {
$this->mockengine = new Mock_Calendar_Engine($this);
$this->mockcal = new Mock_Calendar_Second($this);
$this->mockcal->setReturnValue('prevYear',2002);
$this->mockcal->setReturnValue('thisYear',2003);
$this->mockcal->setReturnValue('nextYear',2004);
$this->mockcal->setReturnValue('prevMonth',9);
$this->mockcal->setReturnValue('thisMonth',10);
$this->mockcal->setReturnValue('nextMonth',11);
$this->mockcal->setReturnValue('prevDay',14);
$this->mockcal->setReturnValue('thisDay',15);
$this->mockcal->setReturnValue('nextDay',16);
$this->mockcal->setReturnValue('prevHour',12);
$this->mockcal->setReturnValue('thisHour',13);
$this->mockcal->setReturnValue('nextHour',14);
$this->mockcal->setReturnValue('prevMinute',29);
$this->mockcal->setReturnValue('thisMinute',30);
$this->mockcal->setReturnValue('nextMinute',31);
$this->mockcal->setReturnValue('prevSecond',44);
$this->mockcal->setReturnValue('thisSecond',45);
$this->mockcal->setReturnValue('nextSecond',46);
$this->mockcal->setReturnValue('getEngine',$this->mockengine);
$this->mockcal->setReturnValue('getTimestamp',12345);
}
function tearDown() {
unset ( $this->engine );
unset ( $this->mockcal );
}
function testMonthNamesLong() {
$monthNames = array(
1=>'January',
2=>'February',
3=>'March',
4=>'April',
5=>'May',
6=>'June',
7=>'July',
8=>'August',
9=>'September',
10=>'October',
11=>'November',
12=>'December',
);
$this->assertEqual($monthNames,Calendar_Util_Textual::monthNames());
}
function testMonthNamesShort() {
$monthNames = array(
1=>'Jan',
2=>'Feb',
3=>'Mar',
4=>'Apr',
5=>'May',
6=>'Jun',
7=>'Jul',
8=>'Aug',
9=>'Sep',
10=>'Oct',
11=>'Nov',
12=>'Dec',
);
$this->assertEqual($monthNames,Calendar_Util_Textual::monthNames('short'));
}
function testMonthNamesTwo() {
$monthNames = array(
1=>'Ja',
2=>'Fe',
3=>'Ma',
4=>'Ap',
5=>'Ma',
6=>'Ju',
7=>'Ju',
8=>'Au',
9=>'Se',
10=>'Oc',
11=>'No',
12=>'De',
);
$this->assertEqual($monthNames,Calendar_Util_Textual::monthNames('two'));
}
function testMonthNamesOne() {
$monthNames = array(
1=>'J',
2=>'F',
3=>'M',
4=>'A',
5=>'M',
6=>'J',
7=>'J',
8=>'A',
9=>'S',
10=>'O',
11=>'N',
12=>'D',
);
$this->assertEqual($monthNames,Calendar_Util_Textual::monthNames('one'));
}
function testWeekdayNamesLong() {
$weekdayNames = array(
0=>'Sunday',
1=>'Monday',
2=>'Tuesday',
3=>'Wednesday',
4=>'Thursday',
5=>'Friday',
6=>'Saturday',
);
$this->assertEqual($weekdayNames,Calendar_Util_Textual::weekdayNames());
}
function testWeekdayNamesShort() {
$weekdayNames = array(
0=>'Sun',
1=>'Mon',
2=>'Tue',
3=>'Wed',
4=>'Thu',
5=>'Fri',
6=>'Sat',
);
$this->assertEqual($weekdayNames,Calendar_Util_Textual::weekdayNames('short'));
}
function testWeekdayNamesTwo() {
$weekdayNames = array(
0=>'Su',
1=>'Mo',
2=>'Tu',
3=>'We',
4=>'Th',
5=>'Fr',
6=>'Sa',
);
$this->assertEqual($weekdayNames,Calendar_Util_Textual::weekdayNames('two'));
}
function testWeekdayNamesOne() {
$weekdayNames = array(
0=>'S',
1=>'M',
2=>'T',
3=>'W',
4=>'T',
5=>'F',
6=>'S',
);
$this->assertEqual($weekdayNames,Calendar_Util_Textual::weekdayNames('one'));
}
function testPrevMonthNameShort() {
$this->assertEqual('Sep',Calendar_Util_Textual::prevMonthName($this->mockcal,'short'));
}
function testThisMonthNameShort() {
$this->assertEqual('Oct',Calendar_Util_Textual::thisMonthName($this->mockcal,'short'));
}
function testNextMonthNameShort() {
$this->assertEqual('Nov',Calendar_Util_Textual::nextMonthName($this->mockcal,'short'));
}
function testThisDayNameShort() {
$this->assertEqual('Wed',Calendar_Util_Textual::thisDayName($this->mockcal,'short'));
}
function testOrderedWeekdaysShort() {
$weekdayNames = array(
0=>'Sun',
1=>'Mon',
2=>'Tue',
3=>'Wed',
4=>'Thu',
5=>'Fri',
6=>'Sat',
);
$this->assertEqual($weekdayNames,Calendar_Util_Textual::orderedWeekdays($this->mockcal,'short'));
}
 
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfUtilTextual();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/validator_unit_test.php
New file
0,0 → 1,210
<?php
// $Id: validator_unit_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
Mock::generate('Calendar_Engine_Interface','Mock_Calendar_Engine');
Mock::generate('Calendar_Second','Mock_Calendar_Second');
 
class TestOfValidator extends UnitTestCase {
var $mockengine;
var $mockcal;
function TestOfValidator() {
$this->UnitTestCase('Test of Validator');
}
function setUp() {
$this->mockengine = new Mock_Calendar_Engine($this);
$this->mockengine->setReturnValue('getMinYears',1970);
$this->mockengine->setReturnValue('getMaxYears',2037);
$this->mockengine->setReturnValue('getMonthsInYear',12);
$this->mockengine->setReturnValue('getDaysInMonth',30);
$this->mockengine->setReturnValue('getHoursInDay',24);
$this->mockengine->setReturnValue('getMinutesInHour',60);
$this->mockengine->setReturnValue('getSecondsInMinute',60);
$this->mockcal = new Mock_Calendar_Second($this);
$this->mockcal->setReturnValue('getEngine',$this->mockengine);
}
function tearDown() {
unset ($this->mockengine);
unset ($this->mocksecond);
}
function testIsValidYear() {
$this->mockcal->setReturnValue('thisYear',2000);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertTrue($Validator->isValidYear());
}
function testIsValidYearTooSmall() {
$this->mockcal->setReturnValue('thisYear',1969);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidYear());
}
function testIsValidYearTooLarge() {
$this->mockcal->setReturnValue('thisYear',2038);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidYear());
}
function testIsValidMonth() {
$this->mockcal->setReturnValue('thisMonth',10);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertTrue($Validator->isValidMonth());
}
function testIsValidMonthTooSmall() {
$this->mockcal->setReturnValue('thisMonth',0);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidMonth());
}
function testIsValidMonthTooLarge() {
$this->mockcal->setReturnValue('thisMonth',13);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidMonth());
}
function testIsValidDay() {
$this->mockcal->setReturnValue('thisDay',10);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertTrue($Validator->isValidDay());
}
function testIsValidDayTooSmall() {
$this->mockcal->setReturnValue('thisDay',0);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidDay());
}
function testIsValidDayTooLarge() {
$this->mockcal->setReturnValue('thisDay',31);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidDay());
}
function testIsValidHour() {
$this->mockcal->setReturnValue('thisHour',10);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertTrue($Validator->isValidHour());
}
function testIsValidHourTooSmall() {
$this->mockcal->setReturnValue('thisHour',-1);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidHour());
}
function testIsValidHourTooLarge() {
$this->mockcal->setReturnValue('thisHour',24);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidHour());
}
function testIsValidMinute() {
$this->mockcal->setReturnValue('thisMinute',30);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertTrue($Validator->isValidMinute());
}
function testIsValidMinuteTooSmall() {
$this->mockcal->setReturnValue('thisMinute',-1);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidMinute());
}
function testIsValidMinuteTooLarge() {
$this->mockcal->setReturnValue('thisMinute',60);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidMinute());
}
function testIsValidSecond() {
$this->mockcal->setReturnValue('thisSecond',30);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertTrue($Validator->isValidSecond());
}
function testIsValidSecondTooSmall() {
$this->mockcal->setReturnValue('thisSecond',-1);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidSecond());
}
function testIsValidSecondTooLarge() {
$this->mockcal->setReturnValue('thisSecond',60);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValidSecond());
}
function testIsValid() {
$this->mockcal->setReturnValue('thisYear',2000);
$this->mockcal->setReturnValue('thisMonth',5);
$this->mockcal->setReturnValue('thisDay',15);
$this->mockcal->setReturnValue('thisHour',13);
$this->mockcal->setReturnValue('thisMinute',30);
$this->mockcal->setReturnValue('thisSecond',40);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertTrue($Validator->isValid());
}
function testIsValidAllWrong() {
$this->mockcal->setReturnValue('thisYear',2038);
$this->mockcal->setReturnValue('thisMonth',13);
$this->mockcal->setReturnValue('thisDay',31);
$this->mockcal->day = 31;
$this->mockcal->setReturnValue('thisHour',24);
$this->mockcal->setReturnValue('thisMinute',60);
$this->mockcal->setReturnValue('thisSecond',60);
$Validator = & new Calendar_Validator($this->mockcal);
$this->assertFalse($Validator->isValid());
$i = 0;
while ( $Validator->fetch() ) {
$i++;
}
$this->assertEqual($i,6);
}
}
 
class TestOfValidatorLive extends UnitTestCase {
function TestOfValidatorLive() {
$this->UnitTestCase('Test of Validator Live');
}
function testYear() {
$Unit = new Calendar_Year(2038);
$Validator = & $Unit->getValidator();
$this->assertFalse($Validator->isValidYear());
}
function testMonth() {
$Unit = new Calendar_Month(2000,13);
$Validator = & $Unit->getValidator();
$this->assertFalse($Validator->isValidMonth());
}
/*
function testWeek() {
$Unit = new Calendar_Week(2000,12,7);
$Validator = & $Unit->getValidator();
$this->assertFalse($Validator->isValidWeek());
}
*/
function testDay() {
$Unit = new Calendar_Day(2000,12,32);
$Validator = & $Unit->getValidator();
$this->assertFalse($Validator->isValidDay());
}
function testHour() {
$Unit = new Calendar_Hour(2000,12,20,24);
$Validator = & $Unit->getValidator();
$this->assertFalse($Validator->isValidHour());
}
function testMinute() {
$Unit = new Calendar_Minute(2000,12,20,23,60);
$Validator = & $Unit->getValidator();
$this->assertFalse($Validator->isValidMinute());
}
function testSecond() {
$Unit = new Calendar_Second(2000,12,20,23,59,60);
$Validator = & $Unit->getValidator();
$this->assertFalse($Validator->isValidSecond());
}
function testAllBad() {
$Unit = new Calendar_Second(2000,13,32,24,60,60);
$this->assertFalse($Unit->isValid());
$Validator = & $Unit->getValidator();
$i = 0;
while ( $Validator->fetch() ) {
$i++;
}
$this->assertEqual($i,5);
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfValidator();
$test->run(new HtmlReporter());
$test = &new TestOfValidatorLive();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/decorator_textual_test.php
New file
0,0 → 1,174
<?php
// $Id: decorator_textual_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./decorator_test.php');
 
class TestOfDecoratorTextual extends TestOfDecorator {
function TestOfDecoratorTextual() {
$this->UnitTestCase('Test of Calendar_Decorator_Textual');
}
function testMonthNamesLong() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$monthNames = array(
1=>'January',
2=>'February',
3=>'March',
4=>'April',
5=>'May',
6=>'June',
7=>'July',
8=>'August',
9=>'September',
10=>'October',
11=>'November',
12=>'December',
);
$this->assertEqual($monthNames,$Textual->monthNames());
}
function testMonthNamesShort() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$monthNames = array(
1=>'Jan',
2=>'Feb',
3=>'Mar',
4=>'Apr',
5=>'May',
6=>'Jun',
7=>'Jul',
8=>'Aug',
9=>'Sep',
10=>'Oct',
11=>'Nov',
12=>'Dec',
);
$this->assertEqual($monthNames,$Textual->monthNames('short'));
}
function testMonthNamesTwo() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$monthNames = array(
1=>'Ja',
2=>'Fe',
3=>'Ma',
4=>'Ap',
5=>'Ma',
6=>'Ju',
7=>'Ju',
8=>'Au',
9=>'Se',
10=>'Oc',
11=>'No',
12=>'De',
);
$this->assertEqual($monthNames,$Textual->monthNames('two'));
}
function testMonthNamesOne() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$monthNames = array(
1=>'J',
2=>'F',
3=>'M',
4=>'A',
5=>'M',
6=>'J',
7=>'J',
8=>'A',
9=>'S',
10=>'O',
11=>'N',
12=>'D',
);
$this->assertEqual($monthNames,$Textual->monthNames('one'));
}
function testWeekdayNamesLong() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$weekdayNames = array(
0=>'Sunday',
1=>'Monday',
2=>'Tuesday',
3=>'Wednesday',
4=>'Thursday',
5=>'Friday',
6=>'Saturday',
);
$this->assertEqual($weekdayNames,$Textual->weekdayNames());
}
function testWeekdayNamesShort() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$weekdayNames = array(
0=>'Sun',
1=>'Mon',
2=>'Tue',
3=>'Wed',
4=>'Thu',
5=>'Fri',
6=>'Sat',
);
$this->assertEqual($weekdayNames,$Textual->weekdayNames('short'));
}
function testWeekdayNamesTwo() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$weekdayNames = array(
0=>'Su',
1=>'Mo',
2=>'Tu',
3=>'We',
4=>'Th',
5=>'Fr',
6=>'Sa',
);
$this->assertEqual($weekdayNames,$Textual->weekdayNames('two'));
}
function testWeekdayNamesOne() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$weekdayNames = array(
0=>'S',
1=>'M',
2=>'T',
3=>'W',
4=>'T',
5=>'F',
6=>'S',
);
$this->assertEqual($weekdayNames,$Textual->weekdayNames('one'));
}
function testPrevMonthNameShort() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$this->assertEqual('Sep',$Textual->prevMonthName('short'));
}
function testThisMonthNameShort() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$this->assertEqual('Oct',$Textual->thisMonthName('short'));
}
function testNextMonthNameShort() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$this->assertEqual('Nov',$Textual->nextMonthName('short'));
}
function testThisDayNameShort() {
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$this->assertEqual('Wed',$Textual->thisDayName('short'));
}
function testOrderedWeekdaysShort() {
$weekdayNames = array(
0=>'Sun',
1=>'Mon',
2=>'Tue',
3=>'Wed',
4=>'Thu',
5=>'Fri',
6=>'Sat',
);
$Textual = new Calendar_Decorator_Textual($this->mockcal);
$this->assertEqual($weekdayNames,$Textual->orderedWeekdays('short'));
}
 
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfDecoratorTextual();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/all_tests.php
New file
0,0 → 1,34
<?php
// $Id: all_tests.php,v 1.2 2004/08/16 08:55:24 hfuecks Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
define("TEST_RUNNING", true);
 
require_once('./calendar_tests.php');
require_once('./calendar_tabular_tests.php');
require_once('./validator_tests.php');
require_once('./calendar_engine_tests.php');
require_once('./calendar_engine_tests.php');
require_once('./table_helper_tests.php');
require_once('./decorator_tests.php');
require_once('./util_tests.php');
 
 
class AllTests extends GroupTest {
function AllTests() {
$this->GroupTest('All PEAR::Calendar Tests');
$this->AddTestCase(new CalendarTests());
$this->AddTestCase(new CalendarTabularTests());
$this->AddTestCase(new ValidatorTests());
$this->AddTestCase(new CalendarEngineTests());
$this->AddTestCase(new TableHelperTests());
$this->AddTestCase(new DecoratorTests());
$this->AddTestCase(new UtilTests());
}
}
 
$test = &new AllTests();
$test->run(new HtmlReporter());
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/simple_include.php
New file
0,0 → 1,10
<?php
// $Id: simple_include.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
if (!defined('SIMPLE_TEST')) {
define('SIMPLE_TEST', '../../../simpletest/');
}
 
require_once(SIMPLE_TEST . 'unit_tester.php');
require_once(SIMPLE_TEST . 'reporter.php');
require_once(SIMPLE_TEST . 'mock_objects.php');
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/validator_error_test.php
New file
0,0 → 1,34
<?php
// $Id: validator_error_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class TestOfValidationError extends UnitTestCase {
var $vError;
function TestOfValidationError() {
$this->UnitTestCase('Test of Validation Error');
}
function setUp() {
$this->vError = new Calendar_Validation_Error('foo',20,'bar');
}
function testGetUnit() {
$this->assertEqual($this->vError->getUnit(),'foo');
}
function testGetValue() {
$this->assertEqual($this->vError->getValue(),20);
}
function testGetMessage() {
$this->assertEqual($this->vError->getMessage(),'bar');
}
function testToString() {
$this->assertEqual($this->vError->toString(),'foo = 20 [bar]');
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfValidationError();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/year_test.php
New file
0,0 → 1,142
<?php
// $Id: year_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./calendar_test.php');
 
class TestOfYear extends TestOfCalendar {
function TestOfYear() {
$this->UnitTestCase('Test of Year');
}
function setUp() {
$this->cal = new Calendar_Year(2003);
}
function testPrevYear_Object() {
$this->assertEqual(new Calendar_Year(2002), $this->cal->prevYear('object'));
}
function testThisYear_Object() {
$this->assertEqual(new Calendar_Year(2003), $this->cal->thisYear('object'));
}
function testPrevMonth () {
$this->assertEqual(12,$this->cal->prevMonth());
}
function testPrevMonth_Array () {
$this->assertEqual(
array(
'year' => 2002,
'month' => 12,
'day' => 1,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevMonth('array'));
}
function testThisMonth () {
$this->assertEqual(1,$this->cal->thisMonth());
}
function testNextMonth () {
$this->assertEqual(2,$this->cal->nextMonth());
}
function testPrevDay () {
$this->assertEqual(31,$this->cal->prevDay());
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2002,
'month' => 12,
'day' => 31,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
function testThisDay () {
$this->assertEqual(1,$this->cal->thisDay());
}
function testNextDay () {
$this->assertEqual(2,$this->cal->nextDay());
}
function testPrevHour () {
$this->assertEqual(23,$this->cal->prevHour());
}
function testThisHour () {
$this->assertEqual(0,$this->cal->thisHour());
}
function testNextHour () {
$this->assertEqual(1,$this->cal->nextHour());
}
function testPrevMinute () {
$this->assertEqual(59,$this->cal->prevMinute());
}
function testThisMinute () {
$this->assertEqual(0,$this->cal->thisMinute());
}
function testNextMinute () {
$this->assertEqual(1,$this->cal->nextMinute());
}
function testPrevSecond () {
$this->assertEqual(59,$this->cal->prevSecond());
}
function testThisSecond () {
$this->assertEqual(0,$this->cal->thisSecond());
}
function testNextSecond () {
$this->assertEqual(1,$this->cal->nextSecond());
}
function testGetTimeStamp() {
$stamp = mktime(0,0,0,1,1,2003);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
}
 
class TestOfYearBuild extends TestOfYear {
function TestOfYearBuild() {
$this->UnitTestCase('Test of Year::build()');
}
function testSize() {
$this->cal->build();
$this->assertEqual(12,$this->cal->size());
}
function testFetch() {
$this->cal->build();
$i=0;
while ( $Child = $this->cal->fetch() ) {
$i++;
}
$this->assertEqual(12,$i);
}
function testFetchAll() {
$this->cal->build();
$children = array();
$i = 1;
while ( $Child = $this->cal->fetch() ) {
$children[$i]=$Child;
$i++;
}
$this->assertEqual($children,$this->cal->fetchAll());
}
function testSelection() {
require_once(CALENDAR_ROOT . 'Month.php');
$selection = array(new Calendar_Month(2003,10));
$this->cal->build($selection);
$i = 1;
while ( $Child = $this->cal->fetch() ) {
if ( $i == 10 )
break;
$i++;
}
$this->assertTrue($Child->isSelected());
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfYear();
$test->run(new HtmlReporter());
$test = &new TestOfYearBuild();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/decorator_tests.php
New file
0,0 → 1,21
<?php
// $Id: decorator_tests.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class DecoratorTests extends GroupTest {
function DecoratorTests() {
$this->GroupTest('Decorator Tests');
$this->addTestFile('decorator_test.php');
$this->addTestFile('decorator_textual_test.php');
$this->addTestFile('decorator_uri_test.php');
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new DecoratorTests();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/README
New file
0,0 → 1,7
These tests require Simple Test: http://www.lastcraft.com/simple_test.php
 
Ideally they would use PEAR::PHPUnit but the current version has bugs and
lacks alot of the functionality (e.g. Mock Objects) which Simple Test
provides.
 
Modifying the simple_include.php script for your simple test install dir
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/validator_tests.php
New file
0,0 → 1,20
<?php
// $Id: validator_tests.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class ValidatorTests extends GroupTest {
function ValidatorTests() {
$this->GroupTest('Validator Tests');
$this->addTestFile('validator_unit_test.php');
$this->addTestFile('validator_error_test.php');
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new ValidatorTests();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/table_helper_tests.php
New file
0,0 → 1,19
<?php
// $Id: table_helper_tests.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class TableHelperTests extends GroupTest {
function TableHelperTests() {
$this->GroupTest('Table Helper Tests');
$this->addTestFile('helper_test.php');
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TableHelperTests();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/hour_test.php
New file
0,0 → 1,98
<?php
// $Id: hour_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./calendar_test.php');
 
class TestOfHour extends TestOfCalendar {
function TestOfHour() {
$this->UnitTestCase('Test of Hour');
}
function setUp() {
$this->cal = new Calendar_Hour(2003,10,25,13);
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 10,
'day' => 24,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
function testPrevMinute () {
$this->assertEqual(59,$this->cal->prevMinute());
}
function testThisMinute () {
$this->assertEqual(0,$this->cal->thisMinute());
}
function testNextMinute () {
$this->assertEqual(1,$this->cal->nextMinute());
}
function testPrevSecond () {
$this->assertEqual(59,$this->cal->prevSecond());
}
function testThisSecond () {
$this->assertEqual(0,$this->cal->thisSecond());
}
function testNextSecond () {
$this->assertEqual(1,$this->cal->nextSecond());
}
function testGetTimeStamp() {
$stamp = mktime(13,0,0,10,25,2003);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
}
 
class TestOfHourBuild extends TestOfHour {
function TestOfHourBuild() {
$this->UnitTestCase('Test of Hour::build()');
}
function testSize() {
$this->cal->build();
$this->assertEqual(60,$this->cal->size());
}
function testFetch() {
$this->cal->build();
$i=0;
while ( $Child = $this->cal->fetch() ) {
$i++;
}
$this->assertEqual(60,$i);
}
function testFetchAll() {
$this->cal->build();
$children = array();
$i = 0;
while ( $Child = $this->cal->fetch() ) {
$children[$i]=$Child;
$i++;
}
$this->assertEqual($children,$this->cal->fetchAll());
}
function testSelection() {
require_once(CALENDAR_ROOT . 'Minute.php');
$selection = array(new Calendar_Minute(2003,10,25,13,32));
$this->cal->build($selection);
$i = 0;
while ( $Child = $this->cal->fetch() ) {
if ( $i == 32 )
break;
$i++;
}
$this->assertTrue($Child->isSelected());
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfHour();
$test->run(new HtmlReporter());
$test = &new TestOfHourBuild();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/helper_test.php
New file
0,0 → 1,83
<?php
// $Id: helper_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
Mock::generate('Calendar_Engine_Interface','Mock_Calendar_Engine');
Mock::generate('Calendar_Second','Mock_Calendar_Second');
 
class TestOfTableHelper extends UnitTestCase {
var $mockengine;
var $mockcal;
function TestOfTableHelper() {
$this->UnitTestCase('Test of Calendar_Table_Helper');
}
function setUp() {
$this->mockengine = new Mock_Calendar_Engine($this);
$this->mockengine->setReturnValue('getMinYears',1970);
$this->mockengine->setReturnValue('getMaxYears',2037);
$this->mockengine->setReturnValue('getMonthsInYear',12);
$this->mockengine->setReturnValue('getDaysInMonth',31);
$this->mockengine->setReturnValue('getHoursInDay',24);
$this->mockengine->setReturnValue('getMinutesInHour',60);
$this->mockengine->setReturnValue('getSecondsInMinute',60);
$this->mockengine->setReturnValue('getWeekDays',array(0,1,2,3,4,5,6));
$this->mockengine->setReturnValue('getDaysInWeek',7);
$this->mockengine->setReturnValue('getFirstDayOfWeek',1);
$this->mockengine->setReturnValue('getFirstDayInMonth',3);
$this->mockcal = new Mock_Calendar_Second($this);
$this->mockcal->setReturnValue('thisYear',2003);
$this->mockcal->setReturnValue('thisMonth',10);
$this->mockcal->setReturnValue('thisDay',15);
$this->mockcal->setReturnValue('thisHour',13);
$this->mockcal->setReturnValue('thisMinute',30);
$this->mockcal->setReturnValue('thisSecond',45);
$this->mockcal->setReturnValue('getEngine',$this->mockengine);
}
function testGetFirstDay() {
for ( $i = 0; $i <= 7; $i++ ) {
$Helper = & new Calendar_Table_Helper($this->mockcal,$i);
$this->assertEqual($Helper->getFirstDay(),$i);
}
}
function testGetDaysOfWeekMonday() {
$Helper = & new Calendar_Table_Helper($this->mockcal);
$this->assertEqual($Helper->getDaysOfWeek(),array(1,2,3,4,5,6,0));
}
function testGetDaysOfWeekSunday() {
$Helper = & new Calendar_Table_Helper($this->mockcal,0);
$this->assertEqual($Helper->getDaysOfWeek(),array(0,1,2,3,4,5,6));
}
function testGetDaysOfWeekThursday() {
$Helper = & new Calendar_Table_Helper($this->mockcal,4);
$this->assertEqual($Helper->getDaysOfWeek(),array(4,5,6,0,1,2,3));
}
function testGetNumWeeks() {
$Helper = & new Calendar_Table_Helper($this->mockcal);
$this->assertEqual($Helper->getNumWeeks(),5);
}
function testGetNumTableDaysInMonth() {
$Helper = & new Calendar_Table_Helper($this->mockcal);
$this->assertEqual($Helper->getNumTableDaysInMonth(),35);
}
function testGetEmptyDaysBefore() {
$Helper = & new Calendar_Table_Helper($this->mockcal);
$this->assertEqual($Helper->getEmptyDaysBefore(),2);
}
function testGetEmptyDaysAfter() {
$Helper = & new Calendar_Table_Helper($this->mockcal);
$this->assertEqual($Helper->getEmptyDaysAfter(),33);
}
function testGetEmptyDaysAfterOffset() {
$Helper = & new Calendar_Table_Helper($this->mockcal);
$this->assertEqual($Helper->getEmptyDaysAfterOffset(),5);
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfTableHelper();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/week_firstday_0_test.php
New file
0,0 → 1,241
<?php
// $Id: week_firstday_0_test.php,v 1.1 2005/10/20 18:57:52 quipo Exp $
define('CALENDAR_FIRST_DAY_OF_WEEK', 0); //force firstDay = Sunday
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./calendar_test.php');
 
class TestOfWeek_firstday_0 extends TestOfCalendar {
function TestOfWeek_firstday_0() {
$this->UnitTestCase('Test of Week - Week Starting on Sunday');
}
function setUp() {
$this->cal = Calendar_Factory::create('Week', 2003, 10, 9);
//print_r($this->cal);
}
function testPrevDay () {
$this->assertEqual(8, $this->cal->prevDay());
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 10,
'day' => 8,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
function testThisDay () {
$this->assertEqual(9, $this->cal->thisDay());
}
function testNextDay () {
$this->assertEqual(10, $this->cal->nextDay());
}
function testPrevHour () {
$this->assertEqual(23, $this->cal->prevHour());
}
function testThisHour () {
$this->assertEqual(0, $this->cal->thisHour());
}
function testNextHour () {
$this->assertEqual(1, $this->cal->nextHour());
}
function testPrevMinute () {
$this->assertEqual(59, $this->cal->prevMinute());
}
function testThisMinute () {
$this->assertEqual(0, $this->cal->thisMinute());
}
function testNextMinute () {
$this->assertEqual(1, $this->cal->nextMinute());
}
function testPrevSecond () {
$this->assertEqual(59, $this->cal->prevSecond());
}
function testThisSecond () {
$this->assertEqual(0, $this->cal->thisSecond());
}
function testNextSecond () {
$this->assertEqual(1, $this->cal->nextSecond());
}
function testGetTimeStamp() {
$stamp = mktime(0,0,0,10,9,2003);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
function testNewTimeStamp() {
$stamp = mktime(0,0,0,7,28,2004);
$this->cal->setTimestamp($stamp);
$this->assertEqual('29 2004', date('W Y', $this->cal->prevWeek(true)));
$this->assertEqual('30 2004', date('W Y', $this->cal->thisWeek(true)));
$this->assertEqual('31 2004', date('W Y', $this->cal->nextWeek(true)));
}
function testPrevWeekInMonth() {
$this->assertEqual(1, $this->cal->prevWeek());
$stamp = mktime(0,0,0,2,3,2005);
$this->cal->setTimestamp($stamp);
$this->assertEqual(0, $this->cal->prevWeek());
}
function testThisWeekInMonth() {
$this->assertEqual(2, $this->cal->thisWeek());
$stamp = mktime(0,0,0,2,3,2005);
$this->cal->setTimestamp($stamp);
$this->assertEqual(1, $this->cal->thisWeek());
$stamp = mktime(0,0,0,1,1,2005);
$this->cal->setTimestamp($stamp);
$this->assertEqual(1, $this->cal->thisWeek());
$stamp = mktime(0,0,0,1,3,2005);
$this->cal->setTimestamp($stamp);
$this->assertEqual(2, $this->cal->thisWeek());
}
function testNextWeekInMonth() {
$this->assertEqual(3, $this->cal->nextWeek());
$stamp = mktime(0,0,0,2,3,2005);
$this->cal->setTimestamp($stamp);
$this->assertEqual(2, $this->cal->nextWeek());
}
function testPrevWeekInYear() {
$this->assertEqual(date('W', $this->cal->prevWeek('timestamp')), $this->cal->prevWeek('n_in_year'));
$stamp = mktime(0,0,0,1,1,2004);
$this->cal->setTimestamp($stamp);
$this->assertEqual(date('W', $this->cal->nextWeek('timestamp')), $this->cal->nextWeek('n_in_year'));
}
function testThisWeekInYear() {
$this->assertEqual(date('W', $this->cal->thisWeek('timestamp')), $this->cal->thisWeek('n_in_year'));
$stamp = mktime(0,0,0,1,1,2004);
$this->cal->setTimestamp($stamp);
$this->assertEqual(date('W', $this->cal->thisWeek('timestamp')), $this->cal->thisWeek('n_in_year'));
}
function testFirstWeekInYear() {
$stamp = mktime(0,0,0,1,4,2004);
$this->cal->setTimestamp($stamp);
$this->assertEqual(1, $this->cal->thisWeek('n_in_year'));
}
function testNextWeekInYear() {
$this->assertEqual(date('W', $this->cal->nextWeek('timestamp')), $this->cal->nextWeek('n_in_year'));
}
function testPrevWeekArray() {
$testArray = array(
'year'=>2003,
'month'=>9,
'day'=>28,
'hour'=>0,
'minute'=>0,
'second'=>0
);
$this->assertEqual($testArray, $this->cal->prevWeek('array'));
}
function testThisWeekArray() {
$testArray = array(
'year'=>2003,
'month'=>10,
'day'=>5,
'hour'=>0,
'minute'=>0,
'second'=>0
);
$this->assertEqual($testArray, $this->cal->thisWeek('array'));
}
function testNextWeekArray() {
$testArray = array(
'year'=>2003,
'month'=>10,
'day'=>12,
'hour'=>0,
'minute'=>0,
'second'=>0
);
$this->assertEqual($testArray, $this->cal->nextWeek('array'));
}
function testPrevWeekObject() {
$testWeek = Calendar_Factory::create('Week', 2003,9,28);
$Week = $this->cal->prevWeek('object');
$this->assertEqual($testWeek->getTimeStamp(),$Week->getTimeStamp());
}
function testThisWeekObject() {
$testWeek = Calendar_Factory::create('Week', 2003,10,5);
$Week = $this->cal->thisWeek('object');
$this->assertEqual($testWeek->getTimeStamp(),$Week->getTimeStamp());
}
function testNextWeekObject() {
$testWeek = Calendar_Factory::create('Week', 2003,10,12);
$Week = $this->cal->nextWeek('object');
$this->assertEqual($testWeek->getTimeStamp(),$Week->getTimeStamp());
}
}
 
class TestOfWeek_firstday_0_Build extends TestOfWeek_firstday_0 {
function TestOfWeek_firstday_0_Build() {
$this->UnitTestCase('Test of Week::build() - FirstDay = Sunday');
}
function testSize() {
$this->cal->build();
$this->assertEqual(7, $this->cal->size());
}
 
function testFetch() {
$this->cal->build();
$i=0;
while ($Child = $this->cal->fetch()) {
$i++;
}
$this->assertEqual(7, $i);
}
function testFetchAll() {
$this->cal->build();
$children = array();
$i = 1;
while ( $Child = $this->cal->fetch() ) {
$children[$i]=$Child;
$i++;
}
$this->assertEqual($children,$this->cal->fetchAll());
}
 
function testSelection() {
require_once(CALENDAR_ROOT . 'Day.php');
$selection = array(Calendar_Factory::create('Day', 2003, 10, 6));
$this->cal->build($selection);
$i = 1;
while ($Child = $this->cal->fetch()) {
if ($i == 2) {
break; //06-10-2003 is the 2nd day of the week
}
$i++;
}
$this->assertTrue($Child->isSelected());
}
function testSelectionCornerCase() {
require_once(CALENDAR_ROOT . 'Day.php');
$selectedDays = array(
Calendar_Factory::create('Day', 2003, 12, 28),
Calendar_Factory::create('Day', 2003, 12, 29),
Calendar_Factory::create('Day', 2003, 12, 30),
Calendar_Factory::create('Day', 2003, 12, 31),
Calendar_Factory::create('Day', 2004, 01, 01),
Calendar_Factory::create('Day', 2004, 01, 02),
Calendar_Factory::create('Day', 2004, 01, 03)
);
$this->cal = Calendar_Factory::create('Week', 2003, 12, 31, 0);
$this->cal->build($selectedDays);
while ($Day = $this->cal->fetch()) {
$this->assertTrue($Day->isSelected());
}
$this->cal = Calendar_Factory::create('Week', 2004, 1, 1, 0);
$this->cal->build($selectedDays);
while ($Day = $this->cal->fetch()) {
$this->assertTrue($Day->isSelected());
}
}
}
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfWeek_firstday_0();
$test->run(new HtmlReporter());
$test = &new TestOfWeek_firstday_0_Build();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/month_weekdays_test.php
New file
0,0 → 1,130
<?php
// $Id: month_weekdays_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./calendar_test.php');
 
class TestOfMonthWeekdays extends TestOfCalendar {
function TestOfMonthWeekdays() {
$this->UnitTestCase('Test of Month Weekdays');
}
function setUp() {
$this->cal = new Calendar_Month_Weekdays(2003,10);
}
function testPrevDay () {
$this->assertEqual(30,$this->cal->prevDay());
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 9,
'day' => 30,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
function testThisDay () {
$this->assertEqual(1,$this->cal->thisDay());
}
function testNextDay () {
$this->assertEqual(2,$this->cal->nextDay());
}
function testPrevHour () {
$this->assertEqual(23,$this->cal->prevHour());
}
function testThisHour () {
$this->assertEqual(0,$this->cal->thisHour());
}
function testNextHour () {
$this->assertEqual(1,$this->cal->nextHour());
}
function testPrevMinute () {
$this->assertEqual(59,$this->cal->prevMinute());
}
function testThisMinute () {
$this->assertEqual(0,$this->cal->thisMinute());
}
function testNextMinute () {
$this->assertEqual(1,$this->cal->nextMinute());
}
function testPrevSecond () {
$this->assertEqual(59,$this->cal->prevSecond());
}
function testThisSecond () {
$this->assertEqual(0,$this->cal->thisSecond());
}
function testNextSecond () {
$this->assertEqual(1,$this->cal->nextSecond());
}
function testGetTimeStamp() {
$stamp = mktime(0,0,0,10,1,2003);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
}
 
class TestOfMonthWeekdaysBuild extends TestOfMonthWeekdays {
function TestOfMonthWeekdaysBuild() {
$this->UnitTestCase('Test of Month_Weekdays::build()');
}
function testSize() {
$this->cal->build();
$this->assertEqual(35,$this->cal->size());
}
function testFetch() {
$this->cal->build();
$i=0;
while ( $Child = $this->cal->fetch() ) {
$i++;
}
$this->assertEqual(35,$i);
}
function testFetchAll() {
$this->cal->build();
$children = array();
$i = 1;
while ( $Child = $this->cal->fetch() ) {
$children[$i]=$Child;
$i++;
}
$this->assertEqual($children,$this->cal->fetchAll());
}
function testSelection() {
require_once(CALENDAR_ROOT . 'Day.php');
$selection = array(new Calendar_Day(2003,10,25));
$this->cal->build($selection);
$i = 1;
while ( $Child = $this->cal->fetch() ) {
if ( $i == 27 )
break;
$i++;
}
$this->assertTrue($Child->isSelected());
}
function testEmptyCount() {
$this->cal->build();
$empty = 0;
while ( $Child = $this->cal->fetch() ) {
if ( $Child->isEmpty() )
$empty++;
}
$this->assertEqual(4,$empty);
}
function testEmptyDaysBefore_AfterAdjust() {
$this->cal = new Calendar_Month_Weekdays(2004,0);
$this->cal->build();
$this->assertEqual(0,$this->cal->tableHelper->getEmptyDaysBefore());
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfMonthWeekdays();
$test->run(new HtmlReporter());
$test = &new TestOfMonthWeekdaysBuild();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/calendar_engine_tests.php
New file
0,0 → 1,20
<?php
// $Id: calendar_engine_tests.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
class CalendarEngineTests extends GroupTest {
function CalendarEngineTests() {
$this->GroupTest('Calendar Engine Tests');
$this->addTestFile('peardate_engine_test.php');
$this->addTestFile('unixts_engine_test.php');
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new CalendarEngineTests();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/tests/month_test.php
New file
0,0 → 1,119
<?php
// $Id: month_test.php,v 1.1 2004/05/24 22:25:43 quipo Exp $
 
require_once('simple_include.php');
require_once('calendar_include.php');
 
require_once('./calendar_test.php');
 
class TestOfMonth extends TestOfCalendar {
function TestOfMonth() {
$this->UnitTestCase('Test of Month');
}
function setUp() {
$this->cal = new Calendar_Month(2003,10);
}
function testPrevMonth_Object() {
$this->assertEqual(new Calendar_Month(2003, 9), $this->cal->prevMonth('object'));
}
function testPrevDay () {
$this->assertEqual(30,$this->cal->prevDay());
}
function testPrevDay_Array () {
$this->assertEqual(
array(
'year' => 2003,
'month' => 9,
'day' => 30,
'hour' => 0,
'minute' => 0,
'second' => 0),
$this->cal->prevDay('array'));
}
function testThisDay () {
$this->assertEqual(1,$this->cal->thisDay());
}
function testNextDay () {
$this->assertEqual(2,$this->cal->nextDay());
}
function testPrevHour () {
$this->assertEqual(23,$this->cal->prevHour());
}
function testThisHour () {
$this->assertEqual(0,$this->cal->thisHour());
}
function testNextHour () {
$this->assertEqual(1,$this->cal->nextHour());
}
function testPrevMinute () {
$this->assertEqual(59,$this->cal->prevMinute());
}
function testThisMinute () {
$this->assertEqual(0,$this->cal->thisMinute());
}
function testNextMinute () {
$this->assertEqual(1,$this->cal->nextMinute());
}
function testPrevSecond () {
$this->assertEqual(59,$this->cal->prevSecond());
}
function testThisSecond () {
$this->assertEqual(0,$this->cal->thisSecond());
}
function testNextSecond () {
$this->assertEqual(1,$this->cal->nextSecond());
}
function testGetTimeStamp() {
$stamp = mktime(0,0,0,10,1,2003);
$this->assertEqual($stamp,$this->cal->getTimeStamp());
}
}
 
class TestOfMonthBuild extends TestOfMonth {
function TestOfMonthBuild() {
$this->UnitTestCase('Test of Month::build()');
}
function testSize() {
$this->cal->build();
$this->assertEqual(31,$this->cal->size());
}
function testFetch() {
$this->cal->build();
$i=0;
while ( $Child = $this->cal->fetch() ) {
$i++;
}
$this->assertEqual(31,$i);
}
function testFetchAll() {
$this->cal->build();
$children = array();
$i = 1;
while ( $Child = $this->cal->fetch() ) {
$children[$i]=$Child;
$i++;
}
$this->assertEqual($children,$this->cal->fetchAll());
}
function testSelection() {
require_once(CALENDAR_ROOT . 'Day.php');
$selection = array(new Calendar_Day(2003,10,25));
$this->cal->build($selection);
$i = 1;
while ( $Child = $this->cal->fetch() ) {
if ( $i == 25 )
break;
$i++;
}
$this->assertTrue($Child->isSelected());
}
}
 
if (!defined('TEST_RUNNING')) {
define('TEST_RUNNING', true);
$test = &new TestOfMonth();
$test->run(new HtmlReporter());
$test = &new TestOfMonthBuild();
$test->run(new HtmlReporter());
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Day.php
New file
0,0 → 1,197
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Day.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Day.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar base class
*/
require_once CALENDAR_ROOT.'Calendar.php';
 
/**
* Represents a Day and builds Hours.
* <code>
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Day.php';
* $Day = & new Calendar_Day(2003, 10, 21); // Oct 21st 2003
* while ($Hour = & $Day->fetch()) {
* echo $Hour->thisHour().'<br />';
* }
* </code>
* @package Calendar
* @access public
*/
class Calendar_Day extends Calendar
{
/**
* Marks the Day at the beginning of a week
* @access private
* @var boolean
*/
var $first = false;
 
/**
* Marks the Day at the end of a week
* @access private
* @var boolean
*/
var $last = false;
 
 
/**
* Used for tabular calendars
* @access private
* @var boolean
*/
var $empty = false;
 
/**
* Constructs Calendar_Day
* @param int year e.g. 2003
* @param int month e.g. 8
* @param int day e.g. 15
* @access public
*/
function Calendar_Day($y, $m, $d)
{
Calendar::Calendar($y, $m, $d);
}
 
/**
* Builds the Hours of the Day
* @param array (optional) Caledar_Hour objects representing selected dates
* @return boolean
* @access public
*/
function build($sDates = array())
{
require_once CALENDAR_ROOT.'Hour.php';
 
$hID = $this->cE->getHoursInDay($this->year, $this->month, $this->day);
for ($i=0; $i < $hID; $i++) {
$this->children[$i]=
new Calendar_Hour($this->year, $this->month, $this->day, $i);
}
if (count($sDates) > 0) {
$this->setSelection($sDates);
}
return true;
}
 
/**
* Called from build()
* @param array
* @return void
* @access private
*/
function setSelection($sDates)
{
foreach ($sDates as $sDate) {
if ($this->year == $sDate->thisYear()
&& $this->month == $sDate->thisMonth()
&& $this->day == $sDate->thisDay())
{
$key = (int)$sDate->thisHour();
if (isset($this->children[$key])) {
$sDate->setSelected();
$this->children[$key] = $sDate;
}
}
}
}
 
/**
* Defines Day object as first in a week
* Only used by Calendar_Month_Weekdays::build()
* @param boolean state
* @return void
* @access private
*/
function setFirst ($state = true)
{
$this->first = $state;
}
 
/**
* Defines Day object as last in a week
* Used only following Calendar_Month_Weekdays::build()
* @param boolean state
* @return void
* @access private
*/
function setLast($state = true)
{
$this->last = $state;
}
 
/**
* Returns true if Day object is first in a Week
* Only relevant when Day is created by Calendar_Month_Weekdays::build()
* @return boolean
* @access public
*/
function isFirst() {
return $this->first;
}
 
/**
* Returns true if Day object is last in a Week
* Only relevant when Day is created by Calendar_Month_Weekdays::build()
* @return boolean
* @access public
*/
function isLast()
{
return $this->last;
}
 
/**
* Defines Day object as empty
* Only used by Calendar_Month_Weekdays::build()
* @param boolean state
* @return void
* @access private
*/
function setEmpty ($state = true)
{
$this->empty = $state;
}
 
/**
* @return boolean
* @access public
*/
function isEmpty()
{
return $this->empty;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Hour.php
New file
0,0 → 1,113
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Hour.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
//
/**
* @package Calendar
* @version $Id: Hour.php,v 1.1 2004/05/24 22:25:42 quipo Exp $
*/
 
/**
* Allows Calendar include path to be redefined
* @ignore
*/
if (!defined('CALENDAR_ROOT')) {
define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR);
}
 
/**
* Load Calendar base class
*/
require_once CALENDAR_ROOT.'Calendar.php';
 
/**
* Represents an Hour and builds Minutes
* <code>
* require_once 'Calendar'.DIRECTORY_SEPARATOR.'Hour.php';
* $Hour = & new Calendar_Hour(2003, 10, 21, 15); // Oct 21st 2003, 3pm
* $Hour->build(); // Build Calendar_Minute objects
* while ($Minute = & $Hour->fetch()) {
* echo $Minute->thisMinute().'<br />';
* }
* </code>
* @package Calendar
* @access public
*/
class Calendar_Hour extends Calendar
{
/**
* Constructs Calendar_Hour
* @param int year e.g. 2003
* @param int month e.g. 5
* @param int day e.g. 11
* @param int hour e.g. 13
* @access public
*/
function Calendar_Hour($y, $m, $d, $h)
{
Calendar::Calendar($y, $m, $d, $h);
}
 
/**
* Builds the Minutes in the Hour
* @param array (optional) Calendar_Minute objects representing selected dates
* @return boolean
* @access public
*/
function build($sDates=array())
{
require_once CALENDAR_ROOT.'Minute.php';
$mIH = $this->cE->getMinutesInHour($this->year, $this->month, $this->day,
$this->hour);
for ($i=0; $i < $mIH; $i++) {
$this->children[$i]=
new Calendar_Minute($this->year, $this->month, $this->day,
$this->hour, $i);
}
if (count($sDates) > 0) {
$this->setSelection($sDates);
}
return true;
}
 
/**
* Called from build()
* @param array
* @return void
* @access private
*/
function setSelection($sDates)
{
foreach ($sDates as $sDate) {
if ($this->year == $sDate->thisYear()
&& $this->month == $sDate->thisMonth()
&& $this->day == $sDate->thisDay()
&& $this->hour == $sDate->thisHour())
{
$key = (int)$sDate->thisMinute();
if (isset($this->children[$key])) {
$sDate->setSelected();
$this->children[$key] = $sDate;
}
}
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Engine/Interface.php
New file
0,0 → 1,293
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: Interface.php,v 1.5 2004/08/16 12:29:18 hfuecks Exp $
//
/**
* @package Calendar
* @version $Id: Interface.php,v 1.5 2004/08/16 12:29:18 hfuecks Exp $
*/
/**
* The methods the classes implementing the Calendar_Engine must implement.
* Note this class is not used but simply to help development
* @package Calendar
* @access protected
*/
class Calendar_Engine_Interface
{
/**
* Provides a mechansim to make sure parsing of timestamps
* into human dates is only performed once per timestamp.
* Typically called "internally" by methods like stampToYear.
* Return value can vary, depending on the specific implementation
* @param int timestamp (depending on implementation)
* @return mixed
* @access protected
*/
function stampCollection($stamp)
{
}
 
/**
* Returns a numeric year given a timestamp
* @param int timestamp (depending on implementation)
* @return int year (e.g. 2003)
* @access protected
*/
function stampToYear($stamp)
{
}
 
/**
* Returns a numeric month given a timestamp
* @param int timestamp (depending on implementation)
* @return int month (e.g. 9)
* @access protected
*/
function stampToMonth($stamp)
{
}
 
/**
* Returns a numeric day given a timestamp
* @param int timestamp (depending on implementation)
* @return int day (e.g. 15)
* @access protected
*/
function stampToDay($stamp)
{
}
 
/**
* Returns a numeric hour given a timestamp
* @param int timestamp (depending on implementation)
* @return int hour (e.g. 13)
* @access protected
*/
function stampToHour($stamp)
{
}
 
/**
* Returns a numeric minute given a timestamp
* @param int timestamp (depending on implementation)
* @return int minute (e.g. 34)
* @access protected
*/
function stampToMinute($stamp)
{
}
 
/**
* Returns a numeric second given a timestamp
* @param int timestamp (depending on implementation)
* @return int second (e.g. 51)
* @access protected
*/
function stampToSecond($stamp)
{
}
 
/**
* Returns a timestamp. Can be worth "caching" generated
* timestamps in a static variable, identified by the
* params this method accepts, to timestamp will only
* be calculated once.
* @param int year (e.g. 2003)
* @param int month (e.g. 9)
* @param int day (e.g. 13)
* @param int hour (e.g. 13)
* @param int minute (e.g. 34)
* @param int second (e.g. 53)
* @return int (depends on implementation)
* @access protected
*/
function dateToStamp($y,$m,$d,$h,$i,$s)
{
}
 
/**
* The upper limit on years that the Calendar Engine can work with
* @return int (e.g. 2037)
* @access protected
*/
function getMaxYears()
{
}
 
/**
* The lower limit on years that the Calendar Engine can work with
* @return int (e.g 1902)
* @access protected
*/
function getMinYears()
{
}
 
/**
* Returns the number of months in a year
* @param int (optional) year to get months for
* @return int (e.g. 12)
* @access protected
*/
function getMonthsInYear($y=null)
{
}
 
/**
* Returns the number of days in a month, given year and month
* @param int year (e.g. 2003)
* @param int month (e.g. 9)
* @return int days in month
* @access protected
*/
function getDaysInMonth($y, $m)
{
}
 
/**
* Returns numeric representation of the day of the week in a month,
* given year and month
* @param int year (e.g. 2003)
* @param int month (e.g. 9)
* @return int
* @access protected
*/
function getFirstDayInMonth ($y, $m)
{
}
 
/**
* Returns the number of days in a week
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int (e.g. 7)
* @access protected
*/
function getDaysInWeek($y=NULL, $m=NULL, $d=NULL)
{
}
 
/**
* Returns the number of the week in the year (ISO-8601), given a date
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int week number
* @access protected
*/
function getWeekNInYear($y, $m, $d)
{
}
 
/**
* Returns the number of the week in the month, given a date
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @param int first day of the week (default: 1 - monday)
* @return int week number
* @access protected
*/
function getWeekNInMonth($y, $m, $d, $firstDay=1)
{
}
 
/**
* Returns the number of weeks in the month
* @param int year (2003)
* @param int month (9)
* @param int first day of the week (default: 1 - monday)
* @return int weeks number
* @access protected
*/
function getWeeksInMonth($y, $m)
{
}
 
/**
* Returns the number of the day of the week (0=sunday, 1=monday...)
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int weekday number
* @access protected
*/
function getDayOfWeek($y, $m, $d)
{
}
 
/**
* Returns the numeric values of the days of the week.
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return array list of numeric values of days in week, beginning 0
* @access protected
*/
function getWeekDays($y=NULL, $m=NULL, $d=NULL)
{
}
 
/**
* Returns the default first day of the week as an integer. Must be a
* member of the array returned from getWeekDays
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int (e.g. 1 for Monday)
* @see getWeekDays
* @access protected
*/
function getFirstDayOfWeek($y=NULL, $m=NULL, $d=NULL)
{
}
 
/**
* Returns the number of hours in a day<br>
* @param int (optional) day to get hours for
* @return int (e.g. 24)
* @access protected
*/
function getHoursInDay($y=null,$m=null,$d=null)
{
}
 
/**
* Returns the number of minutes in an hour
* @param int (optional) hour to get minutes for
* @return int
* @access protected
*/
function getMinutesInHour($y=null,$m=null,$d=null,$h=null)
{
}
 
/**
* Returns the number of seconds in a minutes
* @param int (optional) minute to get seconds for
* @return int
* @access protected
*/
function getSecondsInMinute($y=null,$m=null,$d=null,$h=null,$i=null)
{
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Engine/PearDate.php
New file
0,0 → 1,407
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Lorenzo Alberton <l dot alberton at quipo dot it> |
// +----------------------------------------------------------------------+
//
// $Id: PearDate.php,v 1.8 2004/08/20 20:00:55 quipo Exp $
//
/**
* @package Calendar
* @version $Id: PearDate.php,v 1.8 2004/08/20 20:00:55 quipo Exp $
*/
/**
* Load PEAR::Date class
*/
require_once 'Date.php';
 
/**
* Performs calendar calculations based on the PEAR::Date class
* Timestamps are in the ISO-8601 format (YYYY-MM-DD HH:MM:SS)
* @package Calendar
* @access protected
*/
class Calendar_Engine_PearDate /* implements Calendar_Engine_Interface */
{
/**
* Makes sure a given timestamp is only ever parsed once
* Uses a static variable to prevent date() being used twice
* for a date which is already known
* @param mixed Any timestamp format recognized by Pear::Date
* @return object Pear::Date object
* @access protected
*/
function stampCollection($stamp)
{
static $stamps = array();
if (!isset($stamps[$stamp])) {
$stamps[$stamp] = new Date($stamp);
}
return $stamps[$stamp];
}
 
/**
* Returns a numeric year given a iso-8601 datetime
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
* @return int year (e.g. 2003)
* @access protected
*/
function stampToYear($stamp)
{
$date = Calendar_Engine_PearDate::stampCollection($stamp);
return (int)$date->year;
}
 
/**
* Returns a numeric month given a iso-8601 datetime
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
* @return int month (e.g. 9)
* @access protected
*/
function stampToMonth($stamp)
{
$date = Calendar_Engine_PearDate::stampCollection($stamp);
return (int)$date->month;
}
 
/**
* Returns a numeric day given a iso-8601 datetime
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
* @return int day (e.g. 15)
* @access protected
*/
function stampToDay($stamp)
{
$date = Calendar_Engine_PearDate::stampCollection($stamp);
return (int)$date->day;
}
 
/**
* Returns a numeric hour given a iso-8601 datetime
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
* @return int hour (e.g. 13)
* @access protected
*/
function stampToHour($stamp)
{
$date = Calendar_Engine_PearDate::stampCollection($stamp);
return (int)$date->hour;
}
 
/**
* Returns a numeric minute given a iso-8601 datetime
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
* @return int minute (e.g. 34)
* @access protected
*/
function stampToMinute($stamp)
{
$date = Calendar_Engine_PearDate::stampCollection($stamp);
return (int)$date->minute;
}
 
/**
* Returns a numeric second given a iso-8601 datetime
* @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
* @return int second (e.g. 51)
* @access protected
*/
function stampToSecond($stamp)
{
$date = Calendar_Engine_PearDate::stampCollection($stamp);
return (int)$date->second;
}
 
/**
* Returns a iso-8601 datetime
* @param int year (2003)
* @param int month (9)
* @param int day (13)
* @param int hour (13)
* @param int minute (34)
* @param int second (53)
* @return string iso-8601 datetime
* @access protected
*/
function dateToStamp($y, $m, $d, $h=0, $i=0, $s=0)
{
$r = array();
Calendar_Engine_PearDate::adjustDate($y, $m, $d, $h, $i, $s);
$key = $y.$m.$d.$h.$i.$s;
if (!isset($r[$key])) {
$r[$key] = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
$y, $m, $d, $h, $i, $s);
}
return $r[$key];
}
 
/**
* Set the correct date values (useful for math operations on dates)
* @param int year (2003)
* @param int month (9)
* @param int day (13)
* @param int hour (13)
* @param int minute (34)
* @param int second (53)
* @access protected
*/
function adjustDate(&$y, &$m, &$d, &$h, &$i, &$s)
{
if ($s < 0) {
$m -= floor($s / 60);
$s = -$s % 60;
}
if ($s > 60) {
$m += floor($s / 60);
$s %= 60;
}
if ($i < 0) {
$h -= floor($i / 60);
$i = -$i % 60;
}
if ($i > 60) {
$h += floor($i / 60);
$i %= 60;
}
if ($h < 0) {
$d -= floor($h / 24);
$h = -$h % 24;
}
if ($h > 24) {
$d += floor($h / 24);
$h %= 24;
}
for(; $m < 1; $y--, $m+=12);
for(; $m > 12; $y++, $m-=12);
 
while ($d < 1) {
if ($m > 1) {
$m--;
} else {
$m = 12;
$y--;
}
$d += Date_Calc::daysInMonth($m, $y);
}
for ($max_days = Date_Calc::daysInMonth($m, $y); $d > $max_days; ) {
$d -= $max_days;
if ($m < 12) {
$m++;
} else {
$m = 1;
$y++;
}
}
}
 
/**
* The upper limit on years that the Calendar Engine can work with
* @return int 9999
* @access protected
*/
function getMaxYears()
{
return 9999;
}
 
/**
* The lower limit on years that the Calendar Engine can work with
* @return int 0
* @access protected
*/
function getMinYears()
{
return 0;
}
 
/**
* Returns the number of months in a year
* @return int (12)
* @access protected
*/
function getMonthsInYear($y=null)
{
return 12;
}
 
/**
* Returns the number of days in a month, given year and month
* @param int year (2003)
* @param int month (9)
* @return int days in month
* @access protected
*/
function getDaysInMonth($y, $m)
{
return (int)Date_Calc::daysInMonth($m, $y);
}
 
/**
* Returns numeric representation of the day of the week in a month,
* given year and month
* @param int year (2003)
* @param int month (9)
* @return int from 0 to 7
* @access protected
*/
function getFirstDayInMonth($y, $m)
{
return (int)Date_Calc::dayOfWeek(1, $m, $y);
}
 
/**
* Returns the number of days in a week
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int (7)
* @access protected
*/
function getDaysInWeek($y=NULL, $m=NULL, $d=NULL)
{
return 7;
}
 
/**
* Returns the number of the week in the year (ISO-8601), given a date
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int week number
* @access protected
*/
function getWeekNInYear($y, $m, $d)
{
return Date_Calc::weekOfYear($d, $m, $y); //beware, Date_Calc doesn't follow ISO-8601 standard!
}
 
/**
* Returns the number of the week in the month, given a date
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @param int first day of the week (default: monday)
* @return int week number
* @access protected
*/
function getWeekNInMonth($y, $m, $d, $firstDay=1)
{
$weekEnd = ($firstDay == 0) ? $this->getDaysInWeek()-1 : $firstDay-1;
$end_of_week = (int)Date_Calc::nextDayOfWeek($weekEnd, 1, $m, $y, '%e', true);
$w = 1;
while ($d > $end_of_week) {
++$w;
$end_of_week += $this->getDaysInWeek();
}
return $w;
}
 
/**
* Returns the number of weeks in the month
* @param int year (2003)
* @param int month (9)
* @param int first day of the week (default: monday)
* @return int weeks number
* @access protected
*/
function getWeeksInMonth($y, $m, $firstDay=1)
{
$FDOM = Date_Calc::firstOfMonthWeekday($m, $y);
if ($FDOM == 0) {
$FDOM = $this->getDaysInWeek();
}
if ($FDOM > $firstDay) {
$daysInTheFirstWeek = $this->getDaysInWeek() - $FDOM + $firstDay;
$weeks = 1;
} else {
$daysInTheFirstWeek = $firstDay - $FDOM;
$weeks = 0;
}
$daysInTheFirstWeek %= $this->getDaysInWeek();
return (int)(ceil(($this->getDaysInMonth($y, $m) - $daysInTheFirstWeek) /
$this->getDaysInWeek()) + $weeks);
}
 
/**
* Returns the number of the day of the week (0=sunday, 1=monday...)
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int weekday number
* @access protected
*/
function getDayOfWeek($y, $m, $d)
{
return Date_Calc::dayOfWeek($d, $m, $y);
}
 
/**
* Returns a list of integer days of the week beginning 0
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return array (0, 1, 2, 3, 4, 5, 6) 1 = Monday
* @access protected
*/
function getWeekDays($y=NULL, $m=NULL, $d=NULL)
{
return array(0, 1, 2, 3, 4, 5, 6);
}
 
/**
* Returns the default first day of the week
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int (default 1 = Monday)
* @access protected
*/
function getFirstDayOfWeek($y=NULL, $m=NULL, $d=NULL)
{
return 1;
}
 
/**
* Returns the number of hours in a day
* @return int (24)
* @access protected
*/
function getHoursInDay($y=null,$m=null,$d=null)
{
return 24;
}
 
/**
* Returns the number of minutes in an hour
* @return int (60)
* @access protected
*/
function getMinutesInHour($y=null,$m=null,$d=null,$h=null)
{
return 60;
}
 
/**
* Returns the number of seconds in a minutes
* @return int (60)
* @access protected
*/
function getSecondsInMinute($y=null,$m=null,$d=null,$h=null,$i=null)
{
return 60;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/Calendar/Engine/UnixTS.php
New file
0,0 → 1,365
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Harry Fuecks <hfuecks@phppatterns.com> |
// +----------------------------------------------------------------------+
//
// $Id: UnixTS.php,v 1.9 2004/08/20 20:00:55 quipo Exp $
//
/**
* @package Calendar
* @version $Id: UnixTS.php,v 1.9 2004/08/20 20:00:55 quipo Exp $
*/
/**
* Performs calendar calculations based on the PHP date() function and
* Unix timestamps (using PHP's mktime() function).
* @package Calendar
* @access protected
*/
class Calendar_Engine_UnixTS /* implements Calendar_Engine_Interface */
{
/**
* Makes sure a given timestamp is only ever parsed once
* <pre>
* array (
* [0] => year (e.g 2003),
* [1] => month (e.g 9),
* [2] => day (e.g 6),
* [3] => hour (e.g 14),
* [4] => minute (e.g 34),
* [5] => second (e.g 45),
* [6] => num days in month (e.g. 31),
* [7] => week in year (e.g. 50),
* [8] => day in week (e.g. 0 for Sunday)
* )
* </pre>
* Uses a static variable to prevent date() being used twice
* for a date which is already known
* @param int Unix timestamp
* @return array
* @access protected
*/
function stampCollection($stamp)
{
static $stamps = array();
if ( !isset($stamps[$stamp]) ) {
$date = @date('Y n j H i s t W w',$stamp);
$stamps[$stamp] = sscanf($date, "%d %d %d %d %d %d %d %d %d");
}
return $stamps[$stamp];
}
 
/**
* Returns a numeric year given a timestamp
* @param int Unix timestamp
* @return int year (e.g. 2003)
* @access protected
*/
function stampToYear($stamp)
{
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
return (int)$date[0];
}
 
/**
* Returns a numeric month given a timestamp
* @param int Unix timestamp
* @return int month (e.g. 9)
* @access protected
*/
function stampToMonth($stamp)
{
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
return (int)$date[1];
}
 
/**
* Returns a numeric day given a timestamp
* @param int Unix timestamp
* @return int day (e.g. 15)
* @access protected
*/
function stampToDay($stamp)
{
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
return (int)$date[2];
}
 
/**
* Returns a numeric hour given a timestamp
* @param int Unix timestamp
* @return int hour (e.g. 13)
* @access protected
*/
function stampToHour($stamp)
{
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
return (int)$date[3];
}
 
/**
* Returns a numeric minute given a timestamp
* @param int Unix timestamp
* @return int minute (e.g. 34)
* @access protected
*/
function stampToMinute($stamp)
{
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
return (int)$date[4];
}
 
/**
* Returns a numeric second given a timestamp
* @param int Unix timestamp
* @return int second (e.g. 51)
* @access protected
*/
function stampToSecond($stamp)
{
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
return (int)$date[5];
}
 
/**
* Returns a timestamp
* @param int year (2003)
* @param int month (9)
* @param int day (13)
* @param int hour (13)
* @param int minute (34)
* @param int second (53)
* @return int Unix timestamp
* @access protected
*/
function dateToStamp($y, $m, $d, $h=0, $i=0, $s=0)
{
static $dates = array();
if ( !isset($dates[$y][$m][$d][$h][$i][$s]) ) {
$dates[$y][$m][$d][$h][$i][$s] = @mktime($h, $i, $s, $m, $d, $y);
}
return $dates[$y][$m][$d][$h][$i][$s];
}
 
/**
* The upper limit on years that the Calendar Engine can work with
* @return int (2037)
* @access protected
*/
function getMaxYears()
{
return 2037;
}
 
/**
* The lower limit on years that the Calendar Engine can work with
* @return int (1970 if it's Windows and 1902 for all other OSs)
* @access protected
*/
function getMinYears()
{
return $min = strpos(PHP_OS, 'WIN') === false ? 1902 : 1970;
}
 
/**
* Returns the number of months in a year
* @return int (12)
* @access protected
*/
function getMonthsInYear($y=null)
{
return 12;
}
 
/**
* Returns the number of days in a month, given year and month
* @param int year (2003)
* @param int month (9)
* @return int days in month
* @access protected
*/
function getDaysInMonth($y, $m)
{
$stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,1);
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
return $date[6];
}
 
/**
* Returns numeric representation of the day of the week in a month,
* given year and month
* @param int year (2003)
* @param int month (9)
* @return int from 0 to 6
* @access protected
*/
function getFirstDayInMonth($y, $m)
{
$stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,1);
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
return $date[8];
}
 
/**
* Returns the number of days in a week
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int (7)
* @access protected
*/
function getDaysInWeek($y=NULL, $m=NULL, $d=NULL)
{
return 7;
}
 
/**
* Returns the number of the week in the year (ISO-8601), given a date
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int week number
* @access protected
*/
function getWeekNInYear($y, $m, $d)
{
$stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,$d);
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
return $date[7];
}
 
/**
* Returns the number of the week in the month, given a date
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @param int first day of the week (default: monday)
* @return int week number
* @access protected
*/
function getWeekNInMonth($y, $m, $d, $firstDay=1)
{
$weekEnd = ($firstDay == 0) ? $this->getDaysInWeek()-1 : $firstDay-1;
$end_of_week = 1;
while (@date('w', @mktime(0, 0, 0, $m, $end_of_week, $y)) != $weekEnd) {
++$end_of_week; //find first weekend of the month
}
$w = 1;
while ($d > $end_of_week) {
++$w;
$end_of_week += $this->getDaysInWeek();
}
return $w;
}
 
/**
* Returns the number of weeks in the month
* @param int year (2003)
* @param int month (9)
* @param int first day of the week (default: monday)
* @return int weeks number
* @access protected
*/
function getWeeksInMonth($y, $m, $firstDay=1)
{
$FDOM = $this->getFirstDayInMonth($y, $m);
if ($FDOM == 0) {
$FDOM = $this->getDaysInWeek();
}
if ($FDOM > $firstDay) {
$daysInTheFirstWeek = $this->getDaysInWeek() - $FDOM + $firstDay;
$weeks = 1;
} else {
$daysInTheFirstWeek = $firstDay - $FDOM;
$weeks = 0;
}
$daysInTheFirstWeek %= $this->getDaysInWeek();
return (int)(ceil(($this->getDaysInMonth($y, $m) - $daysInTheFirstWeek) /
$this->getDaysInWeek()) + $weeks);
}
 
/**
* Returns the number of the day of the week (0=sunday, 1=monday...)
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int weekday number
* @access protected
*/
function getDayOfWeek($y, $m, $d)
{
$stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,$d);
$date = Calendar_Engine_UnixTS::stampCollection($stamp);
return $date[8];
}
 
/**
* Returns a list of integer days of the week beginning 0
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return array (0,1,2,3,4,5,6) 1 = Monday
* @access protected
*/
function getWeekDays($y=NULL, $m=NULL, $d=NULL)
{
return array(0, 1, 2, 3, 4, 5, 6);
}
 
/**
* Returns the default first day of the week
* @param int year (2003)
* @param int month (9)
* @param int day (4)
* @return int (default 1 = Monday)
* @access protected
*/
function getFirstDayOfWeek($y=NULL, $m=NULL, $d=NULL)
{
return 1;
}
 
/**
* Returns the number of hours in a day
* @return int (24)
* @access protected
*/
function getHoursInDay($y=null,$m=null,$d=null)
{
return 24;
}
 
/**
* Returns the number of minutes in an hour
* @return int (60)
* @access protected
*/
function getMinutesInHour($y=null,$m=null,$d=null,$h=null)
{
return 60;
}
 
/**
* Returns the number of seconds in a minutes
* @return int (60)
* @access protected
*/
function getSecondsInMinute($y=null,$m=null,$d=null,$h=null,$i=null)
{
return 60;
}
}
?>
/tags/v1.0-Homere/bibliotheque/pear/DB.php
New file
0,0 → 1,1388
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Database independent query interface
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: DB.php,v 1.80 2005/02/16 02:16:00 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
/**
* Obtain the PEAR class so it can be extended from
*/
require_once 'PEAR.php';
 
 
// {{{ constants
// {{{ error codes
 
/**#@+
* One of PEAR DB's portable error codes.
* @see DB_common::errorCode(), DB::errorMessage()
*
* {@internal If you add an error code here, make sure you also add a textual
* version of it in DB::errorMessage().}}
*/
 
/**
* The code returned by many methods upon success
*/
define('DB_OK', 1);
 
/**
* Unkown error
*/
define('DB_ERROR', -1);
 
/**
* Syntax error
*/
define('DB_ERROR_SYNTAX', -2);
 
/**
* Tried to insert a duplicate value into a primary or unique index
*/
define('DB_ERROR_CONSTRAINT', -3);
 
/**
* An identifier in the query refers to a non-existant object
*/
define('DB_ERROR_NOT_FOUND', -4);
 
/**
* Tried to create a duplicate object
*/
define('DB_ERROR_ALREADY_EXISTS', -5);
 
/**
* The current driver does not support the action you attempted
*/
define('DB_ERROR_UNSUPPORTED', -6);
 
/**
* The number of parameters does not match the number of placeholders
*/
define('DB_ERROR_MISMATCH', -7);
 
/**
* A literal submitted did not match the data type expected
*/
define('DB_ERROR_INVALID', -8);
 
/**
* The current DBMS does not support the action you attempted
*/
define('DB_ERROR_NOT_CAPABLE', -9);
 
/**
* A literal submitted was too long so the end of it was removed
*/
define('DB_ERROR_TRUNCATED', -10);
 
/**
* A literal number submitted did not match the data type expected
*/
define('DB_ERROR_INVALID_NUMBER', -11);
 
/**
* A literal date submitted did not match the data type expected
*/
define('DB_ERROR_INVALID_DATE', -12);
 
/**
* Attempt to divide something by zero
*/
define('DB_ERROR_DIVZERO', -13);
 
/**
* A database needs to be selected
*/
define('DB_ERROR_NODBSELECTED', -14);
 
/**
* Could not create the object requested
*/
define('DB_ERROR_CANNOT_CREATE', -15);
 
/**
* Could not drop the database requested because it does not exist
*/
define('DB_ERROR_CANNOT_DROP', -17);
 
/**
* An identifier in the query refers to a non-existant table
*/
define('DB_ERROR_NOSUCHTABLE', -18);
 
/**
* An identifier in the query refers to a non-existant column
*/
define('DB_ERROR_NOSUCHFIELD', -19);
 
/**
* The data submitted to the method was inappropriate
*/
define('DB_ERROR_NEED_MORE_DATA', -20);
 
/**
* The attempt to lock the table failed
*/
define('DB_ERROR_NOT_LOCKED', -21);
 
/**
* The number of columns doesn't match the number of values
*/
define('DB_ERROR_VALUE_COUNT_ON_ROW', -22);
 
/**
* The DSN submitted has problems
*/
define('DB_ERROR_INVALID_DSN', -23);
 
/**
* Could not connect to the database
*/
define('DB_ERROR_CONNECT_FAILED', -24);
 
/**
* The PHP extension needed for this DBMS could not be found
*/
define('DB_ERROR_EXTENSION_NOT_FOUND',-25);
 
/**
* The present user has inadequate permissions to perform the task requestd
*/
define('DB_ERROR_ACCESS_VIOLATION', -26);
 
/**
* The database requested does not exist
*/
define('DB_ERROR_NOSUCHDB', -27);
 
/**
* Tried to insert a null value into a column that doesn't allow nulls
*/
define('DB_ERROR_CONSTRAINT_NOT_NULL',-29);
/**#@-*/
 
 
// }}}
// {{{ prepared statement-related
 
 
/**#@+
* Identifiers for the placeholders used in prepared statements.
* @see DB_common::prepare()
*/
 
/**
* Indicates a scalar (<kbd>?</kbd>) placeholder was used
*
* Quote and escape the value as necessary.
*/
define('DB_PARAM_SCALAR', 1);
 
/**
* Indicates an opaque (<kbd>&</kbd>) placeholder was used
*
* The value presented is a file name. Extract the contents of that file
* and place them in this column.
*/
define('DB_PARAM_OPAQUE', 2);
 
/**
* Indicates a misc (<kbd>!</kbd>) placeholder was used
*
* The value should not be quoted or escaped.
*/
define('DB_PARAM_MISC', 3);
/**#@-*/
 
 
// }}}
// {{{ binary data-related
 
 
/**#@+
* The different ways of returning binary data from queries.
*/
 
/**
* Sends the fetched data straight through to output
*/
define('DB_BINMODE_PASSTHRU', 1);
 
/**
* Lets you return data as usual
*/
define('DB_BINMODE_RETURN', 2);
 
/**
* Converts the data to hex format before returning it
*
* For example the string "123" would become "313233".
*/
define('DB_BINMODE_CONVERT', 3);
/**#@-*/
 
 
// }}}
// {{{ fetch modes
 
 
/**#@+
* Fetch Modes.
* @see DB_common::setFetchMode()
*/
 
/**
* Indicates the current default fetch mode should be used
* @see DB_common::$fetchmode
*/
define('DB_FETCHMODE_DEFAULT', 0);
 
/**
* Column data indexed by numbers, ordered from 0 and up
*/
define('DB_FETCHMODE_ORDERED', 1);
 
/**
* Column data indexed by column names
*/
define('DB_FETCHMODE_ASSOC', 2);
 
/**
* Column data as object properties
*/
define('DB_FETCHMODE_OBJECT', 3);
 
/**
* For multi-dimensional results, make the column name the first level
* of the array and put the row number in the second level of the array
*
* This is flipped from the normal behavior, which puts the row numbers
* in the first level of the array and the column names in the second level.
*/
define('DB_FETCHMODE_FLIPPED', 4);
/**#@-*/
 
/**#@+
* Old fetch modes. Left here for compatibility.
*/
define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED);
/**#@-*/
 
 
// }}}
// {{{ tableInfo() && autoPrepare()-related
 
 
/**#@+
* The type of information to return from the tableInfo() method.
*
* Bitwised constants, so they can be combined using <kbd>|</kbd>
* and removed using <kbd>^</kbd>.
*
* @see DB_common::tableInfo()
*
* {@internal Since the TABLEINFO constants are bitwised, if more of them are
* added in the future, make sure to adjust DB_TABLEINFO_FULL accordingly.}}
*/
define('DB_TABLEINFO_ORDER', 1);
define('DB_TABLEINFO_ORDERTABLE', 2);
define('DB_TABLEINFO_FULL', 3);
/**#@-*/
 
 
/**#@+
* The type of query to create with the automatic query building methods.
* @see DB_common::autoPrepare(), DB_common::autoExecute()
*/
define('DB_AUTOQUERY_INSERT', 1);
define('DB_AUTOQUERY_UPDATE', 2);
/**#@-*/
 
 
// }}}
// {{{ portability modes
 
 
/**#@+
* Portability Modes.
*
* Bitwised constants, so they can be combined using <kbd>|</kbd>
* and removed using <kbd>^</kbd>.
*
* @see DB_common::setOption()
*
* {@internal Since the PORTABILITY constants are bitwised, if more of them are
* added in the future, make sure to adjust DB_PORTABILITY_ALL accordingly.}}
*/
 
/**
* Turn off all portability features
*/
define('DB_PORTABILITY_NONE', 0);
 
/**
* Convert names of tables and fields to lower case
* when using the get*(), fetch*() and tableInfo() methods
*/
define('DB_PORTABILITY_LOWERCASE', 1);
 
/**
* Right trim the data output by get*() and fetch*()
*/
define('DB_PORTABILITY_RTRIM', 2);
 
/**
* Force reporting the number of rows deleted
*/
define('DB_PORTABILITY_DELETE_COUNT', 4);
 
/**
* Enable hack that makes numRows() work in Oracle
*/
define('DB_PORTABILITY_NUMROWS', 8);
 
/**
* Makes certain error messages in certain drivers compatible
* with those from other DBMS's
*
* + mysql, mysqli: change unique/primary key constraints
* DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
*
* + odbc(access): MS's ODBC driver reports 'no such field' as code
* 07001, which means 'too few parameters.' When this option is on
* that code gets mapped to DB_ERROR_NOSUCHFIELD.
*/
define('DB_PORTABILITY_ERRORS', 16);
 
/**
* Convert null values to empty strings in data output by
* get*() and fetch*()
*/
define('DB_PORTABILITY_NULL_TO_EMPTY', 32);
 
/**
* Turn on all portability features
*/
define('DB_PORTABILITY_ALL', 63);
/**#@-*/
 
// }}}
 
 
// }}}
// {{{ class DB
 
/**
* Database independent query interface
*
* The main "DB" class is simply a container class with some static
* methods for creating DB objects as well as some utility functions
* common to all parts of DB.
*
* The object model of DB is as follows (indentation means inheritance):
* <pre>
* DB The main DB class. This is simply a utility class
* with some "static" methods for creating DB objects as
* well as common utility functions for other DB classes.
*
* DB_common The base for each DB implementation. Provides default
* | implementations (in OO lingo virtual methods) for
* | the actual DB implementations as well as a bunch of
* | query utility functions.
* |
* +-DB_mysql The DB implementation for MySQL. Inherits DB_common.
* When calling DB::factory or DB::connect for MySQL
* connections, the object returned is an instance of this
* class.
* </pre>
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB
{
// {{{ &factory()
 
/**
* Create a new DB object for the specified database type but don't
* connect to the database
*
* @param string $type the database type (eg "mysql")
* @param array $options an associative array of option names and values
*
* @return object a new DB object. A DB_Error object on failure.
*
* @see DB_common::setOption()
*/
function &factory($type, $options = false)
{
if (!is_array($options)) {
$options = array('persistent' => $options);
}
 
if (isset($options['debug']) && $options['debug'] >= 2) {
// expose php errors with sufficient debug level
include_once "DB/{$type}.php";
} else {
@include_once "DB/{$type}.php";
}
 
$classname = "DB_${type}";
 
if (!class_exists($classname)) {
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null,
"Unable to include the DB/{$type}.php"
. " file for '$dsn'",
'DB_Error', true);
return $tmp;
}
 
@$obj =& new $classname;
 
foreach ($options as $option => $value) {
$test = $obj->setOption($option, $value);
if (DB::isError($test)) {
return $test;
}
}
 
return $obj;
}
 
// }}}
// {{{ &connect()
 
/**
* Create a new DB object including a connection to the specified database
*
* Example 1.
* <code>
* require_once 'DB.php';
*
* $dsn = 'pgsql://user:password@host/database';
* $options = array(
* 'debug' => 2,
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
* </code>
*
* @param mixed $dsn the string "data source name" or array in the
* format returned by DB::parseDSN()
* @param array $options an associative array of option names and values
*
* @return object a new DB object. A DB_Error object on failure.
*
* @uses DB_dbase::connect(), DB_fbsql::connect(), DB_ibase::connect(),
* DB_ifx::connect(), DB_msql::connect(), DB_mssql::connect(),
* DB_mysql::connect(), DB_mysqli::connect(), DB_oci8::connect(),
* DB_odbc::connect(), DB_pgsql::connect(), DB_sqlite::connect(),
* DB_sybase::connect()
*
* @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError()
*/
function &connect($dsn, $options = array())
{
$dsninfo = DB::parseDSN($dsn);
$type = $dsninfo['phptype'];
 
if (!is_array($options)) {
/*
* For backwards compatibility. $options used to be boolean,
* indicating whether the connection should be persistent.
*/
$options = array('persistent' => $options);
}
 
if (isset($options['debug']) && $options['debug'] >= 2) {
// expose php errors with sufficient debug level
include_once "DB/${type}.php";
} else {
@include_once "DB/${type}.php";
}
 
$classname = "DB_${type}";
if (!class_exists($classname)) {
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null,
"Unable to include the DB/{$type}.php"
. " file for '$dsn'",
'DB_Error', true);
return $tmp;
}
 
@$obj =& new $classname;
 
foreach ($options as $option => $value) {
$test = $obj->setOption($option, $value);
if (DB::isError($test)) {
return $test;
}
}
 
$err = $obj->connect($dsninfo, $obj->getOption('persistent'));
if (DB::isError($err)) {
$err->addUserInfo($dsn);
return $err;
}
 
return $obj;
}
 
// }}}
// {{{ apiVersion()
 
/**
* Return the DB API version
*
* @return string the DB API version number
*/
function apiVersion()
{
return '1.7.6';
}
 
// }}}
// {{{ isError()
 
/**
* Determines if a variable is a DB_Error object
*
* @param mixed $value the variable to check
*
* @return bool whether $value is DB_Error object
*/
function isError($value)
{
return is_a($value, 'DB_Error');
}
 
// }}}
// {{{ isConnection()
 
/**
* Determines if a value is a DB_<driver> object
*
* @param mixed $value the value to test
*
* @return bool whether $value is a DB_<driver> object
*/
function isConnection($value)
{
return (is_object($value) &&
is_subclass_of($value, 'db_common') &&
method_exists($value, 'simpleQuery'));
}
 
// }}}
// {{{ isManip()
 
/**
* Tell whether a query is a data manipulation or data definition query
*
* Examples of data manipulation queries are INSERT, UPDATE and DELETE.
* Examples of data definition queries are CREATE, DROP, ALTER, GRANT,
* REVOKE.
*
* @param string $query the query
*
* @return boolean whether $query is a data manipulation query
*/
function isManip($query)
{
$manips = 'INSERT|UPDATE|DELETE|REPLACE|'
. 'CREATE|DROP|'
. 'LOAD DATA|SELECT .* INTO|COPY|'
. 'ALTER|GRANT|REVOKE|'
. 'LOCK|UNLOCK';
if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) {
return true;
}
return false;
}
 
// }}}
// {{{ errorMessage()
 
/**
* Return a textual error message for a DB error code
*
* @param integer $value the DB error code
*
* @return string the error message or false if the error code was
* not recognized
*/
function errorMessage($value)
{
static $errorMessages;
if (!isset($errorMessages)) {
$errorMessages = array(
DB_ERROR => 'unknown error',
DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions',
DB_ERROR_ALREADY_EXISTS => 'already exists',
DB_ERROR_CANNOT_CREATE => 'can not create',
DB_ERROR_CANNOT_DROP => 'can not drop',
DB_ERROR_CONNECT_FAILED => 'connect failed',
DB_ERROR_CONSTRAINT => 'constraint violation',
DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint',
DB_ERROR_DIVZERO => 'division by zero',
DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found',
DB_ERROR_INVALID => 'invalid',
DB_ERROR_INVALID_DATE => 'invalid date or time',
DB_ERROR_INVALID_DSN => 'invalid DSN',
DB_ERROR_INVALID_NUMBER => 'invalid number',
DB_ERROR_MISMATCH => 'mismatch',
DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied',
DB_ERROR_NODBSELECTED => 'no database selected',
DB_ERROR_NOSUCHDB => 'no such database',
DB_ERROR_NOSUCHFIELD => 'no such field',
DB_ERROR_NOSUCHTABLE => 'no such table',
DB_ERROR_NOT_CAPABLE => 'DB backend not capable',
DB_ERROR_NOT_FOUND => 'not found',
DB_ERROR_NOT_LOCKED => 'not locked',
DB_ERROR_SYNTAX => 'syntax error',
DB_ERROR_UNSUPPORTED => 'not supported',
DB_ERROR_TRUNCATED => 'truncated',
DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row',
DB_OK => 'no error',
);
}
 
if (DB::isError($value)) {
$value = $value->getCode();
}
 
return isset($errorMessages[$value]) ? $errorMessages[$value]
: $errorMessages[DB_ERROR];
}
 
// }}}
// {{{ parseDSN()
 
/**
* Parse a data source name
*
* Additional keys can be added by appending a URI query string to the
* end of the DSN.
*
* The format of the supplied DSN is in its fullest form:
* <code>
* phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true
* </code>
*
* Most variations are allowed:
* <code>
* phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644
* phptype://username:password@hostspec/database_name
* phptype://username:password@hostspec
* phptype://username@hostspec
* phptype://hostspec/database
* phptype://hostspec
* phptype(dbsyntax)
* phptype
* </code>
*
* @param string $dsn Data Source Name to be parsed
*
* @return array an associative array with the following keys:
* + phptype: Database backend used in PHP (mysql, odbc etc.)
* + dbsyntax: Database used with regards to SQL syntax etc.
* + protocol: Communication protocol to use (tcp, unix etc.)
* + hostspec: Host specification (hostname[:port])
* + database: Database to use on the DBMS server
* + username: User name for login
* + password: Password for login
*/
function parseDSN($dsn)
{
$parsed = array(
'phptype' => false,
'dbsyntax' => false,
'username' => false,
'password' => false,
'protocol' => false,
'hostspec' => false,
'port' => false,
'socket' => false,
'database' => false,
);
 
if (is_array($dsn)) {
$dsn = array_merge($parsed, $dsn);
if (!$dsn['dbsyntax']) {
$dsn['dbsyntax'] = $dsn['phptype'];
}
return $dsn;
}
 
// Find phptype and dbsyntax
if (($pos = strpos($dsn, '://')) !== false) {
$str = substr($dsn, 0, $pos);
$dsn = substr($dsn, $pos + 3);
} else {
$str = $dsn;
$dsn = null;
}
 
// Get phptype and dbsyntax
// $str => phptype(dbsyntax)
if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
$parsed['phptype'] = $arr[1];
$parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2];
} else {
$parsed['phptype'] = $str;
$parsed['dbsyntax'] = $str;
}
 
if (!count($dsn)) {
return $parsed;
}
 
// Get (if found): username and password
// $dsn => username:password@protocol+hostspec/database
if (($at = strrpos($dsn,'@')) !== false) {
$str = substr($dsn, 0, $at);
$dsn = substr($dsn, $at + 1);
if (($pos = strpos($str, ':')) !== false) {
$parsed['username'] = rawurldecode(substr($str, 0, $pos));
$parsed['password'] = rawurldecode(substr($str, $pos + 1));
} else {
$parsed['username'] = rawurldecode($str);
}
}
 
// Find protocol and hostspec
 
if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) {
// $dsn => proto(proto_opts)/database
$proto = $match[1];
$proto_opts = $match[2] ? $match[2] : false;
$dsn = $match[3];
 
} else {
// $dsn => protocol+hostspec/database (old format)
if (strpos($dsn, '+') !== false) {
list($proto, $dsn) = explode('+', $dsn, 2);
}
if (strpos($dsn, '/') !== false) {
list($proto_opts, $dsn) = explode('/', $dsn, 2);
} else {
$proto_opts = $dsn;
$dsn = null;
}
}
 
// process the different protocol options
$parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
$proto_opts = rawurldecode($proto_opts);
if ($parsed['protocol'] == 'tcp') {
if (strpos($proto_opts, ':') !== false) {
list($parsed['hostspec'],
$parsed['port']) = explode(':', $proto_opts);
} else {
$parsed['hostspec'] = $proto_opts;
}
} elseif ($parsed['protocol'] == 'unix') {
$parsed['socket'] = $proto_opts;
}
 
// Get dabase if any
// $dsn => database
if ($dsn) {
if (($pos = strpos($dsn, '?')) === false) {
// /database
$parsed['database'] = rawurldecode($dsn);
} else {
// /database?param1=value1&param2=value2
$parsed['database'] = rawurldecode(substr($dsn, 0, $pos));
$dsn = substr($dsn, $pos + 1);
if (strpos($dsn, '&') !== false) {
$opts = explode('&', $dsn);
} else { // database?param1=value1
$opts = array($dsn);
}
foreach ($opts as $opt) {
list($key, $value) = explode('=', $opt);
if (!isset($parsed[$key])) {
// don't allow params overwrite
$parsed[$key] = rawurldecode($value);
}
}
}
}
 
return $parsed;
}
 
// }}}
}
 
// }}}
// {{{ class DB_Error
 
/**
* DB_Error implements a class for reporting portable database error
* messages
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_Error extends PEAR_Error
{
// {{{ constructor
 
/**
* DB_Error constructor
*
* @param mixed $code DB error code, or string with error message
* @param int $mode what "error mode" to operate in
* @param int $level what error level to use for $mode &
* PEAR_ERROR_TRIGGER
* @param mixed $debuginfo additional debug info, such as the last query
*
* @see PEAR_Error
*/
function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
$level = E_USER_NOTICE, $debuginfo = null)
{
if (is_int($code)) {
$this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code,
$mode, $level, $debuginfo);
} else {
$this->PEAR_Error("DB Error: $code", DB_ERROR,
$mode, $level, $debuginfo);
}
}
 
// }}}
}
 
// }}}
// {{{ class DB_result
 
/**
* This class implements a wrapper for a DB result set
*
* A new instance of this class will be returned by the DB implementation
* after processing a query that returns data.
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_result
{
// {{{ properties
 
/**
* Should results be freed automatically when there are no more rows?
* @var boolean
* @see DB_common::$options
*/
var $autofree;
 
/**
* A reference to the DB_<driver> object
* @var object
*/
var $dbh;
 
/**
* The current default fetch mode
* @var integer
* @see DB_common::$fetchmode
*/
var $fetchmode;
 
/**
* The name of the class into which results should be fetched when
* DB_FETCHMODE_OBJECT is in effect
*
* @var string
* @see DB_common::$fetchmode_object_class
*/
var $fetchmode_object_class;
 
/**
* The number of rows to fetch from a limit query
* @var integer
*/
var $limit_count = null;
 
/**
* The row to start fetching from in limit queries
* @var integer
*/
var $limit_from = null;
 
/**
* The execute parameters that created this result
* @var array
* @since Property available since Release 1.7.0
*/
var $parameters;
 
/**
* The query string that created this result
*
* Copied here incase it changes in $dbh, which is referenced
*
* @var string
* @since Property available since Release 1.7.0
*/
var $query;
 
/**
* The query result resource id created by PHP
* @var resource
*/
var $result;
 
/**
* The present row being dealt with
* @var integer
*/
var $row_counter = null;
 
/**
* The prepared statement resource id created by PHP in $dbh
*
* This resource is only available when the result set was created using
* a driver's native execute() method, not PEAR DB's emulated one.
*
* Copied here incase it changes in $dbh, which is referenced
*
* {@internal Mainly here because the InterBase/Firebird API is only
* able to retrieve data from result sets if the statemnt handle is
* still in scope.}}
*
* @var resource
* @since Property available since Release 1.7.0
*/
var $statement;
 
 
// }}}
// {{{ constructor
 
/**
* This constructor sets the object's properties
*
* @param object &$dbh the DB object reference
* @param resource $result the result resource id
* @param array $options an associative array with result options
*
* @return void
*/
function DB_result(&$dbh, $result, $options = array())
{
$this->autofree = $dbh->options['autofree'];
$this->dbh = &$dbh;
$this->fetchmode = $dbh->fetchmode;
$this->fetchmode_object_class = $dbh->fetchmode_object_class;
$this->parameters = $dbh->last_parameters;
$this->query = $dbh->last_query;
$this->result = $result;
$this->statement = empty($dbh->last_stmt) ? null : $dbh->last_stmt;
foreach ($options as $key => $value) {
$this->setOption($key, $value);
}
}
 
/**
* Set options for the DB_result object
*
* @param string $key the option to set
* @param mixed $value the value to set the option to
*
* @return void
*/
function setOption($key, $value = null)
{
switch ($key) {
case 'limit_from':
$this->limit_from = $value;
break;
case 'limit_count':
$this->limit_count = $value;
}
}
 
// }}}
// {{{ fetchRow()
 
/**
* Fetch a row of data and return it by reference into an array
*
* The type of array returned can be controlled either by setting this
* method's <var>$fetchmode</var> parameter or by changing the default
* fetch mode setFetchMode() before calling this method.
*
* There are two options for standardizing the information returned
* from databases, ensuring their values are consistent when changing
* DBMS's. These portability options can be turned on when creating a
* new DB object or by using setOption().
*
* + <var>DB_PORTABILITY_LOWERCASE</var>
* convert names of fields to lower case
*
* + <var>DB_PORTABILITY_RTRIM</var>
* right trim the data
*
* @param int $fetchmode the constant indicating how to format the data
* @param int $rownum the row number to fetch (index starts at 0)
*
* @return mixed an array or object containing the row's data,
* NULL when the end of the result set is reached
* or a DB_Error object on failure.
*
* @see DB_common::setOption(), DB_common::setFetchMode()
*/
function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null)
{
if ($fetchmode === DB_FETCHMODE_DEFAULT) {
$fetchmode = $this->fetchmode;
}
if ($fetchmode === DB_FETCHMODE_OBJECT) {
$fetchmode = DB_FETCHMODE_ASSOC;
$object_class = $this->fetchmode_object_class;
}
if ($this->limit_from !== null) {
if ($this->row_counter === null) {
$this->row_counter = $this->limit_from;
// Skip rows
if ($this->dbh->features['limit'] === false) {
$i = 0;
while ($i++ < $this->limit_from) {
$this->dbh->fetchInto($this->result, $arr, $fetchmode);
}
}
}
if ($this->row_counter >= ($this->limit_from + $this->limit_count))
{
if ($this->autofree) {
$this->free();
}
$tmp = null;
return $tmp;
}
if ($this->dbh->features['limit'] === 'emulate') {
$rownum = $this->row_counter;
}
$this->row_counter++;
}
$res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum);
if ($res === DB_OK) {
if (isset($object_class)) {
// The default mode is specified in the
// DB_common::fetchmode_object_class property
if ($object_class == 'stdClass') {
$arr = (object) $arr;
} else {
$arr = &new $object_class($arr);
}
}
return $arr;
}
if ($res == null && $this->autofree) {
$this->free();
}
return $res;
}
 
// }}}
// {{{ fetchInto()
 
/**
* Fetch a row of data into an array which is passed by reference
*
* The type of array returned can be controlled either by setting this
* method's <var>$fetchmode</var> parameter or by changing the default
* fetch mode setFetchMode() before calling this method.
*
* There are two options for standardizing the information returned
* from databases, ensuring their values are consistent when changing
* DBMS's. These portability options can be turned on when creating a
* new DB object or by using setOption().
*
* + <var>DB_PORTABILITY_LOWERCASE</var>
* convert names of fields to lower case
*
* + <var>DB_PORTABILITY_RTRIM</var>
* right trim the data
*
* @param array &$arr the variable where the data should be placed
* @param int $fetchmode the constant indicating how to format the data
* @param int $rownum the row number to fetch (index starts at 0)
*
* @return mixed DB_OK if a row is processed, NULL when the end of the
* result set is reached or a DB_Error object on failure
*
* @see DB_common::setOption(), DB_common::setFetchMode()
*/
function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null)
{
if ($fetchmode === DB_FETCHMODE_DEFAULT) {
$fetchmode = $this->fetchmode;
}
if ($fetchmode === DB_FETCHMODE_OBJECT) {
$fetchmode = DB_FETCHMODE_ASSOC;
$object_class = $this->fetchmode_object_class;
}
if ($this->limit_from !== null) {
if ($this->row_counter === null) {
$this->row_counter = $this->limit_from;
// Skip rows
if ($this->dbh->features['limit'] === false) {
$i = 0;
while ($i++ < $this->limit_from) {
$this->dbh->fetchInto($this->result, $arr, $fetchmode);
}
}
}
if ($this->row_counter >= (
$this->limit_from + $this->limit_count))
{
if ($this->autofree) {
$this->free();
}
return null;
}
if ($this->dbh->features['limit'] === 'emulate') {
$rownum = $this->row_counter;
}
 
$this->row_counter++;
}
$res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum);
if ($res === DB_OK) {
if (isset($object_class)) {
// default mode specified in the
// DB_common::fetchmode_object_class property
if ($object_class == 'stdClass') {
$arr = (object) $arr;
} else {
$arr = new $object_class($arr);
}
}
return DB_OK;
}
if ($res == null && $this->autofree) {
$this->free();
}
return $res;
}
 
// }}}
// {{{ numCols()
 
/**
* Get the the number of columns in a result set
*
* @return int the number of columns. A DB_Error object on failure.
*/
function numCols()
{
return $this->dbh->numCols($this->result);
}
 
// }}}
// {{{ numRows()
 
/**
* Get the number of rows in a result set
*
* @return int the number of rows. A DB_Error object on failure.
*/
function numRows()
{
if ($this->dbh->features['numrows'] === 'emulate'
&& $this->dbh->options['portability'] & DB_PORTABILITY_NUMROWS)
{
if ($this->dbh->features['prepare']) {
$res = $this->dbh->query($this->query, $this->parameters);
} else {
$res = $this->dbh->query($this->query);
}
if (DB::isError($res)) {
return $res;
}
$i = 0;
while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) {
$i++;
}
return $i;
} else {
return $this->dbh->numRows($this->result);
}
}
 
// }}}
// {{{ nextResult()
 
/**
* Get the next result if a batch of queries was executed
*
* @return bool true if a new result is available or false if not
*/
function nextResult()
{
return $this->dbh->nextResult($this->result);
}
 
// }}}
// {{{ free()
 
/**
* Frees the resources allocated for this result set
*
* @return bool true on success. A DB_Error object on failure.
*/
function free()
{
$err = $this->dbh->freeResult($this->result);
if (DB::isError($err)) {
return $err;
}
$this->result = false;
$this->statement = false;
return true;
}
 
// }}}
// {{{ tableInfo()
 
/**
* @see DB_common::tableInfo()
* @deprecated Method deprecated some time before Release 1.2
*/
function tableInfo($mode = null)
{
if (is_string($mode)) {
return $this->dbh->raiseError(DB_ERROR_NEED_MORE_DATA);
}
return $this->dbh->tableInfo($this, $mode);
}
 
// }}}
// {{{ getQuery()
 
/**
* Determine the query string that created this result
*
* @return string the query string
*
* @since Method available since Release 1.7.0
*/
function getQuery()
{
return $this->query;
}
 
// }}}
// {{{ getRowCounter()
 
/**
* Tells which row number is currently being processed
*
* @return integer the current row being looked at. Starts at 1.
*/
function getRowCounter()
{
return $this->row_counter;
}
 
// }}}
}
 
// }}}
// {{{ class DB_row
 
/**
* PEAR DB Row Object
*
* The object contains a row of data from a result set. Each column's data
* is placed in a property named for the column.
*
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
* @see DB_common::setFetchMode()
*/
class DB_row
{
// {{{ constructor
 
/**
* The constructor places a row's data into properties of this object
*
* @param array the array containing the row's data
*
* @return void
*/
function DB_row(&$arr)
{
foreach ($arr as $key => $value) {
$this->$key = &$arr[$key];
}
}
 
// }}}
}
 
// }}}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/tags/v1.0-Homere/bibliotheque/pear/PEAR.php
New file
0,0 → 1,1108
<?php
/**
* PEAR, the PHP Extension and Application Repository
*
* PEAR class and PEAR_Error class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Sterling Hughes <sterling@php.net>
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: PEAR.php,v 1.101 2006/04/25 02:41:03 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**#@+
* ERROR constants
*/
define('PEAR_ERROR_RETURN', 1);
define('PEAR_ERROR_PRINT', 2);
define('PEAR_ERROR_TRIGGER', 4);
define('PEAR_ERROR_DIE', 8);
define('PEAR_ERROR_CALLBACK', 16);
/**
* WARNING: obsolete
* @deprecated
*/
define('PEAR_ERROR_EXCEPTION', 32);
/**#@-*/
define('PEAR_ZE2', (function_exists('version_compare') &&
version_compare(zend_version(), "2-dev", "ge")));
 
if (substr(PHP_OS, 0, 3) == 'WIN') {
define('OS_WINDOWS', true);
define('OS_UNIX', false);
define('PEAR_OS', 'Windows');
} else {
define('OS_WINDOWS', false);
define('OS_UNIX', true);
define('PEAR_OS', 'Unix'); // blatant assumption
}
 
// instant backwards compatibility
if (!defined('PATH_SEPARATOR')) {
if (OS_WINDOWS) {
define('PATH_SEPARATOR', ';');
} else {
define('PATH_SEPARATOR', ':');
}
}
 
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
$GLOBALS['_PEAR_destructor_object_list'] = array();
$GLOBALS['_PEAR_shutdown_funcs'] = array();
$GLOBALS['_PEAR_error_handler_stack'] = array();
 
@ini_set('track_errors', true);
 
/**
* Base class for other PEAR classes. Provides rudimentary
* emulation of destructors.
*
* If you want a destructor in your class, inherit PEAR and make a
* destructor method called _yourclassname (same name as the
* constructor, but with a "_" prefix). Also, in your constructor you
* have to call the PEAR constructor: $this->PEAR();.
* The destructor method will be called without parameters. Note that
* at in some SAPI implementations (such as Apache), any output during
* the request shutdown (in which destructors are called) seems to be
* discarded. If you need to get any debug information from your
* destructor, use error_log(), syslog() or something similar.
*
* IMPORTANT! To use the emulated destructors you need to create the
* objects by reference: $obj =& new PEAR_child;
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @see PEAR_Error
* @since Class available since PHP 4.0.2
* @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear
*/
class PEAR
{
// {{{ properties
 
/**
* Whether to enable internal debug messages.
*
* @var bool
* @access private
*/
var $_debug = false;
 
/**
* Default error mode for this object.
*
* @var int
* @access private
*/
var $_default_error_mode = null;
 
/**
* Default error options used for this object when error mode
* is PEAR_ERROR_TRIGGER.
*
* @var int
* @access private
*/
var $_default_error_options = null;
 
/**
* Default error handler (callback) for this object, if error mode is
* PEAR_ERROR_CALLBACK.
*
* @var string
* @access private
*/
var $_default_error_handler = '';
 
/**
* Which class to use for error objects.
*
* @var string
* @access private
*/
var $_error_class = 'PEAR_Error';
 
/**
* An array of expected errors.
*
* @var array
* @access private
*/
var $_expected_errors = array();
 
// }}}
 
// {{{ constructor
 
/**
* Constructor. Registers this object in
* $_PEAR_destructor_object_list for destructor emulation if a
* destructor object exists.
*
* @param string $error_class (optional) which class to use for
* error objects, defaults to PEAR_Error.
* @access public
* @return void
*/
function PEAR($error_class = null)
{
$classname = strtolower(get_class($this));
if ($this->_debug) {
print "PEAR constructor called, class=$classname\n";
}
if ($error_class !== null) {
$this->_error_class = $error_class;
}
while ($classname && strcasecmp($classname, "pear")) {
$destructor = "_$classname";
if (method_exists($this, $destructor)) {
global $_PEAR_destructor_object_list;
$_PEAR_destructor_object_list[] = &$this;
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
register_shutdown_function("_PEAR_call_destructors");
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
}
break;
} else {
$classname = get_parent_class($classname);
}
}
}
 
// }}}
// {{{ destructor
 
/**
* Destructor (the emulated type of...). Does nothing right now,
* but is included for forward compatibility, so subclass
* destructors should always call it.
*
* See the note in the class desciption about output from
* destructors.
*
* @access public
* @return void
*/
function _PEAR() {
if ($this->_debug) {
printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
}
}
 
// }}}
// {{{ getStaticProperty()
 
/**
* If you have a class that's mostly/entirely static, and you need static
* properties, you can use this method to simulate them. Eg. in your method(s)
* do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
* You MUST use a reference, or they will not persist!
*
* @access public
* @param string $class The calling classname, to prevent clashes
* @param string $var The variable to retrieve.
* @return mixed A reference to the variable. If not set it will be
* auto initialised to NULL.
*/
function &getStaticProperty($class, $var)
{
static $properties;
if (!isset($properties[$class])) {
$properties[$class] = array();
}
if (!array_key_exists($var, $properties[$class])) {
$properties[$class][$var] = null;
}
return $properties[$class][$var];
}
 
// }}}
// {{{ registerShutdownFunc()
 
/**
* Use this function to register a shutdown method for static
* classes.
*
* @access public
* @param mixed $func The function name (or array of class/method) to call
* @param mixed $args The arguments to pass to the function
* @return void
*/
function registerShutdownFunc($func, $args = array())
{
// if we are called statically, there is a potential
// that no shutdown func is registered. Bug #6445
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
register_shutdown_function("_PEAR_call_destructors");
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
}
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
}
 
// }}}
// {{{ isError()
 
/**
* Tell whether a value is a PEAR error.
*
* @param mixed $data the value to test
* @param int $code if $data is an error object, return true
* only if $code is a string and
* $obj->getMessage() == $code or
* $code is an integer and $obj->getCode() == $code
* @access public
* @return bool true if parameter is an error
*/
function isError($data, $code = null)
{
if (is_a($data, 'PEAR_Error')) {
if (is_null($code)) {
return true;
} elseif (is_string($code)) {
return $data->getMessage() == $code;
} else {
return $data->getCode() == $code;
}
}
return false;
}
 
// }}}
// {{{ setErrorHandling()
 
/**
* Sets how errors generated by this object should be handled.
* Can be invoked both in objects and statically. If called
* statically, setErrorHandling sets the default behaviour for all
* PEAR objects. If called in an object, setErrorHandling sets
* the default behaviour for that object.
*
* @param int $mode
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
*
* @param mixed $options
* When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
* of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
*
* When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
* to be the callback function or method. A callback
* function is a string with the name of the function, a
* callback method is an array of two elements: the element
* at index 0 is the object, and the element at index 1 is
* the name of the method to call in the object.
*
* When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
* a printf format string used when printing the error
* message.
*
* @access public
* @return void
* @see PEAR_ERROR_RETURN
* @see PEAR_ERROR_PRINT
* @see PEAR_ERROR_TRIGGER
* @see PEAR_ERROR_DIE
* @see PEAR_ERROR_CALLBACK
* @see PEAR_ERROR_EXCEPTION
*
* @since PHP 4.0.5
*/
 
function setErrorHandling($mode = null, $options = null)
{
if (isset($this) && is_a($this, 'PEAR')) {
$setmode = &$this->_default_error_mode;
$setoptions = &$this->_default_error_options;
} else {
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
}
 
switch ($mode) {
case PEAR_ERROR_EXCEPTION:
case PEAR_ERROR_RETURN:
case PEAR_ERROR_PRINT:
case PEAR_ERROR_TRIGGER:
case PEAR_ERROR_DIE:
case null:
$setmode = $mode;
$setoptions = $options;
break;
 
case PEAR_ERROR_CALLBACK:
$setmode = $mode;
// class/object method callback
if (is_callable($options)) {
$setoptions = $options;
} else {
trigger_error("invalid error callback", E_USER_WARNING);
}
break;
 
default:
trigger_error("invalid error mode", E_USER_WARNING);
break;
}
}
 
// }}}
// {{{ expectError()
 
/**
* This method is used to tell which errors you expect to get.
* Expected errors are always returned with error mode
* PEAR_ERROR_RETURN. Expected error codes are stored in a stack,
* and this method pushes a new element onto it. The list of
* expected errors are in effect until they are popped off the
* stack with the popExpect() method.
*
* Note that this method can not be called statically
*
* @param mixed $code a single error code or an array of error codes to expect
*
* @return int the new depth of the "expected errors" stack
* @access public
*/
function expectError($code = '*')
{
if (is_array($code)) {
array_push($this->_expected_errors, $code);
} else {
array_push($this->_expected_errors, array($code));
}
return sizeof($this->_expected_errors);
}
 
// }}}
// {{{ popExpect()
 
/**
* This method pops one element off the expected error codes
* stack.
*
* @return array the list of error codes that were popped
*/
function popExpect()
{
return array_pop($this->_expected_errors);
}
 
// }}}
// {{{ _checkDelExpect()
 
/**
* This method checks unsets an error code if available
*
* @param mixed error code
* @return bool true if the error code was unset, false otherwise
* @access private
* @since PHP 4.3.0
*/
function _checkDelExpect($error_code)
{
$deleted = false;
 
foreach ($this->_expected_errors AS $key => $error_array) {
if (in_array($error_code, $error_array)) {
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
$deleted = true;
}
 
// clean up empty arrays
if (0 == count($this->_expected_errors[$key])) {
unset($this->_expected_errors[$key]);
}
}
return $deleted;
}
 
// }}}
// {{{ delExpect()
 
/**
* This method deletes all occurences of the specified element from
* the expected error codes stack.
*
* @param mixed $error_code error code that should be deleted
* @return mixed list of error codes that were deleted or error
* @access public
* @since PHP 4.3.0
*/
function delExpect($error_code)
{
$deleted = false;
 
if ((is_array($error_code) && (0 != count($error_code)))) {
// $error_code is a non-empty array here;
// we walk through it trying to unset all
// values
foreach($error_code as $key => $error) {
if ($this->_checkDelExpect($error)) {
$deleted = true;
} else {
$deleted = false;
}
}
return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
} elseif (!empty($error_code)) {
// $error_code comes alone, trying to unset it
if ($this->_checkDelExpect($error_code)) {
return true;
} else {
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
}
} else {
// $error_code is empty
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
}
}
 
// }}}
// {{{ raiseError()
 
/**
* This method is a wrapper that returns an instance of the
* configured error class with this object's default error
* handling applied. If the $mode and $options parameters are not
* specified, the object's defaults are used.
*
* @param mixed $message a text error message or a PEAR error object
*
* @param int $code a numeric error code (it is up to your class
* to define these if you want to use codes)
*
* @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
* PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
*
* @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
* specifies the PHP-internal error level (one of
* E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
* If $mode is PEAR_ERROR_CALLBACK, this
* parameter specifies the callback function or
* method. In other error modes this parameter
* is ignored.
*
* @param string $userinfo If you need to pass along for example debug
* information, this parameter is meant for that.
*
* @param string $error_class The returned error object will be
* instantiated from this class, if specified.
*
* @param bool $skipmsg If true, raiseError will only pass error codes,
* the error message parameter will be dropped.
*
* @access public
* @return object a PEAR error object
* @see PEAR::setErrorHandling
* @since PHP 4.0.5
*/
function &raiseError($message = null,
$code = null,
$mode = null,
$options = null,
$userinfo = null,
$error_class = null,
$skipmsg = false)
{
// The error is yet a PEAR error object
if (is_object($message)) {
$code = $message->getCode();
$userinfo = $message->getUserInfo();
$error_class = $message->getType();
$message->error_message_prefix = '';
$message = $message->getMessage();
}
 
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
if ($exp[0] == "*" ||
(is_int(reset($exp)) && in_array($code, $exp)) ||
(is_string(reset($exp)) && in_array($message, $exp))) {
$mode = PEAR_ERROR_RETURN;
}
}
// No mode given, try global ones
if ($mode === null) {
// Class error handler
if (isset($this) && isset($this->_default_error_mode)) {
$mode = $this->_default_error_mode;
$options = $this->_default_error_options;
// Global error handler
} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
$mode = $GLOBALS['_PEAR_default_error_mode'];
$options = $GLOBALS['_PEAR_default_error_options'];
}
}
 
if ($error_class !== null) {
$ec = $error_class;
} elseif (isset($this) && isset($this->_error_class)) {
$ec = $this->_error_class;
} else {
$ec = 'PEAR_Error';
}
if ($skipmsg) {
$a = &new $ec($code, $mode, $options, $userinfo);
return $a;
} else {
$a = &new $ec($message, $code, $mode, $options, $userinfo);
return $a;
}
}
 
// }}}
// {{{ throwError()
 
/**
* Simpler form of raiseError with fewer options. In most cases
* message, code and userinfo are enough.
*
* @param string $message
*
*/
function &throwError($message = null,
$code = null,
$userinfo = null)
{
if (isset($this) && is_a($this, 'PEAR')) {
$a = &$this->raiseError($message, $code, null, null, $userinfo);
return $a;
} else {
$a = &PEAR::raiseError($message, $code, null, null, $userinfo);
return $a;
}
}
 
// }}}
function staticPushErrorHandling($mode, $options = null)
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
$def_options = &$GLOBALS['_PEAR_default_error_options'];
$stack[] = array($def_mode, $def_options);
switch ($mode) {
case PEAR_ERROR_EXCEPTION:
case PEAR_ERROR_RETURN:
case PEAR_ERROR_PRINT:
case PEAR_ERROR_TRIGGER:
case PEAR_ERROR_DIE:
case null:
$def_mode = $mode;
$def_options = $options;
break;
 
case PEAR_ERROR_CALLBACK:
$def_mode = $mode;
// class/object method callback
if (is_callable($options)) {
$def_options = $options;
} else {
trigger_error("invalid error callback", E_USER_WARNING);
}
break;
 
default:
trigger_error("invalid error mode", E_USER_WARNING);
break;
}
$stack[] = array($mode, $options);
return true;
}
 
function staticPopErrorHandling()
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
array_pop($stack);
list($mode, $options) = $stack[sizeof($stack) - 1];
array_pop($stack);
switch ($mode) {
case PEAR_ERROR_EXCEPTION:
case PEAR_ERROR_RETURN:
case PEAR_ERROR_PRINT:
case PEAR_ERROR_TRIGGER:
case PEAR_ERROR_DIE:
case null:
$setmode = $mode;
$setoptions = $options;
break;
 
case PEAR_ERROR_CALLBACK:
$setmode = $mode;
// class/object method callback
if (is_callable($options)) {
$setoptions = $options;
} else {
trigger_error("invalid error callback", E_USER_WARNING);
}
break;
 
default:
trigger_error("invalid error mode", E_USER_WARNING);
break;
}
return true;
}
 
// {{{ pushErrorHandling()
 
/**
* Push a new error handler on top of the error handler options stack. With this
* you can easily override the actual error handler for some code and restore
* it later with popErrorHandling.
*
* @param mixed $mode (same as setErrorHandling)
* @param mixed $options (same as setErrorHandling)
*
* @return bool Always true
*
* @see PEAR::setErrorHandling
*/
function pushErrorHandling($mode, $options = null)
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
if (isset($this) && is_a($this, 'PEAR')) {
$def_mode = &$this->_default_error_mode;
$def_options = &$this->_default_error_options;
} else {
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
$def_options = &$GLOBALS['_PEAR_default_error_options'];
}
$stack[] = array($def_mode, $def_options);
 
if (isset($this) && is_a($this, 'PEAR')) {
$this->setErrorHandling($mode, $options);
} else {
PEAR::setErrorHandling($mode, $options);
}
$stack[] = array($mode, $options);
return true;
}
 
// }}}
// {{{ popErrorHandling()
 
/**
* Pop the last error handler used
*
* @return bool Always true
*
* @see PEAR::pushErrorHandling
*/
function popErrorHandling()
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
array_pop($stack);
list($mode, $options) = $stack[sizeof($stack) - 1];
array_pop($stack);
if (isset($this) && is_a($this, 'PEAR')) {
$this->setErrorHandling($mode, $options);
} else {
PEAR::setErrorHandling($mode, $options);
}
return true;
}
 
// }}}
// {{{ loadExtension()
 
/**
* OS independant PHP extension load. Remember to take care
* on the correct extension name for case sensitive OSes.
*
* @param string $ext The extension name
* @return bool Success or not on the dl() call
*/
function loadExtension($ext)
{
if (!extension_loaded($ext)) {
// if either returns true dl() will produce a FATAL error, stop that
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
return false;
}
if (OS_WINDOWS) {
$suffix = '.dll';
} elseif (PHP_OS == 'HP-UX') {
$suffix = '.sl';
} elseif (PHP_OS == 'AIX') {
$suffix = '.a';
} elseif (PHP_OS == 'OSX') {
$suffix = '.bundle';
} else {
$suffix = '.so';
}
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
}
return true;
}
 
// }}}
}
 
// {{{ _PEAR_call_destructors()
 
function _PEAR_call_destructors()
{
global $_PEAR_destructor_object_list;
if (is_array($_PEAR_destructor_object_list) &&
sizeof($_PEAR_destructor_object_list))
{
reset($_PEAR_destructor_object_list);
if (PEAR::getStaticProperty('PEAR', 'destructlifo')) {
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
}
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
$classname = get_class($objref);
while ($classname) {
$destructor = "_$classname";
if (method_exists($objref, $destructor)) {
$objref->$destructor();
break;
} else {
$classname = get_parent_class($classname);
}
}
}
// Empty the object list to ensure that destructors are
// not called more than once.
$_PEAR_destructor_object_list = array();
}
 
// Now call the shutdown functions
if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
call_user_func_array($value[0], $value[1]);
}
}
}
 
// }}}
/**
* Standard PEAR error class for PHP 4
*
* This class is supserseded by {@link PEAR_Exception} in PHP 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Gregory Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/manual/en/core.pear.pear-error.php
* @see PEAR::raiseError(), PEAR::throwError()
* @since Class available since PHP 4.0.2
*/
class PEAR_Error
{
// {{{ properties
 
var $error_message_prefix = '';
var $mode = PEAR_ERROR_RETURN;
var $level = E_USER_NOTICE;
var $code = -1;
var $message = '';
var $userinfo = '';
var $backtrace = null;
 
// }}}
// {{{ constructor
 
/**
* PEAR_Error constructor
*
* @param string $message message
*
* @param int $code (optional) error code
*
* @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
* PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
*
* @param mixed $options (optional) error level, _OR_ in the case of
* PEAR_ERROR_CALLBACK, the callback function or object/method
* tuple.
*
* @param string $userinfo (optional) additional user/debug info
*
* @access public
*
*/
function PEAR_Error($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null)
{
if ($mode === null) {
$mode = PEAR_ERROR_RETURN;
}
$this->message = $message;
$this->code = $code;
$this->mode = $mode;
$this->userinfo = $userinfo;
if (!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
$this->backtrace = debug_backtrace();
if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
unset($this->backtrace[0]['object']);
}
}
if ($mode & PEAR_ERROR_CALLBACK) {
$this->level = E_USER_NOTICE;
$this->callback = $options;
} else {
if ($options === null) {
$options = E_USER_NOTICE;
}
$this->level = $options;
$this->callback = null;
}
if ($this->mode & PEAR_ERROR_PRINT) {
if (is_null($options) || is_int($options)) {
$format = "%s";
} else {
$format = $options;
}
printf($format, $this->getMessage());
}
if ($this->mode & PEAR_ERROR_TRIGGER) {
trigger_error($this->getMessage(), $this->level);
}
if ($this->mode & PEAR_ERROR_DIE) {
$msg = $this->getMessage();
if (is_null($options) || is_int($options)) {
$format = "%s";
if (substr($msg, -1) != "\n") {
$msg .= "\n";
}
} else {
$format = $options;
}
die(sprintf($format, $msg));
}
if ($this->mode & PEAR_ERROR_CALLBACK) {
if (is_callable($this->callback)) {
call_user_func($this->callback, $this);
}
}
if ($this->mode & PEAR_ERROR_EXCEPTION) {
trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
eval('$e = new Exception($this->message, $this->code);throw($e);');
}
}
 
// }}}
// {{{ getMode()
 
/**
* Get the error mode from an error object.
*
* @return int error mode
* @access public
*/
function getMode() {
return $this->mode;
}
 
// }}}
// {{{ getCallback()
 
/**
* Get the callback function/method from an error object.
*
* @return mixed callback function or object/method array
* @access public
*/
function getCallback() {
return $this->callback;
}
 
// }}}
// {{{ getMessage()
 
 
/**
* Get the error message from an error object.
*
* @return string full error message
* @access public
*/
function getMessage()
{
return ($this->error_message_prefix . $this->message);
}
 
 
// }}}
// {{{ getCode()
 
/**
* Get error code from an error object
*
* @return int error code
* @access public
*/
function getCode()
{
return $this->code;
}
 
// }}}
// {{{ getType()
 
/**
* Get the name of this error/exception.
*
* @return string error/exception name (type)
* @access public
*/
function getType()
{
return get_class($this);
}
 
// }}}
// {{{ getUserInfo()
 
/**
* Get additional user-supplied information.
*
* @return string user-supplied information
* @access public
*/
function getUserInfo()
{
return $this->userinfo;
}
 
// }}}
// {{{ getDebugInfo()
 
/**
* Get additional debug information supplied by the application.
*
* @return string debug information
* @access public
*/
function getDebugInfo()
{
return $this->getUserInfo();
}
 
// }}}
// {{{ getBacktrace()
 
/**
* Get the call backtrace from where the error was generated.
* Supported with PHP 4.3.0 or newer.
*
* @param int $frame (optional) what frame to fetch
* @return array Backtrace, or NULL if not available.
* @access public
*/
function getBacktrace($frame = null)
{
if (defined('PEAR_IGNORE_BACKTRACE')) {
return null;
}
if ($frame === null) {
return $this->backtrace;
}
return $this->backtrace[$frame];
}
 
// }}}
// {{{ addUserInfo()
 
function addUserInfo($info)
{
if (empty($this->userinfo)) {
$this->userinfo = $info;
} else {
$this->userinfo .= " ** $info";
}
}
 
// }}}
// {{{ toString()
 
/**
* Make a string representation of this object.
*
* @return string a string with an object summary
* @access public
*/
function toString() {
$modes = array();
$levels = array(E_USER_NOTICE => 'notice',
E_USER_WARNING => 'warning',
E_USER_ERROR => 'error');
if ($this->mode & PEAR_ERROR_CALLBACK) {
if (is_array($this->callback)) {
$callback = (is_object($this->callback[0]) ?
strtolower(get_class($this->callback[0])) :
$this->callback[0]) . '::' .
$this->callback[1];
} else {
$callback = $this->callback;
}
return sprintf('[%s: message="%s" code=%d mode=callback '.
'callback=%s prefix="%s" info="%s"]',
strtolower(get_class($this)), $this->message, $this->code,
$callback, $this->error_message_prefix,
$this->userinfo);
}
if ($this->mode & PEAR_ERROR_PRINT) {
$modes[] = 'print';
}
if ($this->mode & PEAR_ERROR_TRIGGER) {
$modes[] = 'trigger';
}
if ($this->mode & PEAR_ERROR_DIE) {
$modes[] = 'die';
}
if ($this->mode & PEAR_ERROR_RETURN) {
$modes[] = 'return';
}
return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
'prefix="%s" info="%s"]',
strtolower(get_class($this)), $this->message, $this->code,
implode("|", $modes), $levels[$this->level],
$this->error_message_prefix,
$this->userinfo);
}
 
// }}}
}
 
/*
* Local Variables:
* mode: php
* tab-width: 4
* c-basic-offset: 4
* End:
*/
?>
/tags/v1.0-Homere/bibliotheque/noyau/aControlleurAction.class.php
New file
0,0 → 1,95
<?php
 
abstract class aControlleurAction {
 
private $suivant;
 
public function getRegistre()
{
return Registre::getRegistre();
}
 
// Suivant
public function getSuivant()
{
return $this->suivant;
}
public function setSuivant($s, $position = null)
{
if (is_array($s)){
$this->suivant = $s;
} else {
if (!is_null($position)) {
$tab_fin = array_slice($this->suivant, $position);
$tab_deb = array_slice($this->suivant, 0, $position);
$this->suivant = array_merge($tab_deb, array($s), $tab_fin);
} else {
$this->suivant[] = $s;
}
}
}
 
public function demarrer()
{
if (!is_null($this->getSuivant())) {
// ATTENTION :
// Il est important de laisser "count($this->getSuivant())" $this->getSuivant() peut varier de taille
for ($i = 0; $i < count($this->getSuivant()) ; $i++) {
//echo '<pre>'.print_r($this->getSuivant(), true).'</pre>';
if ($this->getRegistre()->get('action_finale')) {
// Si l'action met fin au script prématurément nous arrétons
break;
} else {
$liste_actions = $this->getSuivant();
//echo '<pre>'.print_r($liste_actions[$i], true).'</pre>';
if ($liste_actions[$i] instanceof aControlleurAction) {
$liste_actions[$i]->demarrer();
} else {
if (isset($_POST) || isset($_GET)) {
// Méthode "vérifier" générale présente dans aControlleurAction
$this->verifier();
$methode_verif = 'verifier'.$liste_actions[$i];
if (method_exists($this, $methode_verif)) {
// Méthode "vérifier" spécifique à une action
$this->$methode_verif();
}
}
if ($liste_actions[$i] == '__defaut__') {
$methode = 'executer';
} else {
$methode = 'executer'.$liste_actions[$i];
}
if (method_exists($this, $methode)) {
$this->$methode();
} else {
$m = "La méthode $methode de la classe ".get_class($this)." est introuvable!";
trigger_error($m, E_USER_ERROR);
}
}
}
}
} else {
$m = "Le registre ne contient aucune action!";
trigger_error($m, E_USER_ERROR);
}
}
 
public function verifier()
{
// Nous rassemblons les valeurs du tableau _POST contenant des : dans des sous-tableau de _POST.
foreach ($_POST as $cle => $val) {
$morceau = array();
if (preg_match('/^(.+?)(:.+)+$/', $cle, $morceau)) {
$table = '';
foreach (explode(':', trim($morceau[2], ':')) as $c) {
$table .= '['.$c.']';
}
eval('$_POST[$morceau[1]]'.$table.' = $val;');
unset($_POST[$cle]);
}
}
}
 
abstract protected function executer();
}
?>
/tags/v1.0-Homere/bibliotheque/noyau/GestionnaireErreur.class.php
New file
0,0 → 1,423
<?php
/*vim: set expandtab tabstop=4 shiftwidth=4: */
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.0.4 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2005 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore-Debogage. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id: GestionnaireErreur.class.php,v 1.6 2007-07-09 18:54:43 jp_milcent Exp $
/**
* Classe de gestion des erreurs.
*
*
*
*@package eFlore
*@subpackage Debogage
//Auteur original :
*@author Jean-Pascal MILCENT <jpm@tela-botanica.org>
//Autres auteurs :
*@author aucun
*@copyright Tela-Botanica 2000-2005
*@version $Revision: 1.6 $ $Date: 2007-07-09 18:54:43 $
// +------------------------------------------------------------------------------------------------------+
*/
 
// +------------------------------------------------------------------------------------------------------+
// | ENTETE du PROGRAMME |
// +------------------------------------------------------------------------------------------------------+
 
 
// +------------------------------------------------------------------------------------------------------+
// | CORPS du PROGRAMME |
// +------------------------------------------------------------------------------------------------------+
 
 
/**
* Classe GestionnaireErreur
*
* Gérer les erreurs PHP et SQL.
*/
class GestionnaireErreur
{
/*** Attributes: ***/
 
/**
* Permet de savoir si on utilise PHP en ligne de commande dans une console (PHP-CLI) ou en mode module de serveur.
* @access private
*/
private $mode;
 
/**
* Contient la liste des erreurs.
* @access private
*/
private $erreurs;
 
/**
* Permet de savoir si on veut faire apparaître ou pas le contexte de l'erreur,
* c'est à dire le contenu des variables.
* @access private
*/
private $contexte;
/**
* Contient le niveau d'erreur courrant. Celui que l'on donne à la fonction
* error_reporting().
* @access private
*/
private $niveau_erreur_courrant;
/*** Constructeur: ***/
/**
* Construit le gestionnaire d'erreur.
*
* @return void
* @access public
*/
public function __construct( $contexte = false )
{
$this->mode = php_sapi_name();
$this->erreurs = array();
$this->setContexte($contexte);
set_error_handler(array(&$this, 'gererErreur'));
}
/*** Accesseurs: ***/
// end of member function __construct
/**
* Récupère le tableau des erreurs.
*
* @return array
* @access public
*/
public function getErreur( ) {
return $this->erreurs;
}
 
/**
* Ajoute une erreur à la liste.
*
* @param array une_erreur
* @return void
* @access public
*/
public function setErreur( $une_erreur ) {
$this->erreurs[] = $une_erreur;
}
 
/**
* Récupère la valeur du contexte.
*
* @return boolean
* @access public
*/
public function getContexte( ) {
return $this->contexte;
}
 
/**
* Définit si oui ou non le contexte sera affiché.
*
* @param boolean un_contexte
* @return void
* @access public
*/
public function setContexte( $un_contexte ) {
$this->contexte = $un_contexte;
}
/**
* Récupère le niveau d'erreur courrant.
*
* @return int le niveau d'erreur courrant.
* @access public
*/
public function getNiveauErreurCourrant( ) {
return (int)$this->niveau_erreur_courrant;
}
 
/**
* Définit le niveau d'erreur courrant.
*
* @param int un niveau d'erreur.
* @return void
* @access public
*/
public function setNiveauErreurCourrant( $niveau = 2048 ) {
$this->niveau_erreur_courrant = $niveau;
}
/**
* Définit le niveau d'erreur courrant (synonyme fonction precedente)
*
* @param int un niveau d'erreur.
* @return void
* @access public
*/
public function setActive ($niveau) {
$this->niveau_erreur_courrant = $niveau;
}
/*** Méthodes : ***/
/**
*
* @param int niveau
* @param string message
* @param string fichier
* @param int ligne
* @param boolean contexte
* @return void
* @access public
*/
public function gererErreur($niveau, $message, $fichier, $ligne, $contexte)
{
$aso_erreur = array();
// Nous vérifions si nous affichons ou pas l'erreur en fonction du niveau demandé
if ( $niveau <= $this->getNiveauErreurCourrant() ) {
$aso_erreur['niveau'] = $niveau;
$aso_erreur['message'] = $message;
$aso_erreur['fichier'] = $fichier;
$aso_erreur['ligne'] = $ligne;
if ($this->getContexte()) {
$aso_erreur['contexte'] = $contexte;
}
$this->setErreur($aso_erreur);
}
// Si nous avons à faire à une erreur et non à un warning ou une notice, nous arrêtons l'exécution du script
switch ($niveau) {
case E_ERROR :
case E_USER_ERROR :
die($this->retournerErreur());
break;
}
}
 
/**
* Retourne l'erreur PHP formatée en XHTML.
*
* @return string
* @access public
*/
public function retournerErreur()
{
$retour = '';
$erreur_pear_nbre = 0;
$erreur_pear_fichier_nbre = 0;
$erreur_pear_message_nbre = 0;
foreach($this->getErreur() as $aso_erreur) {
if ('<!-- BEGIN sql -->' == substr($aso_erreur['message'], 0, 18)) {
$retour .= $aso_erreur['message'];
continue;
}
// Nous testons les erreurs PEAR pour ne pas en tenir compte
if (!GTT_DEBOGAGE_PEAR && preg_match(GTT_DEBOGAGE_PEAR_REGEXP_CHAINE, $aso_erreur['fichier'])) {
$erreur_pear_fichier_nbre++;
} else if (!GTT_DEBOGAGE_PEAR && preg_match(GTT_DEBOGAGE_PEAR_REGEXP_MESSAGE, $aso_erreur['message'])) {
$erreur_pear_message_nbre++;
} else {
switch ($this->mode) {
case 'cli' :
if ($aso_erreur['niveau'] == E_USER_NOTICE) {
$retour .= $aso_erreur['message']."\n";
$retour .= 'Fichier : '.$aso_erreur['fichier']."\n";
$retour .= 'Ligne : '.$aso_erreur['ligne']."\n";
} else if ($aso_erreur['niveau'] <= 512) {
$retour .= 'INFO : Niveau '.$aso_erreur['niveau']."\n";
} else {
$retour .= 'ERREUR : Niveau '.$aso_erreur['niveau']."\n";
}
$retour .= 'Niveau : '.$aso_erreur['niveau']."\n";
$retour .= 'Message : '.$aso_erreur['message']."\n";
$retour .= 'Fichier : '.$aso_erreur['fichier']."\n";
$retour .= 'Ligne : '.$aso_erreur['ligne']."\n";
if ($this->getContexte()) {
$retour .= 'Contexte : '."\n".print_r($aso_erreur['contexte'], true)."\n";
}
break;
default:
if ($aso_erreur['niveau'] == E_USER_NOTICE) {
$retour .= '<pre class="debogage">'."\n";
$retour .= $aso_erreur['message']."\n";
$retour .= '<span class="debogage_fichier">'.'Fichier : '.$aso_erreur['fichier'].'</span>'."\n";
$retour .= '<span class="debogage_ligne">'.'Ligne : '.$aso_erreur['ligne'].'</span>'."\n";
$retour .= '</pre>'."\n";
continue;
} else if ($aso_erreur['niveau'] <= 512) {
$retour .= '<p class="information">'."\n";
$retour .= '<strong>INFO : Niveau '.$aso_erreur['niveau'].'</strong><br />'."\n";
} else {
$retour .= '<p class="attention">'."\n";
$retour .= '<strong>ERREUR : Niveau '.$aso_erreur['niveau'].'</strong><br />'."\n";
}
$retour .= '<strong>Niveau : </strong>'.$aso_erreur['niveau'].'<br />'."\n";
$retour .= '<strong>Message : </strong>'.$aso_erreur['message'].'<br />'."\n";
$retour .= '<strong>Fichier : </strong>'.$aso_erreur['fichier'].'<br />'."\n";
$retour .= '<strong>Ligne : </strong>'.$aso_erreur['ligne'].'<br />'."\n";
if ($this->getContexte()) {
$retour .= '<pre>'."\n";
$retour .= '<stong>Contexte : </stong>'."\n".print_r($aso_erreur['contexte'], true)."\n";
$retour .= '</pre>'."\n";
}
$retour .= '</p>'."\n";
}
}
}
$erreur_pear_nbre = $erreur_pear_fichier_nbre + $erreur_pear_message_nbre;
if ($erreur_pear_nbre != 0) {
$retour .= '<p class="attention">'.
'<strong>Nombre d\'erreurs PEAR totales : </strong>'.$erreur_pear_nbre.'<br />'."\n".
'<strong> - éliminées car le "fichier" correspondé à '.GTT_DEBOGAGE_PEAR_REGEXP_CHAINE.' : </strong>'.$erreur_pear_fichier_nbre.'<br />'."\n".
'<strong> - éliminées car le "message" correspondé à '.GTT_DEBOGAGE_PEAR_REGEXP_MESSAGE.' : </strong>'.$erreur_pear_message_nbre.'<br />'."\n".
'</p>'."\n";
}
return $retour;
}
 
/**
* Retourne l'erreur SQL formatée en XHTML.
*
* @param string fichier
* @param int ligne
* @param string message
* @param string requete
* @param string autres
* @return string
* @static
* @access public
*/
public static function retournerErreurSql( $fichier, $methode, $message, $requete = null, $autres = null )
{
$retour = '';
switch (php_sapi_name()) {
case 'cli' :
$retour .= 'ERREUR SQL '."\n";
$retour .= 'Fichier : '.$fichier."\n";
$retour .= 'Méthode : '.$methode."\n";
$retour .= 'Message : '.$message."\n";
if (!is_null($requete)) {
$retour .= 'Requete : '."\n";
$retour .= $requete."\n";
}
if (!is_null($autres)) {
$retour .= 'Autres infos : '."\n";
$retour .= $autres."\n";
}
break;
default:
$retour .= '<!-- BEGIN sql -->';
$retour .= '<div id="zone_erreur">'."\n";
$retour .= '<h1 > ERREUR SQL </h1><br />'."\n";
$retour .= '<dl>'."\n";
$retour .= '<dt> Fichier : </dt> ';
$retour .= '<dd> '.$fichier.'</dd>'."\n";
$retour .= '<dt> Méthode : </dt> ';
$retour .= '<dd> '.$methode.'</dd>'."\n";
$retour .= '<dt> Message erreur : </dt> ';
$retour .= '<dd> '.$message.'</dd>'."\n";
if (!is_null($requete)) {
$retour .= '<dt> Requete : </dt> ';
$retour .= '<dd> '.$requete.' </dd>'."\n";
}
if (!is_null($autres)) {
$retour .= '<dt> Autres infos : </dt> ';
$retour .= '<dd> '.$autres.' </dd>'."\n";
}
$retour .= '</dl>'."\n";
$retour .= '</div>'."\n";
$retour .= '<!-- END sql -->'."\n";
}
return $retour;
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log: GestionnaireErreur.class.php,v $
* Revision 1.6 2007-07-09 18:54:43 jp_milcent
* Remplacement des balises html par des entités pour le message des E_USER_NOTICE.
*
* Revision 1.5 2007-07-02 15:31:53 jp_milcent
* Initialisation d'une variable.
*
* Revision 1.4 2007-07-02 12:43:09 jp_milcent
* Gestion de php-cli ou cgi...
*
* Revision 1.3 2007-07-02 10:50:06 jp_milcent
* Ajout de la gestion du mode d'affichage (xhtml ou txt).
*
* Revision 1.2 2007-01-15 15:30:03 jp_milcent
* Amélioration du gestionnaire d'erreur pour qu'il prenne en compte les erreurs Pear des méthodes "non static"...
*
* Revision 1.1 2007/01/12 13:16:09 jp_milcent
* Déplacement des classes de débogage et d'optimisation dans le dossier noyau.
*
* Revision 1.9 2006/10/25 08:15:23 jp_milcent
* Fusion avec la livraison Decaisne.
*
* Revision 1.8.2.1 2006/08/29 09:22:37 jp_milcent
* Correction et amélioration du gestionnaire d'erreurs.
*
* Revision 1.8 2006/07/20 13:33:46 jp_milcent
* Légère modif affichage.
*
* Revision 1.7 2006/07/20 13:33:03 jp_milcent
* Amélioration du gestionnaire d'erreur.
*
* Revision 1.6 2006/07/20 13:27:07 jp_milcent
* Ajout du type information.
*
* Revision 1.5 2006/05/29 13:52:41 ddelon
* Integration wiki dans eflore
*
* Revision 1.4 2005/12/09 10:47:05 jp_milcent
* Amélioration du Gestionnaire de Bogues.
*
* Revision 1.3 2005/10/10 07:28:07 jp_milcent
* Utilisation du webservice Yahoo-Image.
*
* Revision 1.2 2005/10/04 16:34:03 jp_milcent
* Début gestion de la chorologie.
* Ajout de la bibliothèque de cartographie (à améliorer!).
*
* Revision 1.1 2005/08/04 15:51:45 jp_milcent
* Implémentation de la gestion via DAO.
* Fin page d'accueil.
* Fin formulaire recherche taxonomique.
*
* Revision 1.3 2005/08/02 16:19:33 jp_milcent
* Amélioration des requetes de recherche de noms.
*
* Revision 1.2 2005/08/01 16:18:39 jp_milcent
* Début gestion résultat de la recherche par nom.
*
* Revision 1.1 2005/07/28 15:37:56 jp_milcent
* Début gestion des squelettes et de l'API eFlore.
*
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/noyau/ControlleurFrontal.class.php
New file
0,0 → 1,161
<?php
 
class ControlleurFrontal {
 
private $url_action;
private $url_format;
private $url_sortie;
 
public function __construct($action, $format, $sortie)
{
$this->url_action = $action;
$this->url_format = $format;
$this->url_sortie = $sortie;
}
public function getRegistre()
{
return Registre::getRegistre();
}
 
public function parserAction($url)
{
if (preg_match('/^(.+?)(?:_(.+)|)$/', $url, $match)) {
$aso_compo_classe = explode('-', $match[1]);
$retour['classe_action'] = 'GttCtrlAction';
foreach ($aso_compo_classe as $mot) {
$retour['classe_action'] .= ucfirst($mot);
}
}
 
$retour['tab_actions'] = array('__defaut__');
if (isset($match[2])) {
preg_match_all('/(.+)(?:_|$)/', $match[2], $match_actions);
//echo '<pre>'.print_r($match_actions[1], true).'</pre>';
foreach ($match_actions[1] as $action) {
$aso_compo_action = explode('-', $action);
$action = '';
foreach ($aso_compo_action as $mot_action) {
$action .= ucfirst($mot_action);
}
$retour['tab_actions'][] = $action;
}
}
return $retour;
}
 
private function chargerActionGenerique(&$tab_actions)
{
// Gestion de l'identification
$GttCtrlActionIdentification = new GttCtrlActionIdentification($this->getRegistre());
$GttCtrlActionIdentification->setSuivant('__defaut__');
array_unshift($tab_actions, $GttCtrlActionIdentification);
 
// Gestion des menus
$GttCtrlActionMenu = new GttCtrlActionMenu($this->getRegistre());
$GttCtrlActionMenu->setSuivant('__defaut__');
$tab_actions[] = $GttCtrlActionMenu;
}
 
 
public function executer()
{
$tab_info_url = $this->parserAction($this->url_action);
//trigger_error(print_r($tab_info_url, true), E_USER_NOTICE);
$classe_action = $tab_info_url['classe_action'];
$fichier_action = GTT_CHEMIN_ACTION.$classe_action.'.class.php';
if (file_exists($fichier_action)) {
require_once $fichier_action;
$Action = new $classe_action($this->getRegistre());
$this->chargerActionGenerique(&$tab_info_url['tab_actions']);
$Action->setSuivant($tab_info_url['tab_actions']);
$Action->demarrer();
if ($this->url_format == 'html') {
$aso_principal['principal'] = $this->rendre();
//echo '<pre>'.print_r($aso_principal, true).'</pre>';
$aso_principal['principal']['titre'] = $this->getRegistre()->getTitre();
$this->getRegistre()->setEspaces(array());
$this->getRegistre()->setDonnees(array());
$this->getRegistre()->ajouterEspace('Principal', 'principal');
$this->getRegistre()->ajouterDonnee('principal', $aso_principal['principal']);
}
$sortie = $this->rendre();
 
// Gestion de la sortie
switch ($this->url_sortie) {
case 'html' :
echo $sortie;
break;
case 'csv' :
header('Content-Disposition: inline' );
header('Content-Type: text/plain');
header('Content-Length: '.strlen($sortie));
echo $sortie;
break;
case 'csvt' :
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="'.str_replace(' ', '_', $this->getRegistre()->getTitre()).'.csv";' );
header('Content-Length: '.strlen($sortie));
echo $sortie;
break;
}
exit();
} else {
$m = "Le fichier $fichier_action contenant l'action est introuvable!";
trigger_error($m, E_USER_ERROR);
}
}
 
public function rendre()
{
$contenu_principal = null;
$aso_contenu = array('zone_contenu' => '', 'zone_menu' => '', 'zone_identification' => '', 'zone_calendrier' => '');
foreach ($this->getRegistre()->getEspaces() as $espace_de_nom) {
if (is_array($this->getRegistre()->getDonnees($espace_de_nom))) {
$squelette = $espace_de_nom;
if (false != $this->getRegistre()->getSquelettes($espace_de_nom)) {
$squelette = $this->getRegistre()->getSquelettes($espace_de_nom);
}
$fichier_squelette = GTT_CHEMIN_PRESENTATION.$squelette.'.tpl.'.$this->url_format;
$squelette_erreur = $fichier_squelette;
if (file_exists($fichier_squelette)) {
$bool_squelette_erreur = false;
ob_start();
extract($GLOBALS['_GTT_']['i18n']['general'], EXTR_PREFIX_ALL, 'i18n_general');
extract($this->getRegistre()->getDonnees($espace_de_nom));
include_once $fichier_squelette;
if ($this->url_format == 'html') {
// Répartition dans des zones
switch($espace_de_nom) {
case 'principal' :
$contenu_principal .= ob_get_contents();
break;
case 'zone_calendrier' :
$aso_contenu['zone_calendrier'] .= ob_get_contents();
break;
case 'identification' :
$aso_contenu['zone_identification'] .= ob_get_contents();
break;
case 'zone_menu' :
$aso_contenu['zone_menu'] .= ob_get_contents();
break;
default:
$aso_contenu['zone_contenu'] .= ob_get_contents();
}
} else {
$contenu_principal = ob_get_contents();
}
ob_end_clean();
}
}
}
if ($bool_squelette_erreur) {
trigger_error("Absence du fichier de squelette : $squelette_erreur", E_USER_ERROR);
}
if (!is_null($contenu_principal)) {
return $contenu_principal;
}
return $aso_contenu;
}
}
?>
/tags/v1.0-Homere/bibliotheque/noyau/Registre.class.php
New file
0,0 → 1,130
<?php
 
class Registre {
private $aso_stock = array();
private static $registre = null;
private $suivant;
private $titre;
private $espaces = array();
private $donnees = array();
private $squelettes;
 
public static function getRegistre()
{
if (is_null(Registre::$registre)) {
Registre::$registre = new Registre;
}
return Registre::$registre;
}
 
function set($intitule, $objet)
{
if (is_array($objet) && isset($this->aso_stock[$intitule])) {
$this->aso_stock[$intitule] = array_merge((array)$this->aso_stock[$intitule], (array)$objet);
$message = "Le tableau $intitule présent dans le registre a été fusionné avec un nouveau tableau de même intitulé !";
trigger_error($message, E_USER_WARNING);
} else {
$this->aso_stock[$intitule] = $objet;
}
}
 
function get($intitule)
{
if (isset($this->aso_stock[$intitule])) {
return $this->aso_stock[$intitule];
}
return false;
}
 
function detruire($intitule)
{
if (isset($this->aso_stock[$intitule])) {
unset($this->aso_stock[$intitule]);
}
}
 
public function etrePresent($intitule)
{
if(isset($this->aso_stock[$intitule])){
return true;
}
return false;
}
 
// Titre
public function getTitre()
{
return $this->titre;
}
public function setTitre($t)
{
$this->titre = $t;
}
 
// Espaces De Nomage
public function setEspaces($e)
{
$this->espaces = $e;
}
public function ajouterEspace($cle, $val)
{
$this->espaces[$cle] = $val;
}
public function getEspaces($cle = null)
{
if ($cle != null) {
if (isset($this->espaces[$cle])) {
return $this->espaces[$cle];
}
} else {
return $this->espaces;
}
}
 
// Donnees
public function setDonnees($d)
{
$this->donnees = $d;
}
public function ajouterDonnee($cle, $val)
{
if (is_array($val) && isset($this->donnees[$cle])) {
$this->donnees[$cle] = array_merge((array)$this->donnees[$cle], $val);
trigger_error('Fusion de données pour la clé : '. $cle, E_USER_NOTICE);
} else {
$this->donnees[$cle] = $val;
}
}
public function getDonnees($cle = null)
{
if (!is_null($cle)) {
if (isset($this->donnees[$cle])) {
return $this->donnees[$cle];
}
} else {
return $this->donnees;
}
}
 
// Squelettes
public function setSquelettes($s)
{
$this->squelettes = $s;
}
public function ajouterSquelette($cle, $val)
{
$this->squelettes[$cle] = $val;
}
public function getSquelettes($cle = null)
{
if ($cle != null) {
if (isset($this->squelettes[$cle])) {
return $this->squelettes[$cle];
}
return false;
} else {
return $this->squelettes;
}
}
}
?>
/tags/v1.0-Homere/bibliotheque/noyau/Chronometre.class.php
New file
0,0 → 1,187
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.0.4 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2005 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore-Debogage. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id: Chronometre.class.php,v 1.1 2007-01-12 13:16:09 jp_milcent Exp $
/**
* Classe permettant de mesurer le temps d'execution d'un script.
*
* Contient des méthodes permettant d'évaluer la vitesse d'exécution d'un script.
*
*@package eFlore
*@subpackage Debogage
//Auteur original :
*@author Jean-Pascal MILCENT <jpm@tela-botanica.org>
//Autres auteurs :
*@author aucun
*@copyright Tela-Botanica 2000-2005
*@version $Revision: 1.1 $ $Date: 2007-01-12 13:16:09 $
// +------------------------------------------------------------------------------------------------------+
*/
 
// +------------------------------------------------------------------------------------------------------+
// | ENTETE du PROGRAMME |
// +------------------------------------------------------------------------------------------------------+
 
 
// +------------------------------------------------------------------------------------------------------+
// | CORPS du PROGRAMME |
// +------------------------------------------------------------------------------------------------------+
/**Classe Chronometre() - Permet de stocker et d'afficher les temps d'éxécution de script.
*
* Cette classe permet de réaliser un ensemble de mesure de temps prises à
* différents endroits d'un script. Ces mesures peuvent ensuite être affichées au
* sein d'un tableau XHTML.
*
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
*/
class Chronometre
{
/*** Attributs : ***/
private $temps = array();
private $temps_sql = 0;
/*** Constructeur : ***/
public function __construct() {
$this->setTemps(array('depart' => microtime()));
}
/*** Accesseurs : ***/
// Temps
public function getTemps($cle = NULL) {
if (!is_null($cle)) {
return $this->temps[$cle];
} else {
return $this->temps;
}
}
public function setTemps($moment = array()) {
array_push($this->temps, $moment);
}
 
// Temps Sql
// Notes : utiliser microtime(true) pour renvoyer un float
public function getTempsSql() {
return $this->temps_sql;
}
public function setTempsSql($tps_deb, $tps_fin = null) {
if (is_null($tps_fin)) {
if (is_float($tps_deb)) {
$this->temps_sql += $tps_deb;
}
} else {
if (is_float($tps_deb) && is_float($tps_fin)) {
$this->temps_sql += $tps_fin - $tps_deb;
}
}
}
/*** Méthodes : ***/
/**Méthode afficherChrono() - Permet d'afficher les temps d'éxécution de différentes parties d'un script.
*
* Cette fonction permet d'afficher un ensemble de mesure de temps prises à différents endroits d'un script.
* Ces mesures sont affichées au sein d'un tableau XHTML dont on peut controler l'indentation des balises.
* Pour un site en production, il suffit d'ajouter un style #chrono {display:none;} dans la css. De cette façon,
* le tableau ne s'affichera pas. Le webmaster lui pourra rajouter sa propre feuille de style affichant le tableau.
* Le développeur initial de cette fonction est Loic d'Anterroches. Elle a été modifiée par Jean-Pascal Milcent.
* Elle utilise une variable gobale : $_CHRONO_
*
* @author Loic d'Anterroches
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @param int l'indentation de base pour le code html du tableau.
* @param int le pas d'indentation pour le code html du tableau.
* @return string la chaine XHTML de mesure des temps.
*/
function afficherChrono($indentation_origine = 8, $indentation = 4) {
// Création du chrono de fin
$GLOBALS['_EFLORE_']['chrono']->setTemps(array('fin' => microtime()));
 
// Début création de l'affichage
$sortie = str_repeat(' ', $indentation_origine).
'<table id="chrono" lang="fr" summary="Résultat du chronométrage du programme affichant la page actuelle.">'."\n";
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 1))).
'<caption>Chronométrage</caption>'."\n";
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 1))).
'<thead>'."\n";
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 2))).
'<tr><th>Action</th><th>Temps écoulé (en s.)</th><th>Cumul du temps écoulé (en s.)</th></tr>'."\n";
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 1))).
'</thead>'."\n";
$tbody = str_repeat(' ', ($indentation_origine + ($indentation * 1))).
'<tbody>'."\n";
$total_tps_ecoule = 0;
// Récupération de la première mesure
$tab_depart =& $this->getTemps(0);
list($usec, $sec) = explode(' ', $tab_depart['depart']);
// Ce temps correspond à tps_fin
$tps_debut = ((float)$usec + (float)$sec);
foreach ($this->getTemps() as $tab_temps) {
foreach ($tab_temps as $cle => $valeur) {
list($usec, $sec) = explode(' ', $valeur);
$tps_fin = ((float)$usec + (float)$sec);
$tps_ecoule = abs($tps_fin - $tps_debut);
$total_tps_ecoule += $tps_ecoule;
$tbody .= str_repeat(' ', ($indentation_origine + ($indentation * 2))).
'<tr>'.
'<th>'.$cle.'</th>'.
'<td>'.number_format($tps_ecoule, 3, ',', ' ').'</td>'.
'<td>'.number_format($total_tps_ecoule, 3, ',', ' ').'</td>'.
'</tr>'."\n";
$tps_debut = $tps_fin;
}
}
$tbody .= str_repeat(' ', ($indentation_origine + ($indentation * 1))).
'</tbody>'."\n";
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 1))).
'<tfoot>'."\n";
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 2))).
'<tr>'.
'<th>'.'Total du temps écoulé (en s.)'.'</th>'.
'<td colspan="2">'.number_format($total_tps_ecoule,3, ',', ' ').'</td>'.
'</tr>'."\n";
$sortie .= str_repeat(' ', ($indentation_origine + ($indentation * 1))).
'</tfoot>'."\n";
$sortie .= $tbody;
$sortie .= str_repeat(' ', $indentation_origine).
'</table>'."\n";
return $sortie;
}
 
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/artichow/Image.class.php
New file
0,0 → 1,606
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
if(is_file(dirname(__FILE__)."/Artichow.cfg.php")) { // For PHP 4+5 version
require_once dirname(__FILE__)."/Artichow.cfg.php";
}
 
 
 
 
/*
* Register a class with the prefix in configuration file
*/
function registerClass($class, $abstract = FALSE) {
 
if(ARTICHOW_PREFIX === 'aw') {
return;
}
if($abstract) {
$abstract = 'abstract';
} else {
$abstract = '';
}
eval($abstract." class ".ARTICHOW_PREFIX.$class." extends aw".$class." { }");
 
}
 
/*
* Register an interface with the prefix in configuration file
*/
function registerInterface($interface) {
 
if(ARTICHOW_PREFIX === 'aw') {
return;
}
 
eval("interface ".ARTICHOW_PREFIX.$interface." extends aw".$interface." { }");
 
}
 
// Some useful files
require_once ARTICHOW."/Component.class.php";
 
require_once ARTICHOW."/inc/Grid.class.php";
require_once ARTICHOW."/inc/Tools.class.php";
require_once ARTICHOW."/inc/Driver.class.php";
require_once ARTICHOW."/inc/Math.class.php";
require_once ARTICHOW."/inc/Tick.class.php";
require_once ARTICHOW."/inc/Axis.class.php";
require_once ARTICHOW."/inc/Legend.class.php";
require_once ARTICHOW."/inc/Mark.class.php";
require_once ARTICHOW."/inc/Label.class.php";
require_once ARTICHOW."/inc/Text.class.php";
require_once ARTICHOW."/inc/Color.class.php";
require_once ARTICHOW."/inc/Font.class.php";
require_once ARTICHOW."/inc/Gradient.class.php";
require_once ARTICHOW."/inc/Shadow.class.php";
require_once ARTICHOW."/inc/Border.class.php";
 
require_once ARTICHOW."/common.php";
/**
* An image for a graph
*
* @package Artichow
*/
class awImage {
 
/**
* Graph width
*
* @var int
*/
public $width;
 
/**
* Graph height
*
* @var int
*/
public $height;
/**
* Use anti-aliasing ?
*
* @var bool
*/
protected $antiAliasing = FALSE;
/**
* Image format
*
* @var int
*/
protected $format = awImage::PNG;
/**
* Image background color
*
* @var Color
*/
protected $background;
/**
* GD resource
*
* @var resource
*/
protected $resource;
/**
* A Driver object
*
* @var Driver
*/
protected $driver;
/**
* Driver string
*
* @var string
*/
protected $driverString;
/**
* Shadow
*
* @var Shadow
*/
public $shadow;
/**
* Image border
*
* @var Border
*/
public $border;
/**
* Use JPEG for image
*
* @var int
*/
const JPEG = IMG_JPG;
/**
* Use PNG for image
*
* @var int
*/
const PNG = IMG_PNG;
/**
* Use GIF for image
*
* @var int
*/
const GIF = IMG_GIF;
/**
* Build the image
*/
public function __construct() {
$this->background = new awColor(255, 255, 255);
$this->shadow = new awShadow(awShadow::RIGHT_BOTTOM);
$this->border = new awBorder;
}
/**
* Get driver of the image
*
* @param int $w Driver width (from 0 to 1) (default to 1)
* @param int $h Driver height (from 0 to 1) (default to 1)
* @param float $x Position on X axis of the center of the driver (default to 0.5)
* @param float $y Position on Y axis of the center of the driver (default to 0.5)
* @return Driver
*/
public function getDriver($w = 1, $h = 1, $x = 0.5, $y = 0.5) {
$this->create();
$this->driver->setSize($w, $h);
$this->driver->setPosition($x, $y);
return $this->driver;
}
/**
* Sets the driver that will be used to draw the graph
*
* @param string $driverString
*/
public function setDriver($driverString) {
$this->driver = $this->selectDriver($driverString);
$this->driver->init($this);
}
/**
* Change the image size
*
* @var int $width Image width
* @var int $height Image height
*/
public function setSize($width, $height) {
if($width !== NULL) {
$this->width = (int)$width;
}
if($height !== NULL) {
$this->height = (int)$height;
}
}
/**
* Change image background
*
* @param mixed $background
*/
public function setBackground($background) {
if($background instanceof awColor) {
$this->setBackgroundColor($background);
} elseif($background instanceof awGradient) {
$this->setBackgroundGradient($background);
}
}
/**
* Change image background color
*
* @param awColor $color
*/
public function setBackgroundColor(awColor $color) {
$this->background = $color;
}
/**
* Change image background gradient
*
* @param awGradient $gradient
*/
public function setBackgroundGradient(awGradient $gradient) {
$this->background = $gradient;
}
/**
* Return image background, whether a Color or a Gradient
*
* @return mixed
*/
public function getBackground() {
return $this->background;
}
/**
* Turn antialiasing on or off
*
* @var bool $bool
*/
public function setAntiAliasing($bool) {
$this->antiAliasing = (bool)$bool;
}
/**
* Return the antialiasing setting
*
* @return bool
*/
public function getAntiAliasing() {
return $this->antiAliasing;
}
/**
* Change image format
*
* @var int $format New image format
*/
public function setFormat($format) {
if($format === awImage::JPEG or $format === awImage::PNG or $format === awImage::GIF) {
$this->format = $format;
}
}
/**
* Returns the image format as an integer
*
* @return unknown
*/
public function getFormat() {
return $this->format;
}
/**
* Returns the image format as a string
*
* @return string
*/
public function getFormatString() {
switch($this->format) {
case awImage::JPEG :
return 'jpeg';
case awImage::PNG :
return 'png';
case awImage::GIF :
return 'gif';
}
}
 
/**
* Create a new awimage
*/
public function create() {
 
if($this->driver === NULL) {
$driver = $this->selectDriver($this->driverString);
 
$driver->init($this);
$this->driver = $driver;
}
 
}
/**
* Select the correct driver
*
* @param string $driver The desired driver
* @return mixed
*/
protected function selectDriver($driver) {
$drivers = array('gd');
$driver = strtolower((string)$driver);
 
if(in_array($driver, $drivers, TRUE)) {
$string = $driver;
} else {
$string = ARTICHOW_DRIVER;
}
 
switch ($string) {
case 'gd':
require_once ARTICHOW.'/inc/drivers/gd.class.php';
$this->driverString = $string;
return new awGDDriver();
default:
// We should never get here, unless the wrong string is used AND the ARTICHOW_DRIVER
// global has been messed with.
awImage::drawError('Class Image: Unknown driver type (\''.$string.'\')');
break;
}
}
/**
* Draw a component on the image
*
* @var awComponent $component A component
*/
public function drawComponent(awComponent $component) {
$shadow = $this->shadow->getSpace(); // Image shadow
$border = $this->border->visible() ? 1 : 0; // Image border size
$driver = clone $this->driver;
$driver->setImageSize(
$this->width - $shadow->left - $shadow->right - $border * 2,
$this->height - $shadow->top - $shadow->bottom - $border * 2
);
// No absolute size specified
if($component->w === NULL and $component->h === NULL) {
list($width, $height) = $driver->setSize($component->width, $component->height);
// Set component size in pixels
$component->setAbsSize($width, $height);
} else {
$driver->setAbsSize($component->w, $component->h);
}
if($component->top !== NULL and $component->left !== NULL) {
$driver->setAbsPosition(
$border + $shadow->left + $component->left,
$border + $shadow->top + $component->top
);
} else {
$driver->setPosition($component->x, $component->y);
}
$driver->movePosition($border + $shadow->left, $border + $shadow->top);
list($x1, $y1, $x2, $y2) = $component->getPosition();
$component->init($driver);
$component->drawComponent($driver, $x1, $y1, $x2, $y2, $this->antiAliasing);
$component->drawEnvelope($driver, $x1, $y1, $x2, $y2);
$component->finalize($driver);
}
protected function drawShadow() {
$driver = $this->getDriver();
$this->shadow->draw(
$driver,
new awPoint(0, 0),
new awPoint($this->width, $this->height),
awShadow::IN
);
}
/**
* Send the image into a file or to the user browser
*
*/
public function send() {
$this->driver->send($this);
}
/**
* Return the image content as binary data
*
*/
public function get() {
return $this->driver->get($this);
}
/**
* Send the correct HTTP header according to the image type
*
*/
public function sendHeaders() {
 
if(headers_sent() === FALSE) {
switch ($this->driverString) {
case 'gd' :
header('Content-type: image/'.$this->getFormatString());
break;
}
 
}
}
private static $errorWriting = FALSE;
 
/*
* Display an error image and exit
*
* @param string $message Error message
*/
public static function drawError($message) {
if(self::$errorWriting) {
return;
}
self::$errorWriting = TRUE;
$message = wordwrap($message, 40, "\n", TRUE);
$width = 400;
$height = max(100, 40 + 22.5 * (substr_count($message, "\n") + 1));
$image = new awImage();
$image->setSize($width, $height);
$image->setDriver('gd');
$driver = $image->getDriver();
$driver->init($image);
// Display title
$driver->filledRectangle(
new awWhite,
new awLine(
new awPoint(0, 0),
new awPoint($width, $height)
)
);
$driver->filledRectangle(
new awRed,
new awLine(
new awPoint(0, 0),
new awPoint(110, 25)
)
);
$text = new awText(
"Artichow error",
new awFont3,
new awWhite,
0
);
$driver->string($text, new awPoint(5, 6));
// Display red box
$driver->rectangle(
new awRed,
new awLine(
new awPoint(0, 25),
new awPoint($width - 90, $height - 1)
)
);
// Display error image
$file = ARTICHOW_IMAGE.DIRECTORY_SEPARATOR.'error.png';
$imageError = new awFileImage($file);
$driver->copyImage(
$imageError,
new awPoint($width - 81, $height - 81),
new awPoint($width - 1, $height - 1)
);
// Draw message
$text = new awText(
strip_tags($message),
new awFont2,
new awBlack,
0
);
$driver->string($text, new awPoint(10, 40));
$image->send();
exit;
}
/*
* Display an error image located in a file and exit
*
* @param string $error Error name
*/
public static function drawErrorFile($error) {
$file = ARTICHOW_IMAGE.DIRECTORY_SEPARATOR.'errors'.DIRECTORY_SEPARATOR.$error.'.png';
header("Content-Type: image/png");
readfile($file);
exit;
}
 
}
 
registerClass('Image');
 
/**
* Load an image from a file
*
* @package Artichow
*/
class awFileImage extends awImage {
 
/**
* Build a new awimage
*
* @param string $file Image file name
*/
public function __construct($file) {
$driver = $this->selectDriver($this->driverString);
$driver->initFromFile($this, $file);
$this->driver = $driver;
}
 
}
 
registerClass('FileImage');
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/common.php
New file
0,0 → 1,96
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
/*
* Get the minimum of an array and ignore non numeric values
*/
function array_min($array) {
 
if(is_array($array) and count($array) > 0) {
do {
$min = array_pop($array);
if(is_numeric($min) === FALSE) {
$min = NULL;
}
} while(count($array) > 0 and $min === NULL);
if($min !== NULL) {
$min = (float)$min;
}
foreach($array as $value) {
if(is_numeric($value) and (float)$value < $min) {
$min = (float)$value;
}
}
return $min;
}
return NULL;
 
}
 
/*
* Get the maximum of an array and ignore non numeric values
*/
function array_max($array) {
 
if(is_array($array) and count($array) > 0) {
do {
$max = array_pop($array);
if(is_numeric($max) === FALSE) {
$max = NULL;
}
} while(count($array) > 0 and $max === NULL);
 
if($max !== NULL) {
$max = (float)$max;
}
foreach($array as $value) {
if(is_numeric($value) and (float)$value > $max) {
$max = (float)$value;
}
}
return $max;
}
return NULL;
 
}
/*
* Define file_put_contents() if needed
*/
if(function_exists('file_put_contents') === FALSE) {
 
function file_put_contents($file, $content) {
$fp = fopen($file, 'w');
if($fp) {
fwrite($fp, $content);
fclose($fp);
}
}
}
 
/*
* Change error handler
*/
set_error_handler('errorHandlerArtichow');
 
function errorHandlerArtichow($level, $message, $file, $line) {
awImage::drawError($message.' in '.$file.' on line '.$line.'.');
}
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/line-005.php
New file
0,0 → 1,36
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../LinePlot.class.php";
 
$graph = new Graph(400, 300);
 
$x = array(
-4, -5, -2, -8, -3, 1, 4, 9, 5, 6, 2
);
 
$plot = new LinePlot($x);
 
// Filled an area with a color
$plot->setFilledArea(7, 9, new DarkGreen(25));
 
// Filled the area with a gradient
$gradient = new LinearGradient(
new Yellow(25),
new Orange(25),
90
);
$plot->setFilledArea(1, 4, $gradient);
 
// Hide first label
$plot->xAxis->label->hideFirst(TRUE);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/line-006.php
New file
0,0 → 1,49
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../LinePlot.class.php";
 
 
// Use cache
$graph = new Graph(400, 400, "Example-006", time() + 5);
$graph->setTiming(TRUE);
$graph->setAntiAliasing(TRUE);
 
 
$x = array();
for($i = 0; $i < 10; $i++) {
$x[] = mt_rand(0, 100);
}
 
$plot = new LinePlot($x);
$plot->setColor(
new Color(60, 60, 150)
);
$plot->setFillGradient(
new LinearGradient(
new Color(120, 175, 80, 47),
new Color(231, 172, 113, 30),
0
)
);
 
$plot->grid->setType(Line::DASHED);
 
$plot->setYMin(-5);
 
$plot->yAxis->setLabelNumber(8);
$plot->yAxis->setLabelPrecision(1);
 
$plot->xAxis->setNumberByTick('minor', 'major', 3);
 
$plot->setXAxisZero(TRUE);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/line-007.php
New file
0,0 → 1,67
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../LinePlot.class.php";
 
// Return a random color
function color($a = NULL) {
return new Color(mt_rand(20, 180), mt_rand(20, 180), mt_rand(20, 180), $a);
}
 
function formatLabel($value) {
return sprintf("%.2f", $value);
}
 
$graph = new Graph(450, 400);
$graph->setAntiAliasing(TRUE);
$graph->title->set("Some lines");
 
$group = new PlotGroup;
$group->setXAxisZero(FALSE);
$group->setBackgroundColor(new Color(197, 180, 210, 80));
 
$group->setPadding(40, NULL, 50, NULL);
 
$group->axis->left->setLabelNumber(8);
$group->axis->left->setLabelPrecision(1);
$group->axis->left->setTickStyle(Tick::OUT);
 
$group->axis->bottom->setTickStyle(Tick::OUT);
 
// Display two lines
for($n = 0; $n < 2; $n++) {
 
$x = array();
for($i = 0; $i < 10; $i++) {
$x[] = (cos($i * M_PI / 5)) / ($n + 1);
}
$plot = new LinePlot($x);
$plot->setColor(color(10)); // Random line color
$plot->setFillColor(color(90)); // Random background color
 
$plot->label->set($x);
$plot->label->setBackgroundColor(new Color(220, 234, 230, 25));
$plot->label->setPadding(1, 0, 0, 0);
$plot->label->setCallbackFunction("formatLabel");
$plot->label->setInterval(2);
$group->add($plot);
$group->legend->add($plot, "Line #".($n + 1), Legend::LINE);
}
 
$group->legend->setSpace(12);
$group->legend->setBackgroundColor(new Color(255, 255, 255));
$group->setPadding(NULL, 100, NULL, NULL);
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/AntiSpam-image.php
New file
0,0 → 1,16
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../AntiSpam.class.php";
 
$object = new AntiSpam();
$object->setRand(5);
$object->save('example');
$object->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/line-008.php
New file
0,0 → 1,34
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../LinePlot.class.php";
 
 
// Use cache
$graph = new Graph(400, 400);
$graph->setAntiAliasing(TRUE);
$graph->border->setStyle(Line::DOTTED);
$graph->border->setColor(new Red);
 
$x = array();
for($i = 0; $i < 10; $i++) {
$x[] = mt_rand(20, 100);
}
 
$plot = new LinePlot($x);
$plot->setFilledArea(0, 1, new Red(40));
$plot->setFilledArea(1, 2, new LinearGradient(new Red(40), new Orange(40), 90));
$plot->setFilledArea(2, 4, new LinearGradient(new Orange(40), new Green(40), 90));
$plot->setFilledArea(4, 7, new LinearGradient(new Green(40), new Blue(40), 90));
$plot->setFilledArea(7, 8, new LinearGradient(new Blue(40), new Purple(40), 90));
$plot->setFilledArea(8, 9, new Purple(40));
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/line-009.php
New file
0,0 → 1,66
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../LinePlot.class.php";
 
 
$graph = new Graph(400, 200);
$graph->setAntiAliasing(TRUE);
 
$group = new PlotGroup;
$group->setXAxisZero(FALSE);
$group->grid->setType(Line::DASHED);
 
$group->setBackgroundColor(new Color(197, 180, 210, 80));
 
$group->setPadding(40, NULL, 20, NULL);
 
$group->axis->left->setLabelNumber(8);
$group->axis->left->setLabelPrecision(1);
$group->axis->left->setTickStyle(Tick::IN);
$group->axis->left->label->move(-4, 0);
 
$group->axis->bottom->setTickStyle(Tick::OUT);
$group->axis->bottom->label->move(0, 4);
 
$x = array();
 
for($i = 0; $i < 15; $i++) {
$x[] = cos($i * M_PI / 5);
}
 
$plot = new LinePlot($x);
$plot->setColor(new Color(40, 40, 150, 10));
$plot->setFillColor(new Color(40, 40, 150, 90));
 
$group->add($plot);
$group->legend->add($plot, "Ligne #1", Legend::LINE);
 
$x = array();
 
for($i = 5; $i < 15; $i++) {
$x[] = (cos($i * M_PI / 5)) / 2;
}
 
$plot = new LinePlot($x);
$plot->setColor(new Color(120, 120, 30, 10));
$plot->setFillColor(new Color(120, 120, 30, 90));
 
$group->add($plot);
$group->legend->add($plot, "Ligne #2", Legend::LINE);
 
$group->legend->setTextFont(new Tuffy(8));
$group->legend->shadow->setSize(0);
$group->legend->setSpace(12);
$group->legend->setBackgroundColor(new Color(255, 255, 255));
$group->setPadding(NULL, 100, NULL, NULL);
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/base-Gradient-linear.php
New file
0,0 → 1,25
<?php
 
require_once "../../Graph.class.php";
 
$graph = new Graph(400, 30);
 
$graph->border->hide();
 
$driver = $graph->getDriver();
 
$driver->filledRectangle(
new LinearGradient(
new Black,
new White,
0
),
new Line(
new Point(0, 0),
new Point(400, 30)
)
);
 
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/line-Simple.php
New file
0,0 → 1,22
<?php
require_once "../../LinePlot.class.php";
 
$graph = new Graph(400, 400);
 
$graph->setAntiAliasing(FALSE);
 
$values = array(1, 4, 5, -2.5, 3);
$plot = new LinePlot($values);
$plot->setBackgroundGradient(
new LinearGradient(
new Color(210, 210, 210),
new Color(250, 250, 250),
0
)
);
$plot->yAxis->setLabelPrecision(1);
$plot->setSpace(5, 5, NULL, NULL);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/plot-More.php
New file
0,0 → 1,47
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../BarPlot.class.php";
require_once "../../LinePlot.class.php";
 
$graph = new Graph(450, 400);
 
$graph->setAntiAliasing(TRUE);
 
$blue = new Color(150, 150, 230, 50);
$red = new Color(240, 50, 50, 25);
 
$group = new PlotGroup;
$group->setSpace(5, 5, 5, 0);
$group->setBackgroundColor(
new Color(240, 240, 240)
);
 
$values = array(18, 12, 14, 21, 11, 7, 9, 16, 7, 23);
 
$plot = new BarPlot($values);
$plot->setBarColor($red);
 
$group->add($plot);
 
$values = array(12, 8, 6, 12, 7, 5, 4, 9, 3, 12);
 
$plot = new LinePlot($values, LinePlot::MIDDLE);
$plot->setFillColor($blue);
 
$plot->mark->setType(Mark::SQUARE);
$plot->mark->setSize(7);
$plot->mark->setFill(new Color(255, 255, 255));
$plot->mark->border->show();
 
$group->add($plot);
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/base-Gradient-radial.php
New file
0,0 → 1,24
<?php
require_once "../../Graph.class.php";
 
$graph = new Graph(250, 250);
 
$graph->border->hide();
 
$driver = $graph->getDriver();
 
$start = new Color(125, 250, 0);
$end = new Color(0, 125, 125);
 
// On dessine le dégradé radial dans un cercle
$driver->filledEllipse(
new RadialGradient(
$start,
$end
),
new Point(125, 125),
250, 250
);
 
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/line-Lines.php
New file
0,0 → 1,49
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
$graph = new Graph(450, 400);
 
$graph->setAntiAliasing(TRUE);
 
$blue = new Color(0, 0, 200);
$red = new Color(200, 0, 0);
 
$group = new PlotGroup;
$group->setBackgroundColor(
new Color(240, 240, 240)
);
$group->setPadding(40, 40);
 
$values = array(12, 5, 20, 32, 15, 4, 16);
 
$plot = new LinePlot($values);
$plot->setColor($blue);
$plot->setYAxis(Plot::LEFT);
 
$group->add($plot);
 
$group->axis->left->setColor($blue);
$group->axis->left->title->set("Blue line");
 
$values = array(6, 12, 14, 2, 11, 5, 21);
 
$plot = new LinePlot($values);
$plot->setColor($red);
$plot->setYAxis(Plot::RIGHT);
 
$group->add($plot);
 
$group->axis->right->setColor($red);
$group->axis->right->title->set("Red line");
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/smiley.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/smiley.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/AntiSpam/valid.php
New file
0,0 → 1,11
<?php
require_once "../../../AntiSpam.class.php";
 
$object = new AntiSpam();
 
if($object->check('example', $_GET['code'])) {
echo "Good value :-)";
} else {
echo "Bad value :-(";
}
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/AntiSpam/spam.php
New file
0,0 → 1,18
<?php
 
require_once '../../../AntiSpam.class.php';
 
// On créé l'image anti-spam
$object = new AntiSpam();
 
// La valeur affichée sur l'image fera 5 caractères
$object->setRand(5);
 
// On assigne un nom à cette image pour vérifier
// ultérieurement la valeur fournie par l'utilisateur
$object->save('example');
 
// On affiche l'image à l'écran
$object->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/AntiSpam/form.php
New file
0,0 → 1,5
<form action="valid.php" method="get">
<img src="spam.php" style="vertical-align: middle"/>
<input type="text" name="code"/>
<input type="submit" value="Submit"/>
</form>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/base-Color.php
New file
0,0 → 1,40
<?php
require_once "../../Graph.class.php";
 
$graph = new Graph(400, 30);
 
$graph->border->hide();
 
$driver = $graph->getDriver();
 
for($i = 7; $i < 400; $i += 15) {
$driver->line(
new Color(0, 0, 0),
new Line(
new Point($i, 0),
new Point($i, 30)
)
);
}
 
for($i = 7; $i < 30; $i += 15) {
$driver->line(
new Color(0, 0, 0),
new Line(
new Point(0, $i),
new Point(400, $i)
)
);
}
 
$driver->filledRectangle(
new Color(0, 100, 200, 50),
new Line(
new Point(0, 0),
new Point(400, 30)
)
);
 
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/line-Customize.php
New file
0,0 → 1,50
<?php
require_once "../../LinePlot.class.php";
 
$graph = new Graph(400, 300);
 
$graph->setAntiAliasing(TRUE);
 
$values = array(1, 7, 3, 2.5, 5, -4.5, -5);
$plot = new LinePlot($values);
$plot->setBackgroundColor(new Color(245, 245, 245));
 
$plot->hideLine(TRUE);
$plot->setFillColor(new Color(180, 180, 180, 75));
 
$plot->grid->setBackgroundColor(new Color(235, 235, 180, 60));
 
$plot->yAxis->setLabelPrecision(2);
$plot->yAxis->setLabelNumber(6);
 
$days = array(
'Lundi',
'Mardi',
'Mercredi',
'Jeudi',
'Vendredi',
'Samedi',
'Dimanche'
);
$plot->xAxis->setLabelText($days);
$plot->setSpace(6, 6, 10, 10);
 
$plot->mark->setType(Mark::IMAGE);
$plot->mark->setImage(new FileImage("smiley.png"));
 
$plot->label->set($values);
$plot->label->move(0, -23);
$plot->label->setBackgroundGradient(
new LinearGradient(
new Color(250, 250, 250, 10),
new Color(255, 200, 200, 30),
0
)
);
$plot->label->border->setColor(new Color(20, 20, 20, 20));
$plot->label->setPadding(3, 1, 1, 0);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/bar-Bars.php
New file
0,0 → 1,47
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../BarPlot.class.php";
 
$graph = new Graph(450, 400);
 
$graph->setAntiAliasing(TRUE);
 
$blue = new Color(0, 0, 200);
$red = new Color(200, 0, 0);
 
$group = new PlotGroup;
$group->setPadding(40, 40);
$group->setBackgroundColor(
new Color(240, 240, 240)
);
 
$values = array(12, 8, 20, 32, 15, 5);
 
$plot = new BarPlot($values, 1, 2);
$plot->setBarColor($blue);
$plot->setYAxis(Plot::LEFT);
 
$group->add($plot);
$group->axis->left->setColor($blue);
$group->axis->left->title->set("Blue bars");
 
$values = array(6, 12, 14, 2, 11, 7);
 
$plot = new BarPlot($values, 2, 2);
$plot->setBarColor($red);
$plot->setYAxis(Plot::RIGHT);
 
$group->add($plot);
$group->axis->right->setColor($red);
$group->axis->right->title->set("Red bars");
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/tutorials/bar-Simple.php
New file
0,0 → 1,31
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../BarPlot.class.php";
 
$graph = new Graph(400, 400);
 
$graph->setAntiAliasing(TRUE);
 
$values = array(19, 42, 15, -25, 3);
$plot = new BarPlot($values);
$plot->setBarColor(
new Color(250, 230, 180)
);
$plot->setSpace(5, 5, NULL, NULL);
 
$plot->barShadow->setSize(4);
$plot->barShadow->setPosition(Shadow::RIGHT_TOP);
$plot->barShadow->setColor(new Color(180, 180, 180, 10));
$plot->barShadow->smooth(TRUE);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/scatter-001.php
New file
0,0 → 1,21
<?php
 
require_once "../ScatterPlot.class.php";
 
$graph = new Graph(400, 400);
 
$graph->title->set('Simple ScatterPlot');
 
$y = array(1, 10, 3,-4, 1, 4, 8, 7);
$x = array(0.5, 0.5, 3, 5, 2, 3, 4, 1.5);
 
$plot = new ScatterPlot($y, $x);
$plot->setBackgroundColor(new VeryLightGray);
$plot->setPadding(NULL, NULL, 40, 20);
 
$plot->legend->add($plot, 'Some points', Legend::MARKONLY);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/scatter-002.php
New file
0,0 → 1,21
<?php
 
require_once "../ScatterPlot.class.php";
 
$graph = new Graph(400, 400);
 
$graph->title->set('Linked ScatterPlot');
 
$y = array(1, 10, 3,-4, 1, 4, 8, 7);
$x = array(0.5, 0.5, 3, 5, 2, 3, 4, 1.5);
 
$plot = new ScatterPlot($y, $x);
$plot->setBackgroundColor(new VeryLightGray);
$plot->setPadding(NULL, NULL, 40, 20);
 
$plot->link(TRUE, new DarkBlue);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/scatter-003.php
New file
0,0 → 1,30
<?php
 
require_once "../ScatterPlot.class.php";
 
$graph = new Graph(400, 400);
 
$graph->shadow->setSize(5);
$graph->title->set('ScatterPlot with values');
 
$y = array(4, 3, 2, 5, 8, 1, 3, 6, 4, 5);
$x = array(1, 2, 5, 4, 3, 6, 2, 4, 5, 1);
 
$plot = new ScatterPlot($y, $x);
$plot->setSpace(6, 6, 6, 0);
$plot->setPadding(NULL, NULL, 40, 20);
 
// Set dashed lines on the grid
$plot->grid->setType(Line::DASHED);
 
$plot->mark->setSize(30);
$plot->mark->setFill(new DarkOrange(20));
 
 
$plot->label->set($y);
$plot->label->setColor(new White);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/scatter-004.php
New file
0,0 → 1,32
<?php
 
require_once "../ScatterPlot.class.php";
 
$graph = new Graph(400, 400);
 
$graph->shadow->setSize(5);
 
$y = array();
for($i = 0; $i < 60; $i++) {
$y[] = cos($i / 30 * 2 * M_PI);
}
 
$plot = new ScatterPlot($y);
$plot->setSpace(6, 6);
 
// Set impulses
$plot->setImpulse(new DarkGreen);
 
$plot->grid->hideVertical();
 
// Hide axis labels and ticks
$plot->xAxis->label->hide();
$plot->xAxis->hideTicks();
 
$plot->mark->setType(Mark::SQUARE);
$plot->mark->setSize(4);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/scatter-005.php
New file
0,0 → 1,37
<?php
 
require_once "../ScatterPlot.class.php";
 
$graph = new Graph(400, 400);
 
$graph->title->set('Impulses');
$graph->title->move(0, 30);
$graph->shadow->setSize(5);
 
$y = array();
for($i = 0; $i < 60; $i++) {
$y[] = cos($i / 30 * 2 * M_PI) / (1.5 + $i / 15);
}
 
$plot = new ScatterPlot($y);
$plot->setBackgroundColor(new VeryLightOrange);
$plot->setSpace(5);
 
// Set impulses
$plot->setImpulse(new DarkBlue);
 
$plot->grid->hideVertical();
 
// Hide ticks
$plot->xAxis->hideTicks();
 
// Change labels interval
$plot->xAxis->label->setInterval(5);
 
$plot->mark->setType(Mark::SQUARE);
$plot->mark->setSize(4);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/scatter-006.php
New file
0,0 → 1,39
<?php
 
require_once "../ScatterPlot.class.php";
 
$graph = new Graph(400, 400);
 
$center = 5;
 
$x = array();
$y = array();
 
for($i = 0; $i <= 30; $i++) {
$rad = ($i / 30) * 2 * M_PI;
$x[] = $center + cos($rad) * $center;
$y[] = $center + sin($rad) * $center;
}
 
$plot = new ScatterPlot($y, $x);
$plot->setBackgroundColor(new VeryLightGray);
$plot->setPadding(30, 30, 30, 30);
$plot->setSpace(5, 5, 5, 5);
 
$plot->link(TRUE, new DarkGreen);
 
$plot->mark->setFill(new DarkOrange);
$plot->mark->setType(Mark::SQUARE, 4);
 
$plot->setXAxis(Plot::BOTH);
$plot->setXAxisZero(FALSE);
$plot->setYAxis(Plot::BOTH);
 
$plot->legend->add($plot, 'A circle', Legend::MARK);
$plot->legend->setPosition(0.5, 0.5);
$plot->legend->setAlign(Legend::CENTER, Legend::MIDDLE);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/AntiSpam-valid.php
New file
0,0 → 1,22
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../AntiSpam.class.php";
 
$object = new AntiSpam();
 
if($object->check('example', $_GET['code'])) {
echo "Good value :-)";
} else {
echo "Bad value :-(";
}
?>
<ul>
<li><a href='AntiSpam.php'>Try again</a></li>
</ul>
/tags/v1.0-Homere/bibliotheque/artichow/examples/scatter-007.php
New file
0,0 → 1,60
<?php
 
require_once "../ScatterPlot.class.php";
 
$graph = new Graph(400, 400);
 
$group = new PlotGroup;
 
$group->setBackgroundColor(new VeryLightGray);
$group->setPadding(30, 30, 30, 30);
$group->setSpace(5, 5, 5, 5);
 
$group->legend->setPosition(0.5, 0.62);
$group->legend->setAlign(Legend::CENTER, Legend::MIDDLE);
 
function getCircle($size) {
 
$center = 0;
$x = array();
$y = array();
for($i = 0; $i <= 30; $i++) {
$rad = ($i / 30) * 2 * M_PI;
$x[] = $center + cos($rad) * $size;
$y[] = $center + sin($rad) * $size;
}
return array($x, $y);
}
 
list($x, $y) = getCircle(3);
 
$plot = new ScatterPlot($y, $x);
 
$plot->link(TRUE, new DarkBlue);
 
$plot->mark->setFill(new DarkPink);
$plot->mark->setType(Mark::CIRCLE, 6);
 
$group->legend->add($plot, 'Circle #1', Legend::MARK);
$group->add($plot);
 
list($x, $y) = getCircle(5);
 
$plot = new ScatterPlot($y, $x);
 
$plot->link(TRUE, new DarkGreen);
 
$plot->mark->setFill(new DarkOrange);
$plot->mark->setType(Mark::SQUARE, 4);
 
$group->legend->add($plot, 'Circle #2', Legend::MARK);
$group->add($plot);
 
$graph->add($group);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-010.php
New file
0,0 → 1,29
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
 
$graph->title->set("Pie (example 10) - Just a pie");
$graph->title->setFont(new Tuffy(10));
 
$values = array(8, 4, 6, 1, 2, 3, 4);
 
$plot = new Pie($values);
$plot->set3D(10);
 
$plot->legend->hide(TRUE);
$plot->label->hide(TRUE);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-011.php
New file
0,0 → 1,48
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
function createPie($values, $title, $x, $y) {
$plot = new Pie($values, Pie::EARTH);
$plot->title->set($title);
$plot->title->setFont(new TuffyBold(8));
$plot->title->move(NULL, -12);
$plot->label->setFont(new Tuffy(7));
$plot->legend->hide(TRUE);
$plot->setLabelPosition(5);
$plot->setSize(0.45, 0.45);
$plot->setCenter($x, $y);
$plot->set3D(10);
$plot->setBorderColor(new Color(230, 230, 230));
return $plot;
 
}
 
$graph = new Graph(400, 300);
 
$plot = createPie(array(1, 4, 5, 2, 3), "Cowléoptère", 0.22, 0.25);
$graph->add($plot);
 
$plot = createPie(array(1, 9, 1, 2, 1), "Asticow", 0.68, 0.25);
$graph->add($plot);
 
$plot = createPie(array(5, 7, 8, 6, 3), "Cowlibri", 0.22, 0.75);
$graph->add($plot);
 
$plot = createPie(array(6, 4, 6, 5, 6), "Bourricow", 0.68, 0.75);
$plot->legend->hide(FALSE); // We print only one legend
$plot->legend->setPosition(1.18, 0);
$graph->add($plot);
 
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-012.php
New file
0,0 → 1,38
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
$graph = new Graph(300, 300);
 
$graph->title->set("Pie (example 12)");
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values, Pie::EARTH);
$plot->setCenter(0.4, 0.55);
$plot->setSize(0.7, 0.6);
$plot->explode(array(1 => 20, 4 => 25));
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->legend->setPosition(1.3);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-013.php
New file
0,0 → 1,40
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Pie (example 13)");
 
$values = array(12, 5, 13, 18, 10, 6, 11);
 
$plot = new Pie($values, Pie::EARTH);
$plot->setCenter(0.4, 0.55);
$plot->setAbsSize(180, 180);
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->legend->setPosition(1.5);
$plot->legend->shadow->setSize(0);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/math-001.php
New file
0,0 → 1,45
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../MathPlot.class.php";
 
 
$graph = new Graph(300, 300);
 
$plot = new MathPlot(-3, 3, 3, -3);
$plot->setInterval(0.2);
$plot->setPadding(NULL, NULL, NULL, 20);
 
$function = new MathFunction('cos');
$function->setColor(new DarkGreen);
$function->mark->setType(Mark::SQUARE);
$function->mark->setSize(3);
$plot->add($function, "f(x) = cos(x)", Legend::MARK);
 
$function = new MathFunction('exp');
$function->setColor(new DarkRed);
$function->mark->setType(Mark::SQUARE);
$function->mark->setSize(3);
$function->mark->setFill(new DarkBlue);
$plot->add($function, "f(x) = exp(x)", Legend::MARK);
 
function x2($x) {
return - $x * $x + 0.5;
}
 
$function = new MathFunction('x2');
$function->setColor(new DarkBlue);
$plot->add($function, "f(x) = - x * x + 0.5");
 
$plot->legend->setPosition(0.9, 0.8);
$plot->legend->setPadding(3, 3, 3, 3, 3);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/line-003.php
New file
0,0 → 1,70
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
$graph = new Graph(280, 200);
 
$x = array();
for($i = 115; $i < 115 + 180; $i++) {
$x[] = cos($i / 25);
}
 
function format($value) {
return sprintf("%.1f", $value).' %';
}
 
$plot = new LinePlot($x);
 
$plot->setBackgroundColor(
new Color(240, 240, 240)
);
 
$plot->setPadding(40, 15, 15, 15);
 
$plot->setColor(
new Color(60, 60, 150)
);
 
$plot->setFillColor(
new Color(120, 175, 80, 47)
);
 
$plot->grid->setType(Line::DASHED);
 
$plot->yAxis->setLabelNumber(6);
$plot->yAxis->setLabelPrecision(1);
$plot->yAxis->setNumberByTick('minor', 'major', 1);
$plot->yAxis->label->setCallbackFunction('format');
$plot->yAxis->label->setFont(new Tuffy(7));
 
$plot->xAxis->setNumberByTick('minor', 'major', 3);
$plot->xAxis->label->hideFirst(TRUE);
$plot->xAxis->setLabelInterval(50);
$plot->xAxis->label->setFont(new Tuffy(7));
 
$plot->grid->setInterval(1, 50);
 
$graph->shadow->setSize(4);
$graph->shadow->setPosition(Shadow::RIGHT_BOTTOM);
$graph->shadow->smooth(TRUE);
 
$plot->label->set($x);
$plot->label->setInterval(25);
$plot->label->hideFirst(TRUE);
$plot->label->setPadding(1, 1, 1, 1);
$plot->label->setCallbackFunction('format');
$plot->label->setBackgroundColor(
new Color(227, 223, 241, 15)
);
$plot->label->setFont(new Tuffy(7));
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/line-004.php
New file
0,0 → 1,104
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
require_once "../../BarPlot.class.php";
 
 
$graph = new Graph(600, 250);
 
$graph->setBackgroundColor(new Color(0xF4, 0xF4, 0xF4));
$graph->shadow->setSize(3);
 
$graph->title->set("Evolution");
$graph->title->setFont(new Tuffy(15));
$graph->title->setColor(new Color(0x00, 0x00, 0x8B));
 
 
$group = new PlotGroup;
$group->setSize(0.82, 1);
$group->setCenter(0.41, 0.5);
$group->setPadding(35, 26, 40, 27);
$group->setSpace(2, 2);
 
$group->grid->setColor(new Color(0xC4, 0xC4, 0xC4));
$group->grid->setType(Line::DASHED);
$group->grid->hideVertical(TRUE);
$group->grid->setBackgroundColor(new White);
 
$group->axis->left->setColor(new DarkGreen);
$group->axis->left->label->setFont(new Font2);
 
$group->axis->right->setColor(new DarkBlue);
$group->axis->right->label->setFont(new Font2);
 
$group->axis->bottom->label->setFont(new Font2);
 
$group->legend->setPosition(1.18);
$group->legend->setTextFont(new Tuffy(8));
$group->legend->setSpace(10);
 
// Add a bar plot
$x = array(16, 16, 12, 13, 11, 18, 10, 12, 11, 12, 11, 16);
 
$plot = new BarPlot($x, 1, 2);
$plot->setBarColor(new MidYellow);
$plot->setBarPadding(0.15, 0.15);
$plot->barShadow->setSize(3);
$plot->barShadow->smooth(TRUE);
$plot->barShadow->setColor(new Color(200, 200, 200, 10));
$plot->move(1, 0);
 
$group->legend->add($plot, "Yellow bar", Legend::BACKGROUND);
$group->add($plot);
 
// Add a bar plot
$x = array(20, 25, 20, 18, 16, 25, 29, 12, 15, 18, 21, 26);
 
$plot = new BarPlot($x, 2, 2);
$plot->setBarColor(new Color(120, 175, 80, 10));
$plot->setBarPadding(0.15, 0.15);
$plot->barShadow->setSize(3);
$plot->barShadow->smooth(TRUE);
$plot->barShadow->setColor(new Color(200, 200, 200, 10));
 
$group->legend->add($plot, "Green bar", Legend::BACKGROUND);
$group->add($plot);
 
// Add a second bar plot
$x = array(12, 14, 10, 9, 10, 16, 12, 8, 8, 10, 12, 13);
 
$plot = new BarPlot($x, 2, 2);
$plot->setBarColor(new Orange);
$plot->setBarPadding(0.15, 0.15);
 
$group->legend->add($plot, "Orange bar", Legend::BACKGROUND);
$group->add($plot);
 
// Add a line plot
$x = array(6, 5, 6, 5.5, 4.5, 4, 4.5, 4, 5, 4, 5, 5.5);
 
$plot = new LinePlot($x, LinePlot::MIDDLE);
$plot->setColor(new DarkBlue);
$plot->setThickness(5);
$plot->setYAxis(Plot::RIGHT);
$plot->setYMax(12);
 
$plot->mark->setType(Mark::CIRCLE);
$plot->mark->setSize(6);
$plot->mark->setFill(new LightBlue);
$plot->mark->border->show();
 
$group->legend->add($plot, "Blue line", Legend::MARK);
$group->add($plot);
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/mini-001.php
New file
0,0 → 1,60
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
 
$graph = new Graph(150, 100);
 
$graph->setAntiAliasing(TRUE);
 
$x = array(
0, 2, 5, 2, 3, 8
);
 
$plot = new LinePlot($x);
$plot->setXAxisZero(FALSE);
$plot->grid->setNobackground();
 
$plot->setSpace(6, 6, 10, 10);
$plot->setPadding(30, 6, 8, 18);
 
// Set a background gradient
$plot->setBackgroundGradient(
new LinearGradient(
new Color(210, 210, 210),
new Color(255, 255, 255),
0
)
);
 
// Change line color
$plot->setColor(new Color(0, 0, 150, 20));
 
// Set line background gradient
$plot->setFillGradient(
new LinearGradient(
new Color(150, 150, 210),
new Color(230, 230, 255),
0
)
);
 
// Change mark type
$plot->mark->setType(Mark::CIRCLE);
$plot->mark->border->show();
$plot->mark->setSize(6);
 
$plot->yAxis->setLabelPrecision(1);
$plot->yAxis->label->setFont(new Font1);
$plot->xAxis->label->setFont(new Font1);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/line-006.php
New file
0,0 → 1,58
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
 
$graph = new Graph(300, 200);
 
$graph->setAntiAliasing(TRUE);
 
$x = array(
-4, -5, -2, -8, -3, 1, 4, 9, 5, 6, 2
);
 
$plot = new LinePlot($x);
$plot->setStyle(Line::DASHED);
 
$plot->setSpace(4, 4, 10, 0);
$plot->setPadding(25, 15, 10, 18);
 
$plot->setBackgroundGradient(
new LinearGradient(
new Color(230, 230, 230),
new Color(255, 255, 255),
90
)
);
 
$plot->setFilledArea(7, 9, new Red(25));
$plot->setFilledArea(1, 4, new Yellow(25));
 
$plot->setColor(new Color(0, 0, 150, 20));
 
$plot->grid->setColor(new VeryLightGray);
 
$plot->mark->setType(Mark::SQUARE);
$plot->mark->setSize(4);
$plot->mark->setFill(new VeryDarkGreen(30));
$plot->mark->border->show();
$plot->mark->border->setColor(new DarkBlue(60));
 
$plot->xAxis->label->hide(TRUE);
$plot->xAxis->setNumberByTick('minor', 'major', 3);
 
$plot->yAxis->setLabelNumber(8);
 
$plot->legend->add($plot, "My line");
$plot->legend->setPosition(0.9, 0.77);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/mini-002.php
New file
0,0 → 1,50
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
 
$graph = new Graph(150, 100);
 
$graph->setAntiAliasing(TRUE);
 
$x = array(
1, 2, 5, 0.5, 3, 8, 7, 6, 2, -4
);
 
$plot = new LinePlot($x);
$plot->grid->setNobackground();
$plot->setPadding(20, 8, 8, 20);
$plot->setXAxisZero(FALSE);
 
// Set a background gradient
$plot->setBackgroundGradient(
new LinearGradient(
new Color(210, 210, 210),
new Color(255, 255, 255),
0
)
);
 
// Set semi-transparent background gradient
$plot->setFillGradient(
new LinearGradient(
new Color(230, 150, 150, 20),
new Color(230, 230, 180, 50),
90
)
);
 
$plot->xAxis->label->hideFirst(TRUE);
$plot->xAxis->label->hideLast(TRUE);
$plot->xAxis->setNumberByTick('minor', 'major', 2);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/line-007.php
New file
0,0 → 1,70
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
 
$graph = new Graph(300, 200);
 
$graph->setAntiAliasing(TRUE);
 
$group = new PlotGroup;
$group->grid->setType(Line::DASHED);
 
$group->setPadding(40, NULL, 20, NULL);
 
$group->axis->left->setLabelNumber(8);
$group->axis->left->setLabelPrecision(1);
$group->axis->left->setTickStyle(Tick::OUT);
 
$x = array(2, 4, 8, 16, 32, 48, 56, 60, 62);
 
$plot = new LinePlot($x);
$plot->setColor(new Orange());
$plot->setFillColor(new LightOrange(80));
 
$plot->mark->setType(Mark::CIRCLE);
$plot->mark->setFill(new MidRed);
$plot->mark->setSize(6);
 
$group->legend->add($plot, "John", Legend::MARK);
$group->add($plot);
 
$x = array(NULL, NULL, NULL, 10, 12, 14, 18, 26, 42);
 
$plot = new LinePlot($x);
$plot->setColor(new Color(120, 120, 30, 10));
$plot->setFillColor(new Color(120, 120, 60, 90));
 
$plot->mark->setType(Mark::SQUARE);
$plot->mark->setFill(new DarkGreen);
$plot->mark->setSize(5);
 
$group->add($plot);
 
function setYear($value) {
return $value + 2000;
}
 
$group->axis->bottom->label->setCallbackFunction('setYear');
 
function setK($value) {
return round($value).'K';
}
 
$group->axis->left->label->setCallbackFunction('setK');
 
$group->legend->add($plot, "George", Legend::MARK);
$group->legend->setPosition(0.45, 0.25);
$group->legend->shadow->smooth(TRUE);
 
$graph->add($group);
 
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/mini-003.php
New file
0,0 → 1,56
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
 
$graph = new Graph(150, 100);
 
$x = array();
 
for($i = 0; $i < 8; $i++) {
$x[] = cos($i / 3 * M_PI) + mt_rand(-10, 10) / 40;
}
 
$plot = new LinePlot($x);
$plot->setPadding(22, 5, 25, 8);
 
// Hide grid
$plot->grid->setType(Line::DASHED);
 
// Change background color
$plot->setBackgroundColor(new Color(240, 240, 240, 50));
 
// Set Y on both left and rights sides
$plot->setYAxis(Plot::BOTH);
 
// Change line properties
$plot->setColor(new Color(0, 0, 0));
$plot->setFillColor(new Color(240, 190, 130, 50));
 
// Chenge ticks and labels interval
$plot->xAxis->setTickInterval(2);
$plot->xAxis->label->hide(TRUE);
$plot->xAxis->setNumberByTick('minor', 'major', 1);
 
// Hide first and last values on X axis
$plot->xAxis->label->hideFirst(TRUE);
$plot->xAxis->label->hideLast(TRUE);
 
// Add a title
$plot->title->set("Random values");
$plot->title->move(0, 2);
$plot->title->setFont(new Tuffy(8));
$plot->title->setBackgroundColor(new Color(255, 255, 255, 25));
$plot->title->border->show();
$plot->title->setPadding(2, 2, 2, 2);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/mini-004.php
New file
0,0 → 1,59
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
 
$graph = new Graph(150, 100);
 
$graph->setAntiAliasing(TRUE);
 
$x = array(
1, 2, 5, 4, 2, 3
);
 
$plot = new LinePlot($x);
 
// Change component padding
$plot->setPadding(10, 12, 12, 7);
 
// Set a background gradient
$plot->setBackgroundGradient(
new LinearGradient(
new Color(230, 230, 230),
new Color(255, 255, 255),
0
)
);
 
// Change line background color
$plot->setFillGradient(
new LinearGradient(
new Color(200, 240, 215, 30),
new Color(150, 190, 165, 30),
0
)
);
 
// Hide grid
$plot->grid->hide(TRUE);
$plot->grid->setNobackground();
 
$plot->yAxis->label->hide(TRUE);
$plot->xAxis->label->hide(TRUE);
 
$plot->label->set($x);
$plot->label->setBackgroundColor(new Color(240, 240, 240, 10));
$plot->label->border->setColor(new Color(255, 0, 0, 15));
$plot->label->setPadding(3, 2, 0, 0);
$plot->label->setFont(new Font1);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/mini-005.php
New file
0,0 → 1,46
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
$graph = new Graph(150, 100);
 
$graph->setAntiAliasing(TRUE);
 
$x = array();
for($i = 0; $i < 10; $i++) {
$x[] = mt_rand(1, 99) / 10;
}
 
$plot = new LinePlot($x);
$plot->setBackgroundColor(new Color(240, 240, 240));
$plot->setPadding(30, 8, 8, 20);
 
$plot->setColor(
new Color(60, 60, 150)
);
$plot->setFillGradient(
new LinearGradient(
new Color(120, 175, 80, 47),
new Color(231, 172, 113, 30),
0
)
);
 
$plot->grid->setType(Line::DASHED);
 
$plot->yAxis->setLabelNumber(2);
$plot->yAxis->setLabelPrecision(1);
 
$plot->xAxis->setLabelInterval(2);
$plot->xAxis->setNumberByTick('minor', 'major', 2);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/mini-006.php
New file
0,0 → 1,53
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
// Return a random color
function color($a = NULL) {
return new Color(mt_rand(20, 180), mt_rand(20, 180), mt_rand(20, 180), $a);
}
 
function formatLabel($value) {
return sprintf("%.2f", $value);
}
 
$graph = new Graph(150, 100);
 
$graph->setAntiAliasing(TRUE);
 
$group = new PlotGroup;
$group->setXAxisZero(FALSE);
$group->setBackgroundColor(new Color(197, 180, 210, 80));
 
$group->setPadding(25, 10, 10, 20);
 
$group->axis->left->setLabelNumber(2);
$group->axis->left->setLabelPrecision(1);
 
// Display two lines
for($n = 0; $n < 2; $n++) {
 
$x = array();
for($i = 0; $i < 10; $i++) {
$x[] = (cos($i * M_PI / 5)) / ($n + 1);
}
$plot = new LinePlot($x);
$plot->setColor(color(10)); // Random line color
$plot->setFillColor(color(90)); // Random background color
$group->add($plot);
}
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/logo.php
New file
0,0 → 1,51
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
 
$graph = new Graph(500, 100);
 
$graph->setAntiAliasing(TRUE);
$graph->border->hide();
 
$x = array();
for($i = 0; $i < 20; $i++) {
$x[] = mt_rand(4, 12);
}
 
$plot = new LinePlot($x);
 
$plot->setSpace(0, 0, 50, 0);
$plot->setPadding(3, 3, 3, 3);
 
$plot->setBackgroundGradient(
new LinearGradient(
new Color(230, 230, 230),
new Color(255, 255, 255),
0
)
);
 
$plot->setColor(new Color(0, 0, 180, 20));
 
$plot->setFillGradient(
new LinearGradient(
new Color(220, 220, 230, 25),
new Color(240, 240, 255, 25),
90
)
);
 
$plot->xAxis->hide(TRUE);
$plot->yAxis->hide(TRUE);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/bar-001.php
New file
0,0 → 1,80
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../BarPlot.class.php";
 
 
$graph = new Graph(280, 200);
 
$graph->setAntiAliasing(TRUE);
 
$x = array(
1, 2, 5, 0.5, 3, 8, 6
);
 
$plot = new BarPlot($x);
 
$plot->setSpace(4, 4, 10, 0);
$plot->setPadding(40, 15, 10, 40);
 
$plot->title->set("Zoé and friends");
$plot->title->setFont(new TuffyBold(11));
$plot->title->border->show();
$plot->title->setBackgroundColor(new Color(255, 255, 255, 25));
$plot->title->setPadding(4, 4, 4, 4);
$plot->title->move(-20, 25);
 
$plot->yAxis->title->set("Axe des Y");
$plot->yAxis->title->setFont(new TuffyBold(10));
$plot->yAxis->title->move(-4, 0);
$plot->yAxis->setTitleAlignment(Label::TOP);
 
$plot->xAxis->title->set("Axe des X");
$plot->xAxis->title->setFont(new TuffyBold(10));
$plot->xAxis->setTitleAlignment(Label::RIGHT);
 
$plot->setBackgroundGradient(
new LinearGradient(
new Color(230, 230, 230),
new Color(255, 255, 255),
0
)
);
 
$plot->barBorder->setColor(new Color(0, 0, 150, 20));
 
$plot->setBarGradient(
new LinearGradient(
new Color(150, 150, 210, 0),
new Color(230, 230, 255, 30),
0
)
);
 
$y = array(
'Zoé',
'Yvan',
'Fred',
'Lucie',
'Ilia',
'Nino',
'Marie'
);
 
$plot->xAxis->setLabelText($y);
$plot->xAxis->label->setFont(new TuffyBold(7));
 
$graph->shadow->setSize(4);
$graph->shadow->setPosition(Shadow::LEFT_TOP);
$graph->shadow->smooth(TRUE);
$graph->shadow->setColor(new Color(160, 160, 160));
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/scatter-001.php
New file
0,0 → 1,69
<?php
 
require_once "../../ScatterPlot.class.php";
 
$graph = new Graph(280, 280);
 
$graph->title->move(-40, 0);
$graph->title->set('Two circles');
 
$group = new PlotGroup;
$group->setBackgroundGradient(
new LinearGradient(
new VeryLightGray,
new Color(245, 245, 245),
0
)
);
 
$group->setPadding(25, 20, 40, 15);
$group->setSpace(5, 5, 5, 5);
 
$group->legend->setPosition(0.82, 0.1);
$group->legend->setAlign(Legend::CENTER, Legend::MIDDLE);
 
function getCircle($size) {
 
$center = 0;
$x = array();
$y = array();
for($i = 0; $i <= 20; $i++) {
$rad = ($i / 20) * 2 * M_PI;
$x[] = $center + cos($rad) * $size;
$y[] = $center + sin($rad) * $size;
}
return array($x, $y);
}
 
list($x, $y) = getCircle(3);
 
$plot = new ScatterPlot($y, $x);
 
$plot->link(TRUE, new DarkBlue);
 
$plot->mark->setFill(new DarkPink);
$plot->mark->setType(Mark::CIRCLE, 6);
 
$group->legend->add($plot, 'Circle #1', Legend::MARK);
$group->add($plot);
 
list($x, $y) = getCircle(5);
 
$plot = new ScatterPlot($y, $x);
 
$plot->link(TRUE, new DarkGreen);
 
$plot->mark->setFill(new DarkOrange);
$plot->mark->setType(Mark::SQUARE, 4);
 
$group->legend->add($plot, 'Circle #2', Legend::MARK);
$group->add($plot);
 
$graph->add($group);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/bar-002.php
New file
0,0 → 1,80
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../BarPlot.class.php";
 
$graph = new Graph(280, 280);
 
$graph->setAntiAliasing(TRUE);
 
$group = new PlotGroup;
$group->setSpace(6, 6, 5, 5);
$group->setBackgroundGradient(
new LinearGradient(
new Color(235, 235, 235),
new White(),
0
)
);
$group->setPadding(40, 10, 10, 50);
 
$group->axis->left->setLabelPrecision(2);
$group->axis->bottom->label->hide(TRUE);
$group->axis->bottom->hideTicks(TRUE);
 
$group->grid->setType(Line::DASHED);
$group->grid->hideHorizontal(TRUE);
 
$gradients = array(
new LinearGradient(
new Color(30, 30, 160, 10), new Color(120, 120, 160, 10), 0
),
new LinearGradient(
new Color(30, 160, 30, 10), new Color(120, 160, 120, 10), 0
),
new LinearGradient(
new Color(160, 30, 30, 10), new Color(160, 120, 120, 10), 0
)
);
 
for($n = 0; $n < 3; $n++) {
 
$x = array();
for($i = 0; $i < 6; $i++) {
$x[] = (cos($i * M_PI / 100) / ($n + 1) * mt_rand(600, 900) / 1000 - 0.5) * (($n%2) ? -0.5 : 1) + (($n%2) ? -0.4 : 0);
}
$plot = new BarPlot($x, $n + 1, 3);
$plot->setXAxis(Plot::BOTTOM);
$plot->barShadow->setSize(1);
$plot->barShadow->setPosition(Shadow::RIGHT_TOP);
$plot->barShadow->setColor(new Color(160, 160, 160, 10));
$plot->barBorder->setColor($gradients[$n]->from);
 
$plot->setBarGradient($gradients[$n]);
$plot->setBarSpace(2);
$group->legend->add($plot, 'Bar#'.($n + 1), Legend::BACKGROUND);
$group->add($plot);
}
 
$group->legend->setModel(Legend::MODEL_BOTTOM);
$group->legend->setPosition(NULL, 0.86);
$group->legend->shadow->hide();
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/scatter-002.php
New file
0,0 → 1,30
<?php
 
require_once "../../ScatterPlot.class.php";
 
$graph = new Graph(300, 240);
 
$graph->title->set('Simple ScatterPlot');
$graph->shadow->setSize(4);
 
$y = array(1, 1.3, 1.8, 1.6, 10, 7, 8, 3, 4, 2, 4);
$x = array(0.5, 0.7, 0.65, 0.9, 0.5, 1.5, 4, 3, 5, 2, 2);
 
$plot = new ScatterPlot($y, $x);
$plot->setBackgroundColor(new Color(255, 245, 220));
 
$plot->mark->setSize(15);
$plot->mark->setFill(
new RadialGradient(
new LightRed,
new Red
)
);
 
$plot->setSpace(6, 6, 6, 0);
$plot->setPadding(25, NULL, 40, 20);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/bar-003.php
New file
0,0 → 1,73
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../BarPlot.class.php";
 
function color($a = NULL) {
if($a === NULL) {
$a = 0;
}
return new Color(mt_rand(20, 180), mt_rand(20, 180), mt_rand(20, 180), $a);
}
 
$graph = new Graph(300, 200);
 
$graph->setAntiAliasing(TRUE);
$graph->border->hide();
 
$group = new PlotGroup;
$group->setSpace(5, 10, 20, 15);
$group->setPadding(40, 10, NULL, 20);
$group->setXAxisZero(FALSE);
 
$group->axis->left->setLabelPrecision(2);
 
$colors = array(
new Color(100, 180, 154, 12),
new Color(100, 154, 180, 12),
new Color(154, 100, 180, 12),
new Color(180, 100, 154, 12)
);
 
for($n = 0; $n < 4; $n++) {
 
$x = array();
for($i = 0; $i < 6; $i++) {
$x[] = (cos($i * M_PI / 100) / ($n + 1) * mt_rand(600, 1400) / 1000 - 0.5);
}
$plot = new BarPlot($x, 1, 1, (3 - $n) * 7);
$plot->barBorder->setColor(new Color(0, 0, 0));
$plot->setBarSize(0.54);
$plot->barShadow->setSize(3);
$plot->barShadow->setPosition(Shadow::RIGHT_TOP);
$plot->barShadow->setColor(new Color(160, 160, 160, 10));
$plot->barShadow->smooth(TRUE);
 
$plot->setBarColor($colors[$n]);
$group->add($plot);
$group->legend->add($plot, "Barre #".$n, Legend::BACKGROUND);
}
 
$group->legend->shadow->setSize(0);
$group->legend->setAlign(Legend::CENTER);
$group->legend->setSpace(6);
$group->legend->setTextFont(new Tuffy(8));
$group->legend->setPosition(0.50, 0.12);
$group->legend->setBackgroundColor(new Color(255, 255, 255, 25));
$group->legend->setColumns(2);
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/scatter-003.php
New file
0,0 → 1,34
<?php
 
require_once "../../ScatterPlot.class.php";
 
$graph = new Graph(300, 280);
 
$graph->title->set('Linked ScatterPlot');
$graph->title->setFont(new TuffyItalic(14));
$graph->shadow->setSize(4);
 
$y = array(1, 10, 7, 8, 5, 4, 2, 4);
$x = array(0.5, 0.5, 1.5, 4, 3, 5, 2, 2);
 
$plot = new ScatterPlot($y, $x);
$plot->setBackgroundColor(new Color(235, 235, 235));
 
$plot->mark->setSize(15);
$plot->mark->setFill(
new RadialGradient(
new LightGreen,
new DarkGreen
)
);
 
$plot->link(TRUE);
$plot->setColor(new DarkGreen);
 
$plot->setSpace(6, 6, 6, 0);
$plot->setPadding(25, NULL, 40, 20);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/bar-004.php
New file
0,0 → 1,92
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../BarPlot.class.php";
 
function labelFormat($value) {
return round($value, 2);
}
 
$graph = new Graph(280, 200);
 
$graph->setAntiAliasing(TRUE);
 
$group = new PlotGroup;
$group->setSpace(5, 5, 15, 0);
$group->setPadding(40, 40);
 
$group->axis->left->setLabelPrecision(2);
$group->axis->right->setLabelPrecision(2);
 
$colors = array(
new Color(80, 105, 190, 10),
new Color(105, 190, 80, 10)
);
 
$darkColor = array(
new Color(40, 55, 120, 10),
new Color(55, 120, 40, 10)
);
 
$axis = array(
Plot::LEFT,
Plot::RIGHT
);
 
$group->axis->left->setColor($darkColor[0]);
$group->axis->left->label->setColor($darkColor[0]);
$group->axis->right->setColor($darkColor[1]);
$group->axis->right->label->setColor($darkColor[1]);
 
$group->setBackgroundGradient(
new LinearGradient(
new Color(225, 225, 225),
new Color(255, 255, 255),
0
)
);
 
for($n = 0; $n < 2; $n++) {
 
$x = array();
for($i = 0; $i < 4; $i++) {
$x[] = (cos($i * M_PI / 100) / ($n + 1) * mt_rand(700, 1300) / 1000 - 0.5) * (($n%2) ? -0.5 : 1) + (($n%2) ? -0.4 : 0) + 1;
}
$plot = new BarPlot($x, $n+1, 2);
$plot->barBorder->setColor(new Color(0, 0, 0, 30));
$plot->setBarPadding(0.1, 0.1);
$plot->setBarSpace(5);
$plot->barShadow->setSize(3);
$plot->barShadow->setPosition(Shadow::RIGHT_TOP);
$plot->barShadow->setColor(new Color(180, 180, 180, 10));
$plot->barShadow->smooth(TRUE);
 
$plot->label->set($x);
$plot->label->move(0, -6);
$plot->label->setFont(new Tuffy(7));
$plot->label->setAngle(90);
$plot->label->setAlign(NULL, Label::TOP);
$plot->label->setPadding(3, 1, 0, 6);
$plot->label->setCallbackFunction("labelFormat");
 
$plot->setBarColor($colors[$n]);
$plot->setYAxis($axis[$n]);
$group->add($plot);
}
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/bar-005.php
New file
0,0 → 1,82
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../BarPlot.class.php";
 
$graph = new Graph(300, 200);
 
$graph->setAntiAliasing(TRUE);
$graph->border->hide();
 
$group = new PlotGroup;
$group->grid->hide(TRUE);
$group->setSpace(2, 2, 20, 0);
$group->setPadding(30, 10, NULL, NULL);
 
$colors = array(
new Orange(25),
new LightBlue(10)
);
 
for($n = 0; $n < 2; $n++) {
 
$x = array();
for($i = 0; $i < 3 - $n * 3; $i++) {
$x[] = NULL;
}
for($i = 3 - ($n * 3); $i < 12 - ($n * 3); $i++) {
$x[] = cos($i * M_PI / 100) * mt_rand(800, 1200) / 1000 * (((1 - $n) * 5 + 10) / 10);
}
for($i = 0; $i < $n * 3; $i++) {
$x[] = NULL;
}
$plot = new BarPlot($x, 1, 1, (1 - $n) * 6);
// $plot->setBarPadding(2, 2);
$plot->barShadow->setSize(2);
$plot->barShadow->setPosition(Shadow::RIGHT_TOP);
$plot->barShadow->setColor(new Color(160, 160, 160, 10));
$plot->barShadow->smooth(TRUE);
 
$plot->setBarColor($colors[$n]);
$group->add($plot);
$group->legend->add($plot, $n + date('Y'), Legend::BACKGROUND);
}
 
function setPc($value) {
return round($value * 10).'%';
}
 
$group->axis->left->label->setCallbackFunction('setPc');
 
$months = array(
"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
);
 
$group->axis->bottom->setLabelText($months);
$group->axis->bottom->hideTicks(TRUE);
 
$group->legend->shadow->setSize(0);
$group->legend->setAlign(Legend::CENTER);
$group->legend->setSpace(6);
$group->legend->setTextFont(new Tuffy(8));
$group->legend->setPosition(0.50, 0.10);
$group->legend->setBackgroundColor(new Color(255, 255, 255, 25));
$group->legend->setColumns(2);
 
$graph->add($group);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/canvas-001.php
New file
0,0 → 1,68
<?php
 
require_once "../../Graph.class.php";
 
$graph = new Graph(300, 200);
 
$driver = $graph->getDriver();
 
$driver->filledRectangle(
new Color(230, 230, 230, 0),
new Line(
new Point(10, 10),
new Point(200, 150)
)
);
 
for($i = 7; $i < 400; $i += 15) {
$driver->line(
new Color(0, 0, 0),
new Line(
new Point($i, 0 + 50),
new Point($i, 30 + 50)
)
);
}
 
for($i = 7; $i < 30; $i += 15) {
$driver->line(
new Color(0, 0, 0),
new Line(
new Point(0, $i + 50),
new Point(400, $i + 50)
)
);
}
 
$driver->filledRectangle(
new Color(0, 100, 200, 50),
new Line(
new Point(100, 100),
new Point(280, 180)
)
);
 
$debut = new Color(230, 250, 0);
$fin = new Color(255, 255, 255, 100);
 
$driver->filledEllipse(
new RadialGradient(
$debut,
$fin
),
new Point(105, 135),
90, 90
);
 
$text = new Text(
"Artichow !",
new Tuffy(15),
new Color(0, 0, 80),
45
);
 
$driver->string($text, new Point(210, 75));
 
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/pie-001.php
New file
0,0 → 1,42
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../Pie.class.php";
 
 
$graph = new Graph(300, 175);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Stats");
$graph->title->setFont(new TuffyItalic(16));
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values, Pie::EARTH);
$plot->setCenter(0.4, 0.55);
$plot->setSize(0.7, 0.6);
$plot->set3D(10);
$plot->explode(array(1 => 14, 4 => 20, 0 => 10));
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->legend->setPosition(1.3);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/impulse-001.php
New file
0,0 → 1,36
<?php
 
require_once "../../ScatterPlot.class.php";
 
$graph = new Graph(300, 200);
 
$graph->title->set('Impulses');
$graph->shadow->setSize(4);
 
$y = array();
for($i = 0; $i < 40; $i++) {
$y[] = cos($i / 15 * 2 * M_PI) / (0.8 + $i / 15) * 4;
}
 
$plot = new ScatterPlot($y);
$plot->setPadding(25, 15, 35, 15);
$plot->setBackgroundColor(new Color(230, 230, 255));
$plot->setSpace(2, 2);
 
// Set impulses
$plot->setImpulse(new DarkBlue);
 
$plot->grid->hideVertical();
$plot->grid->setType(Line::DASHED);
 
// Hide ticks
$plot->xAxis->hideTicks();
$plot->xAxis->label->hide();
 
$plot->mark->setType(Mark::SQUARE);
$plot->mark->setSize(4);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/pie-002.php
New file
0,0 → 1,50
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../Pie.class.php";
 
 
$graph = new Graph(300, 175);
$graph->setBackgroundGradient(
new LinearGradient(
new White,
new VeryLightGray(40),
0
)
);
$graph->title->set("Horses");
$graph->shadow->setSize(5);
$graph->shadow->smooth(TRUE);
$graph->shadow->setPosition(Shadow::LEFT_BOTTOM);
$graph->shadow->setColor(new DarkGray);
 
$values = array(8, 4, 6, 2, 5);
 
$plot = new Pie($values);
$plot->setCenter(0.35, 0.55);
$plot->setSize(0.7, 0.6);
$plot->set3D(10);
$plot->setLabelPosition(10);
 
$plot->setLegend(array(
'France',
'Spain',
'Italy',
'Germany',
'England'
));
 
$plot->legend->setPosition(1.40);
$plot->legend->shadow->setSize(0);
$plot->legend->setBackgroundColor(new VeryLightGray(30));
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/pie-003.php
New file
0,0 → 1,52
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../Pie.class.php";
 
 
$graph = new Graph(300, 175);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Customized colors");
$graph->title->setFont(new Tuffy(12));
$graph->title->move(80, 10);
 
$values = array(16, 9, 13, 23);
$colors = array(
new LightOrange,
new LightPurple,
new LightBlue,
new LightRed,
new LightPink
);
 
$plot = new Pie($values, $colors);
$plot->setCenter(0.3, 0.53);
$plot->setAbsSize(200, 200);
$plot->setBorderColor(new White);
$plot->setStartAngle(234);
 
$plot->setLegend(array(
'Arthur',
'Abel',
'Pascal',
'Thamer'
));
 
$plot->setLabelPosition(-40);
$plot->label->setPadding(2, 2, 2, 2);
$plot->label->setFont(new Tuffy(7));
$plot->label->setBackgroundColor(new White(60));
 
$plot->legend->setPosition(1.38);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/pie-004.php
New file
0,0 → 1,53
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../Pie.class.php";
 
 
$graph = new Graph(300, 175);
$graph->setBackgroundGradient(
new LinearGradient(
new VeryLightGray(40),
new White,
90
)
);
$graph->title->set("Arbitrary labels");
$graph->title->setAngle(90);
$graph->title->move(120, NULL);
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values);
$plot->setCenter(0.45, 0.5);
$plot->setSize(0.55, 0.55 * 300 / 175);
 
$plot->label->set(array(
'Arthur', 'Abel', 'Bernard', 'Thierry', 'Paul', 'Gaston', 'Joe'
));
 
$plot->label->setCallbackFunction(NULL); // We must disable the default callback function
$plot->setLabelPosition(10);
 
$plot->setLegend(array(
'ABC',
'DEF',
'GHI',
'JKL',
'MNO',
'PQR',
'STU'
));
 
$plot->legend->hide(TRUE);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/pie-005.php
New file
0,0 → 1,51
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../Pie.class.php";
 
function createPie($values, $title, $x, $y) {
$plot = new Pie($values, Pie::EARTH);
$plot->title->set($title);
$plot->title->setFont(new TuffyBold(9));
$plot->title->move(NULL, -12);
$plot->label->setFont(new Tuffy(7));
$plot->legend->hide(TRUE);
$plot->setLabelPosition(5);
$plot->setSize(0.48, 0.35);
$plot->setCenter($x, $y);
$plot->set3D(8);
$plot->setBorderColor(new White);
return $plot;
 
}
 
$graph = new Graph(280, 350);
$graph->setAntiAliasing(TRUE);
 
$plot = createPie(array(1, 4, 5, 2, 3), "Cowléoptère", 0.25, 0.24);
$graph->add($plot);
 
$plot = createPie(array(1, 9, 1, 2, 1), "Asticow", 0.75, 0.24);
$graph->add($plot);
 
$plot = createPie(array(5, 7, 8, 6, 3), "Cowlibri", 0.25, 0.65);
$graph->add($plot);
 
$plot = createPie(array(6, 4, 6, 5, 6), "Bourricow", 0.75, 0.65);
$plot->legend->setModel(Legend::MODEL_BOTTOM);
$plot->setLegend(array('plip', 'plop', 'plap', 'plup', 'plep'));
$plot->legend->hide(FALSE); // We print only one legend
$plot->legend->setPosition(0, 1.10);
$graph->add($plot);
 
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/line-001.php
New file
0,0 → 1,71
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
 
$graph = new Graph(300, 175);
 
$graph->setAntiAliasing(TRUE);
 
$x = array(
3, 1, 5, 6, 3, 8, 6
);
 
$plot = new LinePlot($x);
 
$plot->grid->setNoBackground();
 
$plot->title->set("Filled line and marks");
$plot->title->setFont(new Tuffy(10));
$plot->title->setBackgroundColor(new Color(255, 255, 255, 25));
$plot->title->border->show();
$plot->title->setPadding(3, 3, 3, 3);
$plot->title->move(-20, 25);
 
$plot->setSpace(4, 4, 10, 0);
$plot->setPadding(25, 15, 10, 18);
 
$plot->setBackgroundGradient(
new LinearGradient(
new Color(210, 210, 210),
new Color(255, 255, 255),
0
)
);
 
$plot->setColor(new Color(0, 0, 150, 20));
 
$plot->setFillGradient(
new LinearGradient(
new Color(150, 150, 210),
new Color(245, 245, 245),
0
)
);
 
$plot->mark->setType(Mark::CIRCLE);
$plot->mark->border->show();
 
$y = array(
'Lundi',
'Mardi',
'Mercredi',
'Jeudi',
'Vendredi',
'Samedi',
'Dimanche'
);
 
$plot->xAxis->setLabelText($y);
$plot->xAxis->label->setFont(new Tuffy(7));
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/site/line-002.php
New file
0,0 → 1,62
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../../LinePlot.class.php";
 
 
$graph = new Graph(300, 175);
 
$graph->setAntiAliasing(TRUE);
 
$x = array(
4, 3, 1, 0, -2, 1, 3, 2, 3, 5, 4, 1
);
 
$plot = new LinePlot($x);
$plot->setXAxisZero(FALSE);
 
$plot->grid->hide(TRUE);
 
$plot->title->set("Using dashed line and legend");
$plot->title->setFont(new TuffyItalic(9));
$plot->title->setBackgroundColor(new Color(255, 255, 255, 50));
$plot->title->setPadding(3, 3, 3, 3);
$plot->title->move(0, 20);
 
$plot->setSpace(6, 6, 10, 10);
$plot->setPadding(30, 10, 15, 25);
 
$plot->setBackgroundColor(
new Color(245, 245, 245)
);
 
$plot->setStyle(Line::DASHED);
$plot->setColor(new Color(0, 150, 0, 20));
 
$plot->setFillGradient(
new LinearGradient(
new Color(220, 220, 150, 40),
new Color(255, 255, 210, 30),
0
)
);
 
$graph->shadow->setSize(4);
$graph->shadow->setPosition(Shadow::LEFT_BOTTOM);
$graph->shadow->smooth(TRUE);
 
$plot->legend->add($plot, "Apples");
$plot->legend->shadow->setSize(0);
$plot->legend->setAlign(Legend::CENTER, Legend::TOP);
$plot->legend->setPosition(0.75, 0.60);
$plot->legend->setTextFont(new Tuffy(8));
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-014.php
New file
0,0 → 1,48
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
function createPie($values, $title, $x, $y) {
$plot = new Pie($values);
$plot->title->set($title);
$plot->title->setFont(new TuffyBold(8));
$plot->title->move(NULL, -12);
$plot->label->setFont(new Tuffy(7));
$plot->legend->hide(TRUE);
$plot->setLabelPosition(5);
$plot->setSize(0.40, 0.40);
$plot->setCenter($x, $y);
$plot->setBorderColor(new Black);
return $plot;
 
}
 
$graph = new Graph(400, 400);
$graph->setAntiAliasing(TRUE);
 
$plot = createPie(array(1, 4, 5, 2, 3), "Cowléoptère", 0.22, 0.25);
$graph->add($plot);
 
$plot = createPie(array(1, 9, 1, 2, 1), "Asticow", 0.66, 0.25);
$graph->add($plot);
 
$plot = createPie(array(5, 7, 8, 6, 3), "Cowlibri", 0.22, 0.75);
$graph->add($plot);
 
$plot = createPie(array(6, 4, 6, 5, 6), "Bourricow", 0.66, 0.75);
$plot->legend->hide(FALSE); // We print only one legend
$plot->legend->setPosition(1.25, 0);
$graph->add($plot);
 
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/champignon.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/examples/champignon.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-015.php
New file
0,0 → 1,50
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 300);
$graph->setBackgroundGradient(
new LinearGradient(
new VeryLightGray,
new White,
0
)
);
$graph->title->set("Pie (example 15) - Arbitrary labels");
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values);
$plot->setCenter(0.4, 0.55);
$plot->setSize(0.6, 0.6 * 4 / 3);
 
$plot->label->set(array(
'Arthur', 'Abel', 'Bernard', 'Thierry', 'Paul', 'Gaston', 'Joe'
));
$plot->label->setCallbackFunction(NULL); // We must disable the default callback function
 
$plot->setLegend(array(
'ABC',
'DEF',
'GHI',
'JKL',
'MNO',
'PQR',
'STU'
));
 
$plot->legend->setPosition(1.3);
$plot->legend->setBackgroundColor(new VeryLightGray(30));
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-016.php
New file
0,0 → 1,45
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Pie (example 13) - Adjusting labels");
 
$values = array(16, 9, 13, 23, 10);
 
$plot = new Pie($values, Pie::EARTH);
$plot->setCenter(0.4, 0.55);
$plot->setAbsSize(220, 220);
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->setLabelPosition(-40);
$plot->label->setPadding(2, 2, 2, 2);
$plot->label->setFont(new Tuffy(7));
$plot->label->setBackgroundColor(new White(60));
 
$plot->legend->setPosition(1.3);
$plot->legend->shadow->setSize(0);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-017.php
New file
0,0 → 1,48
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Pie (example 17)");
$graph->title->setFont(new Tuffy(14));
 
$values = array(12, 16, 13, 18, 10, 20, 11);
 
$plot = new Pie($values, Pie::AQUA);
$plot->setCenter(0.4, 0.55);
$plot->setAbsSize(180, 180);
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$explode = array();
for($i = 0; $i < count($values); $i++) {
$explode[] = 15;
}
 
$plot->explode($explode);
 
$plot->legend->setPosition(1.5);
$plot->legend->shadow->setSize(0);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-018.php
New file
0,0 → 1,32
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Pie (example 18) - Display labels > 10 %");
$graph->title->setFont(new Tuffy(14));
 
$values = array(1, 5, 6, 16, 18, 19, 21, 3, 4, 7, 6);
 
$plot = new Pie($values);
$plot->setCenter(0.4, 0.55);
$plot->setAbsSize(180, 180);
$plot->setLabelMinimum(10);
 
$plot->legend->setPosition(1.5);
$plot->legend->shadow->setSize(0);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/line-010.php
New file
0,0 → 1,46
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../LinePlot.class.php";
 
$graph = new Graph(375, 200);
 
// Set title
$graph->title->set('Star marks');
$graph->title->setFont(new Tuffy(12));
$graph->title->setColor(new DarkRed);
 
$plot = new LinePlot(array(5, 3, 4, 7, 6, 5, 8, 4, 7));
 
// Change plot size and position
$plot->setSize(0.76, 1);
$plot->setCenter(0.38, 0.5);
 
$plot->setPadding(30, 15, 38, 25);
$plot->setColor(new Orange());
$plot->setFillColor(new LightOrange(80));
 
// Change grid style
$plot->grid->setType(Line::DASHED);
 
// Add customized marks
$plot->mark->setType(Mark::STAR);
$plot->mark->setFill(new MidRed);
$plot->mark->setSize(6);
 
// Change legend
$plot->legend->setPosition(1, 0.5);
$plot->legend->setAlign(Legend::LEFT);
$plot->legend->shadow->smooth(TRUE);
 
$plot->legend->add($plot, 'My line', Legend::MARK);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/math-001.php
New file
0,0 → 1,23
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../MathPlot.class.php";
 
 
$graph = new Graph(300, 300);
 
$plot = new MathPlot(-3, 3, 3, -3);
$plot->setInterval(0.1);
 
$function = new MathFunction('cos');
$plot->add($function);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/math-002.php
New file
0,0 → 1,36
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../MathPlot.class.php";
 
 
$graph = new Graph(300, 300);
 
// Set graph title
$graph->title->set('f(x) = x * x');
$graph->title->setBackgroundColor(new White(0));
$graph->title->setPadding(NULL, NULL, 10, 10);
$graph->title->move(0, -10);
 
$plot = new MathPlot(-3, 3, 10, -2);
$plot->setInterval(0.2);
$plot->setPadding(NULL, NULL, NULL, 20);
 
// Defines x²
function x2($x) {
return $x * $x;
}
 
$function = new MathFunction('x2');
$function->setColor(new Orange);
$plot->add($function);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/math-003.php
New file
0,0 → 1,33
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../MathPlot.class.php";
 
 
$graph = new Graph(300, 300);
 
$plot = new MathPlot(-3, 3, 20, -1);
$plot->setInterval(0.2);
$plot->setPadding(NULL, NULL, NULL, 20);
 
$plot->yAxis->setLabelInterval(4);
 
$function = new MathFunction('exp');
$function->setColor(new DarkRed);
$function->mark->setType(Mark::SQUARE);
$function->mark->setSize(3);
$function->mark->setFill(new DarkBlue);
$plot->add($function, "f(x) = exp(x)", Legend::MARK);
 
$plot->legend->setPosition(0.4, 0.2);
$plot->legend->setPadding(3, 3, 3, 3, 3);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/test/multi-line-text.php
New file
0,0 → 1,37
<?php
 
require_once "../../Graph.class.php";
 
$graph = new Graph(400, 600);
 
$driver = $graph->getDriver();
 
$driver->filledRectangle(
new Red,
new Line(
new Point(200, 0),
new Point(200, 600)
)
);
 
$text = new Text(
"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean gravida quam semper nibh. Sed orci. Aenean ullamcorper magna eget odio. Sed nonummy ante sit amet sapien.\nPhasellus nulla dui, aliquet vel, adipiscing vel, vulputate sed, velit.\nSed at neque vel ipsum commodo hendrerit.\nA. Nonyme",
new Tuffy(mt_rand(10, 15)),
new Color(mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)),
0
);
 
$driver->string($text, new Point(0, 0), 200);
 
$text = new Text(
"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean gravida quam semper nibh. Sed orci. Aenean ullamcorper magna eget odio. Sed nonummy ante sit amet sapien.\nPhasellus nulla dui, aliquet vel, adipiscing vel, vulputate sed, velit.\nSed at neque vel ipsum commodo hendrerit.\nA. Nonyme",
new Font(mt_rand(2, 4)),
new Color(mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)),
0
);
 
$driver->string($text, new Point(0, 400), 200);
 
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/test/set-label-text-error.php
New file
0,0 → 1,58
<?php
require_once '../../BarPlot.class.php';
 
$graph = new Graph(600, 200);
$graph->setAntiAliasing(TRUE);
 
$values = array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0);
 
$plot = new BarPlot($values);
$plot->setBarColor(
new Color(234, 236, 255)
);
$plot->setSpace(5, 5, NULL, NULL);
 
$plot->barShadow->setSize(3);
$plot->barShadow->setPosition(Shadow::RIGHT_TOP);
$plot->barShadow->setColor(new Color(180, 180, 180, 10));
$plot->barShadow->smooth(TRUE);
 
 
$mois = array ('Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun', 'Juil', 'Août', 'Sept', 'Oct', 'Nov', 'Déc');
$label = array ();
foreach ($mois as $m) { $label []= $m; }
$label []= ' ';
foreach ($mois as $m) { $label []= $m; }
 
 
$plot->xAxis->setLabelText($label);
 
/* ICI */
 
$max = array_max($values);
$yValues = array();
for($i=0; $i<= $max; $i++) {
$yValues[]=$i;
}
$plot->yAxis->setLabelText($yValues);
 
// Image::drawError(var_export($yValues, TRUE));
$plot->yAxis->setLabelText($yValues);
 
$plot->setPadding(30,5,20,15);
 
$labelAvant = new Label("2005");
$labelAvant->setFont (new TTFFont(ARTICHOW_FONT.'/TuffyBold.ttf', 12));
$labelAvant->move (180,10);
 
$labelMaintenant = new Label("2006");
$labelMaintenant->setFont (new TTFFont(ARTICHOW_FONT.'/TuffyBold.ttf', 12));
$labelMaintenant->move (450,10);
 
$graph->add($plot);
$graph->addLabel($labelAvant, 0, 0);
$graph->addLabel($labelMaintenant, 0, 0);
 
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/test/error.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/examples/test/error.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/examples/test/error-box.php
New file
0,0 → 1,69
<?php
 
require_once "../../Graph.class.php";
 
 
$message = "Missing imageantialias() function.\nCheck your PHP installation.";
 
 
$message = wordwrap($message, 48, "\n", TRUE);
 
$width = 400;
$height = max(90, 50 + 13 * (substr_count($message, "\n") + 1));
 
$graph = new Graph($width, $height);
 
$driver = $graph->getDriver();
 
// Display title
$driver->filledRectangle(
new White,
new Line(
new Point(0, 0),
new Point($width, $height)
)
);
 
$driver->filledRectangle(
new Red,
new Line(
new Point(0, 0),
new Point(110, 25)
)
);
 
$text = new Text(
"Artichow error",
new Font3,
new White,
0
);
 
$driver->string($text, new Point(5, 6));
 
// Display red box
$driver->rectangle(
new Red,
new Line(
new Point(0, 25),
new Point($width - 90, $height - 1)
)
);
 
// Display error image
$image = new FileImage('error.png');
$driver->copyImage($image, new Point($width - 81, $height - 81), new Point($width - 1, $height - 1));
 
// Draw message
$text = new Text(
$message,
new Font2,
new Black,
0
);
 
$driver->string($text, new Point(10, 40));
 
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/math-004.php
New file
0,0 → 1,39
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../MathPlot.class.php";
 
 
$graph = new Graph(300, 300);
 
$plot = new MathPlot(-3, 3, 10, -3);
$plot->setInterval(0.2);
$plot->setPadding(NULL, NULL, NULL, 20);
 
$function = new MathFunction('exp');
$function->setColor(new DarkRed);
$function->mark->setType(Mark::SQUARE);
$function->mark->setSize(3);
$function->mark->setFill(new DarkBlue);
$plot->add($function, "f(x) = exp(x)", Legend::MARK);
 
function x2($x) {
return - $x * $x;
}
 
$function = new MathFunction('x2');
$function->setColor(new DarkBlue);
$plot->add($function, "f(x) = - x * x");
 
$plot->legend->setPosition(0.4, 0.4);
$plot->legend->setPadding(3, 3, 3, 3, 3);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/math-005.php
New file
0,0 → 1,34
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../MathPlot.class.php";
 
 
$graph = new Graph(300, 300);
 
$plot = new MathPlot(-3, 3, 2, -3);
$plot->setInterval(0.05);
 
$function = new MathFunction('sqrt', 0);
$plot->add($function, "sqrt(x)");
 
function x2($x) {
return - $x * $x;
}
 
$function = new MathFunction('sin', -2, 2);
$function->setColor(new DarkBlue);
$plot->add($function, "sin(x) (-2 < x < 2)");
 
$plot->legend->setPosition(0.98, 0.8);
$plot->legend->setTextFont(new Tuffy(8));
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/bar-001.php
New file
0,0 → 1,30
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../BarPlot.class.php";
 
$graph = new Graph(400, 400);
$graph->title->set('The title');
$graph->border->setStyle(Line::DASHED);
$graph->border->setColor(new DarkGray);
 
$values = array(19, 42, 15, -25, 3);
 
$plot = new BarPlot($values);
$plot->setSize(1, 0.96);
$plot->setCenter(0.5, 0.52);
 
$plot->setBarColor(
new VeryLightPurple(25)
);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/bar-002.php
New file
0,0 → 1,37
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../BarPlot.class.php";
 
$graph = new Graph(400, 400);
 
$values = array(2, 6, 3, 2, 4);
 
$plot = new BarPlot($values);
 
$plot->setBarGradient(
new LinearGradient(
new LightBlue(25),
new VeryLightOrange(25),
90
)
);
 
$plot->setSpace(5, 5, NULL, NULL);
 
$plot->barShadow->setSize(4);
$plot->barShadow->setPosition(Shadow::RIGHT_TOP);
$plot->barShadow->setColor(new Color(180, 180, 180, 10));
$plot->barShadow->smooth(TRUE);
 
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/bar-003.php
New file
0,0 → 1,37
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../BarPlot.class.php";
 
$graph = new Graph(400, 400);
$graph->title->set('Two bars');
 
$values = array(12, 8, 13, 2, 4);
 
$group = new PlotGroup;
$group->setPadding(NULL, NULL, 35, NULL);
 
$plot = new BarPlot($values, 1, 2);
$plot->setBarColor(new LightBlue(25));
$plot->setBarSpace(5);
 
$group->add($plot);
 
$values = array(1, 7, 2, 10, 6);
 
$plot = new BarPlot($values, 2, 2);
$plot->setBarColor(new LightOrange(25));
$plot->setBarSpace(5);
 
$group->add($plot);
 
$graph->add($group);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/bar-004.php
New file
0,0 → 1,36
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../BarPlot.class.php";
 
$graph = new Graph(400, 400);
$graph->title->set('Two bars with depth');
 
$group = new PlotGroup;
$group->setPadding(NULL, NULL, 35, NULL);
$group->setSpace(5, 5, NULL, NULL);
 
$group->grid->hide(TRUE);
 
$values = array(1, 7, 2, 10, 6, 3, 4, 7);
 
$plot = new BarPlot($values, 1, 1, 5);
$plot->setBarColor(new LightBlue(25));
$group->add($plot);
 
$values = array(12, 8, 13, 2, 4, 8, 4, 3);
 
$plot = new BarPlot($values, 1, 1, 0);
$plot->setBarColor(new LightRed(25));
$group->add($plot);
 
$graph->add($group);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/bar-005.php
New file
0,0 → 1,59
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../BarPlot.class.php";
 
$graph = new Graph(400, 400);
 
// Set a title to the graph
$graph->title->set('The title');
 
// Change graph background color
$graph->setBackgroundColor(new Color(230, 230, 230));
 
$values = array(8, 2, 6, 1, 3, 5);
 
// Declare a new BarPlot
$plot = new BarPlot($values);
 
// Reduce padding around the plot
$plot->setPadding(NULL, NULL, NULL, 20);
 
// Reduce plot size and move it to the bottom of the graph
$plot->setSize(1, 0.96);
$plot->setCenter(0.5, 0.52);
 
// Set a background color to the plot
$plot->grid->setBackgroundColor(new White);
// Set a dashed grid
$plot->grid->setType(Line::DASHED);
 
 
$plot->label->set($values);
$plot->label->move(0, -10);
$plot->label->setColor(new DarkBlue);
 
// Set a shadow to the bars
$plot->barShadow->setSize(2);
 
// Bar size is at 60%
$plot->setBarSize(0.6);
 
// Change the color of the bars
$plot->setBarColor(
new Orange(15)
);
 
// Add the plot to the graph
$graph->add($plot);
 
// Draw the graph
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/all.php
New file
0,0 → 1,55
<?php
function table($files, $re = NULL) {
 
echo "<table cellpadding='4'>";
 
foreach($files as $key => $file) {
 
if($key%2 == 0) {
echo "<tr>";
}
 
if($re === NULL or eregi($re, $file)) {
image($file);
}
 
if($key%2 == 1) {
echo "</tr>";
}
 
 
}
 
if($key%2 == 0) {
echo "</tr>";
}
 
echo "</table>";
 
}
 
function image($file) {
echo "<td>
<h3>".$file."</h3>
<a href='".$file."'><img src='".$file."' style='border: 0px'/></a>
</td>";
}
?>
<h2>Artichow examples</h2>
<?php
$glob = glob("*.php");
 
table($glob, "[a-z]+\-[0-9]{3}\.php");
?>
<h2>Artichow.org examples</h2>
<?php
$glob = glob("site/*.php");
 
table($glob);
?>
<h2>Artichow tutorials</h2>
<?php
$glob = glob("tutorials/*.php");
 
table($glob);
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-001.php
New file
0,0 → 1,40
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
 
$graph->title->set("Pie (example 1)");
 
$values = array(12, 5, 13, 18, 10, 6, 11);
 
$plot = new Pie($values, Pie::EARTH);
$plot->setCenter(0.4, 0.55);
$plot->setSize(0.7, 0.6);
$plot->set3D(10);
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->legend->setPosition(1.3);
$plot->legend->shadow->setSize(0);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pattern-001.php
New file
0,0 → 1,26
<?php
require_once "../Pattern.class.php";
require_once "../Graph.class.php";
 
$graph = new Graph(300, 200);
 
// Set title
$graph->title->set('Pattern 1');
$graph->title->move(100, 0);
$graph->title->setFont(new Tuffy(9));
$graph->title->setColor(new DarkRed);
 
$pattern = Pattern::get('BarDepth');
$pattern->setArgs(array(
'yForeground' => array(5, 3, 4, 7, 6, 5, 8, 4, 7, NULL, NULL),
'yBackground' => array(NULL, NULL, 4, 5, 6, 4, 2, 3, 7, 5, 4),
'legendForeground' => '2003',
'legendBackground' => '2004'
));
 
$group = $pattern->create();
 
$graph->add($group);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-002.php
New file
0,0 → 1,41
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Pie (example 2)");
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values, Pie::EARTH);
$plot->setCenter(0.4, 0.55);
$plot->setSize(0.7, 0.6);
$plot->set3D(10);
$plot->explode(array(1 => 20, 4 => 26, 0 => 25));
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->legend->setPosition(1.3);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pattern-002.php
New file
0,0 → 1,24
<?php
require_once "../Pattern.class.php";
require_once "../Graph.class.php";
 
$graph = new Graph(300, 200);
 
$graph->title->set('Customized pattern 1');
$graph->title->setFont(new Tuffy(12));
 
$pattern = Pattern::get('BarDepth');
$pattern->setArgs(array(
'yForeground' => array(5, 3, 4, 7, 6, 5, 8, 4, 7, NULL, NULL),
'yBackground' => array(NULL, NULL, 4, 5, 6, 4, 2, 3, 7, 5, 4),
'colorForeground' => new Color(230, 230, 230),
'colorBackground' => new Color(250, 90, 90)
));
 
$group = $pattern->create();
$group->legend->setPosition(0.5, 0.78);
 
$graph->add($group);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/AntiSpam.php
New file
0,0 → 1,14
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
?>
<form action="AntiSpam-valid.php" method="get">
<img src="AntiSpam-image.php" style="vertical-align: middle"/>
<input type="text" name="code"/>
<input type="submit" value="Submit"/>
</form>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-003.php
New file
0,0 → 1,42
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Pie (example 3)");
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values, Pie::AQUA);
$plot->setCenter(0.4, 0.55);
$plot->setSize(0.7, 0.6);
$plot->set3D(15);
$plot->explode(array(4 => 20, 0 => 30));
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->legend->setPosition(1.3);
$plot->legend->setBackgroundColor(new VeryLightGray(30));
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pattern-003.php
New file
0,0 → 1,23
<?php
require_once "../Pattern.class.php";
require_once "../Graph.class.php";
 
$graph = new Graph(400, 200);
 
// Set title
$graph->title->set('Pattern 2');
$graph->title->setFont(new Tuffy(12));
$graph->title->setColor(new DarkRed);
 
$pattern = Pattern::get('LightLine');
$pattern->setArgs(array(
'y' => array(5, 3, 4, 7, 6, 5, 8, 4, 7),
'legend' => 'John Doe'
));
 
$plot = $pattern->create();
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-004.php
New file
0,0 → 1,50
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setBackgroundGradient(
new LinearGradient(
new White,
new VeryLightGray,
0
)
);
$graph->title->set("Pie (example 4)");
$graph->shadow->setSize(7);
$graph->shadow->smooth(TRUE);
$graph->shadow->setPosition(Shadow::LEFT_BOTTOM);
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values);
$plot->setCenter(0.4, 0.55);
$plot->setSize(0.7, 0.6);
$plot->set3D(10);
 
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->legend->setPosition(1.3);
$plot->legend->setBackgroundColor(new VeryLightGray(30));
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-005.php
New file
0,0 → 1,47
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setBackgroundGradient(
new LinearGradient(
new VeryLightGray,
new White,
0
)
);
$graph->title->set("Pie (example 5) - Initial angle: 140°");
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values);
$plot->setCenter(0.4, 0.55);
$plot->setSize(0.7, 0.6);
$plot->set3D(10);
$plot->setStartAngle(140);
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->legend->setPosition(1.3);
$plot->legend->setBackgroundColor(new VeryLightGray(30));
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-006.php
New file
0,0 → 1,37
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setBackgroundGradient(
new LinearGradient(
new VeryLightGray,
new White,
0
)
);
$graph->title->set("Pie (example 6)");
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values);
$plot->setCenter(0.5, 0.55);
$plot->setSize(0.7, 0.6);
$plot->set3D(5);
$plot->setBorderColor(new Black);
 
 
$plot->legend->hide(TRUE);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-007.php
New file
0,0 → 1,56
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Pie (example 7)");
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values, Pie::DARK);
$plot->setCenter(0.4, 0.55);
$plot->setSize(0.7, 0.6);
$plot->set3D(5);
$plot->setBorderColor(new White);
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->legend->setPosition(1.3);
$plot->legend->setBackgroundColor(new VeryLightGray(30));
$plot->legend->shadow->setPosition(Shadow::RIGHT_TOP);
 
$plot->label->setPadding(2, 2, 2, 2);
$plot->label->border->setColor(new Red(60));
$plot->label->setFont(new Tuffy(7));
$plot->label->setBackgroundGradient(
new LinearGradient(
new Red(80),
new White(80),
0
)
);
$plot->setLabelPrecision(1);
 
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-008.php
New file
0,0 → 1,54
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 300);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Pie (example 8)");
 
$values = array(8, 4, 6, 2, 5, 3, 4);
 
$plot = new Pie($values, Pie::EARTH);
$plot->setSize(0.85, 0.60);
$plot->set3D(15);
$plot->setBorderColor(new LightGray);
 
$plot->setLegend(array(
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
));
 
$plot->legend->shadow->setSize(3);
$plot->legend->setModel(Legend::MODEL_BOTTOM);
$plot->legend->setPosition(NULL, 1.1);
 
$plot->label->setPadding(2, 2, 2, 2);
$plot->label->border->setColor(new Red(60));
$plot->label->setFont(new Tuffy(7));
$plot->label->setBackgroundGradient(
new LinearGradient(
new Red(80),
new White(80),
0
)
);
$plot->setLabelPrecision(1);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/pie-009.php
New file
0,0 → 1,49
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../Pie.class.php";
 
 
$graph = new Graph(400, 250);
$graph->setAntiAliasing(TRUE);
 
$graph->title->set("Pie (example 9) - User defined colors");
$graph->title->border->show();
$graph->title->setBackgroundColor(new LightRed(60));
$graph->title->setPadding(3, 3, 3, 3);
 
$values = array(8, 4, 6, 3, 4);
$colors = array(
new LightOrange,
new LightPurple,
new LightBlue,
new LightRed,
new LightPink
);
 
$plot = new Pie($values, $colors);
$plot->setSize(0.70, 0.60);
$plot->setCenter(0.40, 0.55);
$plot->set3D(10);
$plot->setBorderColor(new LightGray);
 
$plot->setLegend(array(
'Alpha',
'Beta',
'Gamma',
'Delta',
'Epsilon'
));
 
$plot->legend->setPosition(1.30);
 
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/line-001.php
New file
0,0 → 1,29
<?php
 
require_once "../LinePlot.class.php";
 
$graph = new Graph(400, 400);
 
$x = array(1, 10, 3,-4, 1);
 
$plot = new LinePlot($x);
$plot->setSpace(6, 6, 10, 10);
 
$plot->hideLine(TRUE);
$plot->setFillColor(new Color(180, 180, 180, 75));
 
$plot->mark->setType(Mark::IMAGE);
$plot->mark->setImage(new FileImage("champignon.png"));
 
$plot->grid->setBackgroundColor(new Color(235, 235, 180, 60));
 
$plot->label->set($x);
$plot->label->move(0, -23);
$plot->label->setBackgroundGradient(new LinearGradient(new Color(250, 250, 250, 10), new Color(255, 200, 200, 30), 0));
$plot->label->border->setColor(new Color(20, 20, 20, 20));
$plot->label->setPadding(3, 1, 1, 0);
$graph->add($plot);
$graph->draw();
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/line-002.php
New file
0,0 → 1,52
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../LinePlot.class.php";
 
 
$graph = new Graph(400, 300);
$graph->setAntiAliasing(TRUE);
 
$x = array(
1, 2, 5, 0.5, 3, 8
);
 
$plot = new LinePlot($x);
 
$plot->setSpace(6, 6, 10, 10);
$plot->setXAxisZero(FALSE);
 
// Set a background gradient
$plot->setBackgroundGradient(
new LinearGradient(
new Color(210, 210, 210),
new Color(255, 255, 255),
0
)
);
 
// Change line color
$plot->setColor(new Color(0, 0, 150, 20));
 
// Set line background gradient
$plot->setFillGradient(
new LinearGradient(
new Color(150, 150, 210),
new Color(230, 230, 255),
90
)
);
 
// Change mark type
$plot->mark->setType(Mark::CIRCLE);
$plot->mark->border->show();
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/line-003.php
New file
0,0 → 1,44
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../LinePlot.class.php";
 
 
$graph = new Graph(400, 300);
$graph->setAntiAliasing(TRUE);
 
$x = array(
1, 2, 5, 0.5, 3, 8, 7, 6, 2, -4
);
 
$plot = new LinePlot($x);
 
// Set a background gradient
$plot->setBackgroundGradient(
new LinearGradient(
new Color(210, 210, 210),
new Color(255, 255, 255),
0
)
);
 
// Set semi-transparent background gradient
$plot->setFillGradient(
new LinearGradient(
new Color(230, 150, 150, 20),
new Color(230, 230, 180, 50),
90
)
);
 
$plot->yAxis->setLabelPrecision(1);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/examples/line-004.php
New file
0,0 → 1,59
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once "../LinePlot.class.php";
 
 
$graph = new Graph(400, 300);
$graph->setAntiAliasing(TRUE);
 
$x = array(
1, 2, 5, 0.5, 3, 8, 7, 6, 2, -4
);
 
$plot = new LinePlot($x);
 
// Change component padding
$plot->setPadding(10, NULL, NULL, NULL);
 
// Change component space
$plot->setSpace(5, 5, 5, 5);
 
// Set a background color
$plot->setBackgroundColor(
new Color(230, 230, 230)
);
 
// Change grid background color
$plot->grid->setBackgroundColor(
new Color(235, 235, 180, 60)
);
 
// Hide grid
$plot->grid->hide(TRUE);
 
// Hide labels on Y axis
$plot->yAxis->label->hide(TRUE);
 
$plot->xAxis->label->setInterval(2);
 
$plot->label->set($x);
$plot->label->setFormat('%.1f');
$plot->label->setBackgroundColor(new Color(240, 240, 240, 15));
$plot->label->border->setColor(new Color(255, 0, 0, 15));
$plot->label->setPadding(5, 3, 1, 1);
 
$plot->xAxis->label->move(0, 5);
$plot->xAxis->label->setBackgroundColor(new Color(240, 240, 240, 15));
$plot->xAxis->label->border->setColor(new Color(0, 150, 0, 15));
$plot->xAxis->label->setPadding(5, 3, 1, 1);
 
$graph->add($plot);
$graph->draw();
?>
/tags/v1.0-Homere/bibliotheque/artichow/LinePlot.class.php
New file
0,0 → 1,585
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/Plot.class.php";
 
/**
* LinePlot
*
* @package Artichow
*/
class awLinePlot extends awPlot implements awLegendable {
/**
* Add marks to your line plot
*
* @var Mark
*/
public $mark;
/**
* Labels on your line plot
*
* @var Label
*/
public $label;
/**
* Filled areas
*
* @var bool
*/
protected $areas = array();
/**
* Is the line hidden
*
* @var bool
*/
protected $lineHide = FALSE;
/**
* Line color
*
* @var Color
*/
protected $lineColor;
/**
* Line mode
*
* @var int
*/
protected $lineMode = awLinePlot::LINE;
/**
* Line type
*
* @var int
*/
protected $lineStyle = awLine::SOLID;
/**
* Line thickness
*
* @var int
*/
protected $lineThickness = 1;
/**
* Line background
*
* @var Color, Gradient
*/
protected $lineBackground;
/**
* Line mode
*
* @var int
*/
const LINE = 0;
/**
* Line in the middle
*
* @var int
*/
const MIDDLE = 1;
/**
* Construct a new awLinePlot
*
* @param array $values Some numeric values for Y axis
* @param int $mode
*/
public function __construct($values, $mode = awLinePlot::LINE) {
parent::__construct();
$this->mark = new awMark;
$this->label = new awLabel;
$this->lineMode = (int)$mode;
$this->setValues($values);
}
/**
* Hide line
*
* @param bool $hide
*/
public function hideLine($hide) {
$this->lineHide = (bool)$hide;
}
/**
* Add a filled area
*
* @param int $start Begining of the area
* @param int $end End of the area
* @param mixed $background Background color or gradient of the area
*/
public function setFilledArea($start, $stop, $background) {
if($stop <= $start) {
awImage::drawError("Class LinePlot: End position can not be greater than begin position in setFilledArea().");
}
$this->areas[] = array((int)$start, (int)$stop, $background);
}
/**
* Change line color
*
* @param awColor $color
*/
public function setColor(awColor $color) {
$this->lineColor = $color;
}
/**
* Change line style
*
* @param int $style
*/
public function setStyle($style) {
$this->lineStyle = (int)$style;
}
/**
* Change line tickness
*
* @param int $tickness
*/
public function setThickness($tickness) {
$this->lineThickness = (int)$tickness;
}
/**
* Change line background color
*
* @param awColor $color
*/
public function setFillColor(awColor $color) {
$this->lineBackground = $color;
}
/**
* Change line background gradient
*
* @param awGradient $gradient
*/
public function setFillGradient(awGradient $gradient) {
$this->lineBackground = $gradient;
}
 
/**
* Get the line thickness
*
* @return int
*/
public function getLegendLineThickness() {
return $this->lineThickness;
}
 
/**
* Get the line type
*
* @return int
*/
public function getLegendLineStyle() {
return $this->lineStyle;
}
 
/**
* Get the color of line
*
* @return Color
*/
public function getLegendLineColor() {
return $this->lineColor;
}
 
/**
* Get the background color or gradient of an element of the component
*
* @return Color, Gradient
*/
public function getLegendBackground() {
return $this->lineBackground;
}
 
/**
* Get a mark object
*
* @return Mark
*/
public function getLegendMark() {
return $this->mark;
}
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
$max = $this->getRealYMax();
$min = $this->getRealYMin();
// Get start and stop values
list($start, $stop) = $this->getLimit();
if($this->lineMode === awLinePlot::MIDDLE) {
$inc = $this->xAxis->getDistance(0, 1) / 2;
} else {
$inc = 0;
}
// Build the polygon
$polygon = new awPolygon;
for($key = $start; $key <= $stop; $key++) {
$value = $this->datay[$key];
if($value !== NULL) {
$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($key, $value));
$p = $p->move($inc, 0);
$polygon->set($key, $p);
}
}
// Draw backgrounds
if($this->lineBackground instanceof awColor or $this->lineBackground instanceof awGradient) {
$backgroundPolygon = new awPolygon;
$p = $this->xAxisPoint($start);
$p = $p->move($inc, 0);
$backgroundPolygon->append($p);
// Add others points
foreach($polygon->all() as $point) {
$backgroundPolygon->append(clone $point);
}
$p = $this->xAxisPoint($stop);
$p = $p->move($inc, 0);
$backgroundPolygon->append($p);
// Draw polygon background
$driver->filledPolygon($this->lineBackground, $backgroundPolygon);
}
$this->drawArea($driver, $polygon);
// Draw line
$prev = NULL;
// Line color
if($this->lineHide === FALSE) {
if($this->lineColor === NULL) {
$this->lineColor = new awColor(0, 0, 0);
}
foreach($polygon->all() as $point) {
if($prev !== NULL) {
$driver->line(
$this->lineColor,
new awLine(
$prev,
$point,
$this->lineStyle,
$this->lineThickness
)
);
}
$prev = $point;
}
 
}
// Draw marks and labels
foreach($polygon->all() as $key => $point) {
 
$this->mark->draw($driver, $point);
$this->label->draw($driver, $point, $key);
}
}
protected function drawArea(awDriver $driver, awPolygon $polygon) {
$starts = array();
foreach($this->areas as $area) {
list($start) = $area;
$starts[$start] = TRUE;
}
// Draw filled areas
foreach($this->areas as $area) {
list($start, $stop, $background) = $area;
$polygonArea = new awPolygon;
$p = $this->xAxisPoint($start);
$polygonArea->append($p);
for($i = $start; $i <= $stop; $i++) {
$p = clone $polygon->get($i);
if($i === $stop and array_key_exists($stop, $starts)) {
$p = $p->move(-1, 0);
}
$polygonArea->append($p);
}
$p = $this->xAxisPoint($stop);
if(array_key_exists($stop, $starts)) {
$p = $p->move(-1, 0);
}
$polygonArea->append($p);
// Draw area
$driver->filledPolygon($background, $polygonArea);
}
}
public function getXAxisNumber() {
if($this->lineMode === awLinePlot::MIDDLE) {
return count($this->datay) + 1;
} else {
return count($this->datay);
}
}
protected function xAxisPoint($position) {
$y = $this->xAxisZero ? 0 : $this->getRealYMin();
return awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($position, $y));
}
public function getXCenter() {
return ($this->lineMode === awLinePlot::MIDDLE);
}
 
}
 
registerClass('LinePlot');
 
 
/**
* Simple LinePlot
* Useful to draw simple horizontal lines
*
* @package Artichow
*/
class awSimpleLinePlot extends awPlot implements awLegendable {
/**
* Line color
*
* @var Color
*/
protected $lineColor;
/**
* Line start
*
* @var int
*/
protected $lineStart;
/**
* Line stop
*
* @var int
*/
protected $lineStop;
/**
* Line value
*
* @var flaot
*/
protected $lineValue;
/**
* Line mode
*
* @var int
*/
protected $lineMode = awLinePlot::LINE;
/**
* Line type
*
* @var int
*/
protected $lineStyle = awLine::SOLID;
/**
* Line thickness
*
* @var int
*/
protected $lineThickness = 1;
/**
* Line mode
*
* @var int
*/
const LINE = 0;
/**
* Line in the middle
*
* @var int
*/
const MIDDLE = 1;
/**
* Construct a new awLinePlot
*
* @param float $value A Y value
* @param int $start Line start index
* @param int $stop Line stop index
* @param int $mode Line mode
*/
public function __construct($value, $start, $stop, $mode = awLinePlot::LINE) {
parent::__construct();
$this->lineMode = (int)$mode;
$this->lineStart = (int)$start;
$this->lineStop = (int)$stop;
$this->lineValue = (float)$value;
$this->lineColor = new awColor(0, 0, 0);
}
/**
* Change line color
*
* @param awColor $color
*/
public function setColor(awColor $color) {
$this->lineColor = $color;
}
/**
* Change line style
*
* @param int $style
*/
public function setStyle($style) {
$this->lineStyle = (int)$style;
}
/**
* Change line tickness
*
* @param int $tickness
*/
public function setThickness($tickness) {
$this->lineThickness = (int)$tickness;
}
 
/**
* Get the line thickness
*
* @return int
*/
public function getLegendLineThickness() {
return $this->lineThickness;
}
 
/**
* Get the line type
*
* @return int
*/
public function getLegendLineStyle() {
return $this->lineStyle;
}
 
/**
* Get the color of line
*
* @return Color
*/
public function getLegendLineColor() {
return $this->lineColor;
}
 
public function getLegendBackground() {
return NULL;
}
 
public function getLegendMark() {
return NULL;
}
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
if($this->lineMode === awLinePlot::MIDDLE) {
$inc = $this->xAxis->getDistance(0, 1) / 2;
} else {
$inc = 0;
}
$p1 = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($this->lineStart, $this->lineValue));
$p2 = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($this->lineStop, $this->lineValue));
$driver->line(
$this->lineColor,
new awLine(
$p1->move($inc, 0),
$p2->move($inc, 0),
$this->lineStyle,
$this->lineThickness
)
);
}
public function getXAxisNumber() {
if($this->lineMode === awLinePlot::MIDDLE) {
return count($this->datay) + 1;
} else {
return count($this->datay);
}
}
protected function xAxisPoint($position) {
$y = $this->xAxisZero ? 0 : $this->getRealYMin();
return awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($position, $y));
}
public function getXCenter() {
return ($this->lineMode === awLinePlot::MIDDLE);
}
 
}
 
registerClass('SimpleLinePlot');
?>
/tags/v1.0-Homere/bibliotheque/artichow/MathPlot.class.php
New file
0,0 → 1,439
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/Component.class.php";
 
/**
* A mathematic function
*
* @package Artichow
*/
class awMathFunction implements awLegendable {
 
/**
* Function line
*
* @var Line
*/
public $line;
/**
* Marks for your plot
*
* @var Mark
*/
public $mark;
/**
* Callback function
*
* @var string
*/
public $f;
/**
* Start the drawing from this value
*
* @var float
*/
public $fromX;
/**
* Stop the drawing at this value
*
* @var float
*/
public $toX;
 
/**
* Line color
*
* @var Color
*/
protected $color;
/**
* Construct the function
*
* @param string $f Callback function
* @param float $fromX
* @param float $toX
*/
public function __construct($f, $fromX = NULL, $toX = NULL) {
$this->f = (string)$f;
$this->fromX = is_null($fromX) ? NULL : (float)$fromX;
$this->toX = is_null($toX) ? NULL : (float)$toX;
$this->line = new awLine;
$this->mark = new awMark;
$this->color = new awBlack;
}
/**
* Change line color
*
* @param awColor $color A new awcolor
*/
public function setColor(awColor $color) {
$this->color = $color;
}
/**
* Get line color
*
* @return Color
*/
public function getColor() {
return $this->color;
}
 
/**
* Get the background color or gradient of an element of the component
*
* @return Color, Gradient
*/
public function getLegendBackground() {
}
 
/**
* Get the line thickness
*
* @return NULL
*/
public function getLegendLineThickness() {
return $this->line->getThickness();
}
 
/**
* Get the line type
*
* @return NULL
*/
public function getLegendLineStyle() {
return $this->line->getStyle();
}
 
/**
* Get the color of line
*
* @return NULL
*/
public function getLegendLineColor() {
return $this->color;
}
 
/**
* Get a mark object
*
* @return NULL
*/
public function getLegendMark() {
return $this->mark;
}
 
}
 
registerClass('MathFunction');
/**
* For mathematics functions
*
* @package Artichow
*/
class awMathPlot extends awComponent {
/**
* Functions
*
* @var array
*/
protected $functions = array();
/**
* Grid properties
*
* @var Grid
*/
public $grid;
/**
* X axis
*
* @var Axis
*/
public $xAxis;
/**
* Y axis
*
* @var Axis
*/
public $yAxis;
/**
* Extremum
*
* @var Side
*/
private $extremum = NULL;
/**
* Interval
*
* @var float
*/
private $interval = 1;
/**
* Build the plot
*
* @param int $xMin Minimum X value
* @param int $xMax Maximum X value
* @param int $yMax Maximum Y value
* @param int $yMin Minimum Y value
*/
public function __construct($xMin, $xMax, $yMax, $yMin) {
parent::__construct();
$this->setPadding(8, 8, 8, 8);
$this->grid = new awGrid;
// Hide grid by default
$this->grid->hide(TRUE);
// Set extremum
$this->extremum = new awSide($xMin, $xMax, $yMax, $yMin);
// Create axis
$this->xAxis = new awAxis;
$this->xAxis->setTickStyle(awTick::IN);
$this->xAxis->label->hideValue(0);
$this->initAxis($this->xAxis);
$this->yAxis = new awAxis;
$this->yAxis->setTickStyle(awTick::IN);
$this->yAxis->label->hideValue(0);
$this->initAxis($this->yAxis);
}
protected function initAxis(awAxis $axis) {
$axis->setLabelPrecision(1);
$axis->addTick('major', new awTick(0, 5));
$axis->addTick('minor', new awTick(0, 3));
$axis->addTick('micro', new awTick(0, 1));
$axis->setNumberByTick('minor', 'major', 1);
$axis->setNumberByTick('micro', 'minor', 4);
$axis->label->setFont(new awTuffy(7));
}
/**
* Interval to calculate values
*
* @param float $interval
*/
public function setInterval($interval) {
$this->interval = (float)$interval;
}
/**
* Add a formula f(x)
*
* @param awMathFunction $function
* @param string $name Name for the legend (can be NULL if you don't want to set a legend)
* @param int $type Type for the legend
*/
public function add(awMathFunction $function, $name = NULL, $type = awLegend::LINE) {
$this->functions[] = $function;
if($name !== NULL) {
$this->legend->add($function, $name, $type);
}
}
public function init(awDriver $driver) {
list($x1, $y1, $x2, $y2) = $this->getPosition();
$this->xAxis->line->setX($x1, $x2);
$this->xAxis->label->setAlign(NULL, awLabel::BOTTOM);
$this->xAxis->label->move(0, 3);
$this->xAxis->setRange($this->extremum->left, $this->extremum->right);
$this->yAxis->line->setY($y2, $y1);
$this->yAxis->label->setAlign(awLabel::RIGHT);
$this->yAxis->label->move(-6, 0);
$this->yAxis->reverseTickStyle();
$this->yAxis->setRange($this->extremum->bottom, $this->extremum->top);
$this->xAxis->setYCenter($this->yAxis, 0);
$this->yAxis->setXCenter($this->xAxis, 0);
if($this->yAxis->getLabelNumber() === NULL) {
$number = $this->extremum->top - $this->extremum->bottom + 1;
$this->yAxis->setLabelNumber($number);
}
if($this->xAxis->getLabelNumber() === NULL) {
$number = $this->extremum->right - $this->extremum->left + 1;
$this->xAxis->setLabelNumber($number);
}
// Set ticks
$this->xAxis->tick('major')->setNumber($this->xAxis->getLabelNumber());
$this->yAxis->tick('major')->setNumber($this->yAxis->getLabelNumber());
// Set axis labels
$labels = array();
for($i = 0, $count = $this->xAxis->getLabelNumber(); $i < $count; $i++) {
$labels[] = $i;
}
$this->xAxis->label->set($labels);
$labels = array();
for($i = 0, $count = $this->yAxis->getLabelNumber(); $i < $count; $i++) {
$labels[] = $i;
}
$this->yAxis->label->set($labels);
parent::init($driver);
// Create the grid
$this->createGrid();
// Draw the grid
$this->grid->draw($driver, $x1, $y1, $x2, $y2);
}
public function drawEnvelope(awDriver $driver) {
// Draw axis
$this->xAxis->draw($driver);
$this->yAxis->draw($driver);
}
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
foreach($this->functions as $function) {
$f = $function->f;
$fromX = is_null($function->fromX) ? $this->extremum->left : $function->fromX;
$toX = is_null($function->toX) ? $this->extremum->right : $function->toX;
$old = NULL;
for($i = $fromX; $i <= $toX; $i += $this->interval) {
$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($i, $f($i)));
if($p->y >= $y1 and $p->y <= $y2) {
$function->mark->draw($driver, $p);
}
if($old !== NULL) {
$line = $function->line;
$line->setLocation($old, $p);
if(
($line->p1->y >= $y1 and $line->p1->y <= $y2) or
($line->p2->y >= $y1 and $line->p2->y <= $y2)
) {
$driver->line(
$function->getColor(),
$line
);
}
}
$old = $p;
}
// Draw last point if needed
if($old !== NULL and $i - $this->interval != $toX) {
$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($toX, $f($toX)));
if($p->y >= $y1 and $p->y <= $y2) {
$function->mark->draw($driver, $p);
}
$line = $function->line;
$line->setLocation($old, $p);
if(
($line->p1->y >= $y1 and $line->p1->y <= $y2) or
($line->p2->y >= $y1 and $line->p2->y <= $y2)
) {
$driver->line(
$function->getColor(),
$line
);
}
}
}
}
protected function createGrid() {
// Horizontal lines of the grid
 
$major = $this->yAxis->tick('major');
$interval = $major->getInterval();
$number = $this->yAxis->getLabelNumber() - 1;
$h = array();
if($number > 0) {
for($i = 0; $i <= $number; $i++) {
$h[] = $i / $number;
}
}
// Vertical lines
$major = $this->xAxis->tick('major');
$interval = $major->getInterval();
$number = $this->xAxis->getLabelNumber() - 1;
$w = array();
if($number > 0) {
for($i = 0; $i <= $number; $i++) {
if($i%$interval === 0) {
$w[] = $i / $number;
}
}
}
$this->grid->setGrid($w, $h);
}
 
}
 
registerClass('MathPlot');
?>
/tags/v1.0-Homere/bibliotheque/artichow/ChangeLog
New file
0,0 → 1,170
Artichow 1.1
 
- All new driver-based architecture: Artichow now draws the graphs using drivers, located in 'inc/drivers/'. The move will ease development of new drawing formats (SVG, Flash, etc.) while keeping backward compatibility very high: you shouldn't have to change anything to your existing code and only two methods from the Font class have disappeared (see below) (Laurent)
- Added Image::setDriver() to allow driver selection (Laurent)
- Changed the Drawer class name to Driver. The class is now abstract, the implementation has to be made in the driver file itself. (Laurent)
- Added the GDDriver class to draw with GD: the file is 'inc/drivers/gd.class.php' (Laurent)
- Modified GDDriver::rectangle() so that it doesn't tamper with the Line object passed as an argument any more (Laurent)
- Fixed a bug where calling GDDriver::polygon() wouldn't close the polygon being drawn when using a non-solid border (Laurent)
- Added the constant ARTICHOW_DRIVER to define the default driver to use when none is selected (defaults to 'gd') (Laurent)
- Changed and reorganised the Font related classes: added FileFont and PHPFont, reworked inheritance (Laurent)
- Deleted Font::getTextWidth() and Font::getTextHeight(), replaced by Driver::getTextWidth() and Driver::getTextHeight() (Laurent)
- Added two new helping classes for Font manipulation, PHPFontDriver and FileFontDriver (Laurent)
- Fixed a bug that prevented values passed to Grid::setGrid() to have any effect (Laurent)
- Added four new types of Mark (Mark::INVERTED_TRIANGLE, Mark::RHOMBUS, Mark::CROSS, Mark::PLUS) (Geoffrey)
- Updated Image::drawError() so that it doesn't display HTML tags any more (Laurent)
- Modified Lable::setCallbackFunction() so that it now accepts static method callbacks (i.e. setCallbackFunction(array($this, 'methodName'))) (Vincent)
- Code cleanup and tweaking
 
Artichow 1.0.9
 
- Fixed a bug in Font class (second argument of wordwrap() can not be empty) (Vincent)
- Fixed a bug in Drawer class (text size was not handled correctly) (Vincent)
- Added support for using font paths containing space character when using GD <= 2.0.18 (bug#12) (Vincent)
- Fixed a bug where the HTTP headers were sent even though the draw() method was called with Graph::DRAW_RETURN or a filename (Laurent)
- Added support for antialiased pies on non-white background (only work with plain colors) (thanks to Eldwin) (Laurent)
- Anti-aliasing is now handled by the Drawer class (Laurent)
- Added method Drawer::setAntiAliasing() to turn anti-aliasing on or off (Laurent)
- Fixed a bug where a LinePlot with multiple lines of different thickness wouldn't have its anti-aliasing setting correctly handled (Laurent)
- Fixed a bug where the X axis wouldn't be labelled properly (bug#16) (Laurent)
- Added a new type of Mark (Mark::TRIANGLE) (Laurent)
- Fixed a bug where calling Axis::setYMax() wouldn't have any effect when drawing the axis (Vincent)
- Fixed a bug where a dashed line wouldn't been drawn properly in certain circumstances (Laurent)
- Fixed a bug where using Label::setFormat() or Label::setCallbackFunction() would be overriden by Axis::setLabelPrecision() (Laurent)
- Fixed a "division by zero" error when using a gradient fill on a LinePlot with zeroed values (bug#19) (Laurent)
- General code cleanup
 
Artichow 1.0.8
 
- Enhanced error support
- Added multi-line text support
- Updated and improved documentation
- Changed Graph::draw() method to accept more options
- Deleted first parameter of Image::send() method
- Added a third parameter to Image::send() method to disable auto-sending of Content-Type header
- Added a second parameter to Image::send() method to return an image instead of outputing it
- Fixed a fatal error on direct access to files Image.class.php and inc/*
- Fixed a bug in configuration file (bad constant definition check for ARTICHOW_CACHE_DIRECTORY)
 
Artichow 1.0.7
 
- Added constant ARTICHOW_CACHE_DIRECTORY to choose cache directory
- Fixed a division by zero bug in Axis class
- Improved cache handling
- Fixed a bug with ob_* handlers
- Fixed a bug for lines thickness
- Shadow color now works fine
 
Artichow 1.0.6
 
- Added method Plot::setYAxisZero()
- Added auto-scaling for plots
- Added constant ARTICHOW_CACHE to enable/disable the cache
- Improved prefix for classes
 
Artichow 1.0.5
 
- Added constant ARTICHOW_PREFIX to prefix Artichow's classes (bug #000002)
- Added methods Shadow::hide() and Shadow::show()
- Added method Plot::reduce()
- It is now possible to save its charts in a file
- Fixed a bug in PlotGroup (setYMin() / setYMax() did not work)
- Fixed an incoherent behaviour if some values in $datay are not numeric (LinePlot, BarPlot, ScatterPlot)
- Fixed an inclusion bug in Pattern
- Fixed a bug for PHP 5.1.0
 
Artichow 1.0.4
 
- Added support for GIF images
- Added patterns (Pattern.class.php)
- Added titles on axis
- Renamed Artichow.class.php to Graph.class.php (break backward compatibility)
- Added a README file
- Added support for ScatterPlot
- Merged setBackgroundColor() and setBackgroundGradient() into setFill() in class Mark (break backward compatibility)
- Added an optional argument $size to Mark::setType()
- Grid background in now default to white in class Plot
- Changed class Polygon to accept NULL values
- Added a new legend type (Legend::MARKONLY)
- Added method Legend::show()
- Added methods Mark::move(), Mark::hide() and Mark::show()
- Added new marks (star, book, ...)
- Added methods Label::setBackground() and Legend::setBackground()
- Added methods Plot::setXMax(), Plot::setXMin(), PlotGroup::setXMax() and PlotGroup::setXMin()
- Added new colors to default theme in Pie
- Removed methods Drawer::setBackground*()
- Tests have been removed from the archive
- Moved methods Component::addLabel() and Component::addAbsLabel() to class Graph
- Modes LinePlot::MIDDLE and LinePlot::BAR have been merged into LinePlot::MIDDLE (break backward compatibility)
- Fixed a bug in Artichow.cfg.php (unable to use some ttf fonts)
- Fixed a bug in Legend (position of marks was sometimes broken)
- Fixed a bug in Pie (pies can now take only a single value)
- Fixed some bugs in Plot / LinePlot
- Fixed a bug in Font::draw() (call to undefined function trigger__error)
 
Artichow 1.0.3 (beta)
 
- Added EXPERIMENTAL support for PHP 4
- Changed class BarPlot so it now uses class Border instead of setBorderThickness() and setBorderColor()
- Changed class Legend so it now uses class Border instead of setBorderSize() and setBorderColor()
- Changed class Mark so it now uses class Border instead of setBorderSize() and setBorderColor()
- Changed class Text so it now uses class Border instead of setBorderColor()
- Changed class Label so it now uses class Border instead of setBorderColor()
- Drawer::drawRectangle() and Drawer::drawFilledRectangle() now take a line as second argument
- Added styles to rectangles and polygons
- BarPlot::setBarPadding() takes now values in per-cent instead of pixels
- Merged drawFilledRectangleColor() and drawFilledRectangleGradient() into drawFilledRectangle() in class Drawer
- Merged drawFilledPolygonColor() and drawFilledPolygonGradient() into drawFilledPolygon() in class Drawer
- Merged drawFilledEllipseColor() and drawFilledEllipseGradient() into drawFilledEllipse() in class Drawer
- Added method BarPlot::setBarWidth()
- Added an optional border to the class Image
- Added a new class Border
- Added support for MathPlot
- LinePlot::STEP has been removed
- Merged classes Paragraph and Label (no changes in the API)
- Method Plot::setLabelCenter() is obsolete and has been removed
- Rewrited Axis (add a new class Tick) (break backward compatibility)
- Removed draw*Triangle* from class Drawer (use polygons instead)
- Removed prefix draw in each method of class Drawer
- Renamed LinePlot::setLineType() into LinePlot::setStyle()
- Renamed LinePlot::setLineThickness() into LinePlot::setThickness()
- Renamed LinePlot::setLineColor() into LinePlot::setColor()
- Renamed LinePlot::setLineBackgroundColor() to LinePlot::setFillColor()
- Renamed LinePlot::setLineBackgroundGradient() to LinePlot::setFillGradient()
- Renamed Line::setType() to Line::setStyle()
- Added methods Label::get(), Label::setFormat() and change method Label::setFont()
- Added a parameter $smooth in Shadow::setSize();
- Added filled areas in LinePlot
- Added lots of new features in Math.class.php
- Fixed a bug in Math::isVertical() and Math::isHorizontal()
- Fixed a bug in Legend (shadow is now well-positioned is there is no border on the legend)
- Lots of minor changes
 
Artichow 1.0.2 (beta)
 
- Added support for pies (2D & 3D)
- Moved shadow from class Component to class Image
- X Axis are now centered on 0 by default on bar and line plots
- Added title to Graphs
- Added 4 named fonts
- Added 50 named colors
- Added shadow to legends
- Added method Image::setBackgroundGradient()
- Added methods Label::setCallbackFunction() and Label::hide()
- Added method Legend::hide()
- Added methods Drawer::copyResizeImage(), Drawer::drawArc() and Drawer::drawFilledArcColor()
- Renamed Positionable::setHorizontalAlign() and Positionable::setVerticalAlign() to Positionable::setAlign()
- API for ellipses has changed
- Title is now a property instead of a method in Component
- Removed old code, that fixes a bug in the grid
- Fixed a bug that affects position of bars in some cases
- Fixed wrong size of shadow
- Fixed a bug in Plot::setYMin() and Plot::setYMax()
 
Artichow 1.0.1 (alpha)
 
- Added anti-spam images
 
Artichow 1.0.0 (alpha)
 
- Initial release
/tags/v1.0-Homere/bibliotheque/artichow/Graph.class.php
New file
0,0 → 1,412
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/Image.class.php";
 
/**
* A graph
*
* @package Artichow
*/
class awGraph extends awImage {
 
/**
* Graph name
*
* @var string
*/
protected $name;
 
/**
* Cache timeout
*
* @var int
*/
protected $timeout = 0;
/**
* Graph timing ?
*
* @var bool
*/
protected $timing;
/**
* Components
*
* @var array
*/
private $components = array();
/**
* Some labels to add to the component
*
* @var array
*/
protected $labels = array();
/**
* Graph title
*
* @var Label
*/
public $title;
/**
* File cache location
*
* @var string
*/
private $fileCache;
/**
* Time file cache location
*
* @var string
*/
private $fileCacheTime;
/**
* Drawing mode to return the graph
*
* @var int
*/
const DRAW_RETURN = 1;
/**
* Drawing mode to display the graph
*
* @var int
*/
const DRAW_DISPLAY = 2;
/**
* Construct a new graph
*
* @param int $width Graph width
* @param int $height Graph height
* @param string $name Graph name for the cache (must be unique). Let it null to not use the cache.
* @param int $timeout Cache timeout (unix timestamp)
*/
public function __construct($width = NULL, $height = NULL, $name = NULL, $timeout = 0) {
parent::__construct();
$this->setSize($width, $height);
 
if(ARTICHOW_CACHE) {
$this->name = $name;
$this->timeout = $timeout;
// Clean sometimes all the cache
if(mt_rand(0, 5000) === 0) {
awGraph::cleanCache();
}
// Take the graph from the cache if possible
if($this->name !== NULL) {
$this->fileCache = ARTICHOW_CACHE_DIRECTORY."/".$this->name;
$this->fileCacheTime = $this->fileCache."-time";
if(is_file($this->fileCache)) {
$type = awGraph::cleanGraphCache($this->fileCacheTime);
if($type === NULL) {
awGraph::deleteFromCache($this->name);
} else {
header("Content-Type: image/".$type);
echo file_get_contents($this->fileCache);
exit;
}
}
}
}
$this->title = new awLabel(
NULL,
new awTuffy(16),
NULL,
0
);
$this->title->setAlign(awLabel::CENTER, awLabel::BOTTOM);
}
/**
* Delete a graph from the cache
*
* @param string $name Graph name
* @return bool TRUE on success, FALSE on failure
*/
public static function deleteFromCache($name) {
 
if(ARTICHOW_CACHE) {
if(is_file(ARTICHOW_CACHE_DIRECTORY."/".$name."-time")) {
unlink(ARTICHOW_CACHE_DIRECTORY."/".$name."");
unlink(ARTICHOW_CACHE_DIRECTORY."/".$name."-time");
}
}
}
/**
* Delete all graphs from the cache
*/
public static function deleteAllCache() {
 
if(ARTICHOW_CACHE) {
$dp = opendir(ARTICHOW_CACHE_DIRECTORY);
while($file = readdir($dp)) {
if($file !== '.' and $file != '..') {
unlink(ARTICHOW_CACHE_DIRECTORY."/".$file);
}
}
}
}
/**
* Clean cache
*/
public static function cleanCache() {
 
if(ARTICHOW_CACHE) {
$glob = glob(ARTICHOW_CACHE_DIRECTORY."/*-time");
foreach($glob as $file) {
$type = awGraph::cleanGraphCache($file);
if($type === NULL) {
$name = ereg_replace(".*/(.*)\-time", "\\1", $file);
awGraph::deleteFromCache($name);
}
}
}
}
/**
* Enable/Disable Graph timing
*
* @param bool $timing
*/
public function setTiming($timing) {
$this->timing = (bool)$timing;
}
/**
* Add a component to the graph
*
* @param awComponent $component
*/
public function add(awComponent $component) {
$this->components[] = $component;
}
/**
* Add a label to the component
*
* @param awLabel $label
* @param int $x Position on X axis of the center of the text
* @param int $y Position on Y axis of the center of the text
*/
public function addLabel(awLabel $label, $x, $y) {
$this->labels[] = array(
$label, $x, $y
);
}
/**
* Add a label to the component with absolute position
*
* @param awLabel $label
* @param awPoint $point Text position
*/
public function addAbsLabel(awLabel $label, awPoint $point) {
$this->labels[] = array(
$label, $point
);
}
/**
* Build the graph and draw component on it
*
* @param string $mode Display mode (can be a file name)
*/
public function draw($mode = Graph::DRAW_DISPLAY) {
if($this->timing) {
$time = microtimeFloat();
}
$this->create();
foreach($this->components as $component) {
$this->drawComponent($component);
}
$this->drawTitle();
$this->drawShadow();
$this->drawLabels();
if($this->timing) {
$this->drawTiming(microtimeFloat() - $time);
}
// Create graph
$data = $this->get();
// Put the graph in the cache if needed
$this->cache($data);
switch($mode) {
case Graph::DRAW_DISPLAY :
$this->sendHeaders();
echo $data;
break;
case Graph::DRAW_RETURN :
return $data;
default :
if(is_string($mode)) {
file_put_contents($mode, $data);
} else {
awImage::drawError("Class Graph: Unable to draw the graph.");
}
}
 
}
private function drawLabels() {
$driver = $this->getDriver();
foreach($this->labels as $array) {
if(count($array) === 3) {
// Text in relative position
list($label, $x, $y) = $array;
$point = new awPoint(
$x * $this->width,
$y * $this->height
);
} else {
// Text in absolute position
list($label, $point) = $array;
}
$label->draw($driver, $point);
}
}
private function drawTitle() {
$driver = $this->getDriver();
$point = new awPoint(
$this->width / 2,
10
);
$this->title->draw($driver, $point);
}
private function drawTiming($time) {
$driver = $this->getDriver();
$label = new awLabel;
$label->set("(".sprintf("%.3f", $time)." s)");
$label->setAlign(awLabel::LEFT, awLabel::TOP);
$label->border->show();
$label->setPadding(1, 0, 0, 0);
$label->setBackgroundColor(new awColor(230, 230, 230, 25));
$label->draw($driver, new awPoint(5, $driver->imageHeight - 5));
}
private function cache($data) {
if(ARTICHOW_CACHE and $this->name !== NULL) {
if(is_writable(ARTICHOW_CACHE_DIRECTORY) === FALSE) {
awImage::drawError("Class Graph: Cache directory is not writable.");
}
file_put_contents($this->fileCache, $data);
file_put_contents($this->fileCacheTime, $this->timeout."\n".$this->getFormatString());
}
}
private static function cleanGraphCache($file) {
list(
$time,
$type
) = explode("\n", file_get_contents($file));
$time = (int)$time;
if($time !== 0 and $time < time()) {
return NULL;
} else {
return $type;
}
}
 
}
 
registerClass('Graph');
 
/*
* To preserve PHP 4 compatibility
*/
function microtimeFloat() {
list($usec, $sec) = explode(" ", microtime());
return (float)$usec + (float)$sec;
}
?>
/tags/v1.0-Homere/bibliotheque/artichow/Component.class.php
New file
0,0 → 1,415
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/Graph.class.php";
 
 
/**
* A graph can contain some groups of components
*
* @package Artichow
*/
abstract class awComponentGroup extends awComponent {
 
/**
* Components of this group
*
* @var array
*/
protected $components;
/**
* Build the component group
*/
public function __construct() {
parent::__construct();
$this->components = array();
}
 
/**
* Add a component to the group
*
* @param awComponent $component A component
*/
public function add(awComponent $component) {
$this->components[] = $component;
}
 
}
 
registerClass('ComponentGroup', TRUE);
 
abstract class awComponent {
 
/**
* Component driver
*
* @var Driver
*/
protected $driver;
 
/**
* Component width
*
* @var float
*/
public $width = 1.0;
 
/**
* Component height
*
* @var float
*/
public $height = 1.0;
 
/**
* Position X of the center the graph (from 0 to 1)
*
* @var float
*/
public $x = 0.5;
 
/**
* Position Y of the center the graph (from 0 to 1)
*
* @var float
*/
public $y = 0.5;
/**
* Component absolute width (in pixels)
*
*
* @var int
*/
public $w;
/**
* Component absolute height (in pixels)
*
*
* @var int
*/
public $h;
 
/**
* Left-top corner Y position
*
* @var float
*/
public $top;
 
/**
* Left-top corner X position
*
* @var float
*/
public $left;
/**
* Component background color
*
* @var Color
*/
protected $background;
/**
* Component padding
*
* @var Side
*/
protected $padding;
/**
* Component space
*
* @var Side
*/
protected $space;
/**
* Component title
*
* @var Label
*/
public $title;
/**
* Adjust automatically the component ?
*
* @var bool
*/
protected $auto = TRUE;
/**
* Legend
*
* @var Legend
*/
public $legend;
/**
* Build the component
*/
public function __construct() {
// Component legend
$this->legend = new awLegend();
$this->padding = new awSide(25, 25, 25, 25);
$this->space = new awSide(0, 0, 0, 0);
// Component title
$this->title = new awLabel(
NULL,
new awTuffy(10),
NULL,
0
);
$this->title->setAlign(awLabel::CENTER, awLabel::TOP);
}
/**
* Adjust automatically the component ?
*
* @param bool $auto
*/
public function auto($auto) {
$this->auto = (bool)$auto;
}
/**
* Change the size of the component
*
* @param int $width Component width (from 0 to 1)
* @param int $height Component height (from 0 to 1)
*/
public function setSize($width, $height) {
$this->width = (float)$width;
$this->height = (float)$height;
}
/**
* Change the absolute size of the component
*
* @param int $w Component width (in pixels)
* @param int $h Component height (in pixels)
*/
public function setAbsSize($w, $h) {
$this->w = (int)$w;
$this->h = (int)$h;
}
/**
* Change component background color
*
* @param awColor $color (can be null)
*/
public function setBackgroundColor($color) {
if($color === NULL or $color instanceof awColor) {
$this->background = $color;
}
}
/**
* Change component background gradient
*
* @param awGradient $gradient (can be null)
*/
public function setBackgroundGradient($gradient) {
if($gradient === NULL or $gradient instanceof awGradient) {
$this->background = $gradient;
}
}
/**
* Change component background image
*
* @param awImage $image (can be null)
*/
public function setBackgroundImage($image) {
if($image === NULL or $image instanceof awImage) {
$this->background = $image;
}
}
/**
* Return the component background
*
* @return Color, Gradient
*/
public function getBackground() {
return $this->background;
}
/**
* Change component padding
*
* @param int $left Padding in pixels (NULL to keep old value)
* @param int $right Padding in pixels (NULL to keep old value)
* @param int $top Padding in pixels (NULL to keep old value)
* @param int $bottom Padding in pixels (NULL to keep old value)
*/
public function setPadding($left = NULL, $right = NULL, $top = NULL, $bottom = NULL) {
$this->padding->set($left, $right, $top, $bottom);
}
/**
* Change component space
*
* @param float $left Space in % (NULL to keep old value)
* @param float $right Space in % (NULL to keep old value)
* @param float $bottom Space in % (NULL to keep old value)
* @param float $top Space in % (NULL to keep old value)
*/
public function setSpace($left = NULL, $right = NULL, $bottom = NULL, $top = NULL) {
$this->space->set($left, $right, $bottom, $top);
}
/**
* Change the absolute position of the component on the graph
*
* @var int $x Left-top corner X position
* @var int $y Left-top corner Y position
*/
public function setAbsPosition($left, $top) {
$this->left = (int)$left;
$this->top = (int)$top;
}
/**
* Set the center of the component
*
* @param int $x Position X of the center of the component
* @param int $y Position Y of the center of the component
*/
public function setCenter($x, $y) {
$this->x = (float)$x;
$this->y = (float)$y;
}
/**
* Get component coords with its padding
*
* @return array Coords of the component
*/
public function getPosition() {
// Get component coords
$x1 = $this->padding->left;
$y1 = $this->padding->top;
$x2 = $this->w - $this->padding->right;
$y2 = $this->h - $this->padding->bottom;
return array($x1, $y1, $x2, $y2);
}
/**
* Init the drawing of the component
*/
public function init(awDriver $driver) {
 
// Set component background
$background = $this->getBackground();
if($background !== NULL) {
$p1 = new awPoint(0, 0);
$p2 = new awPoint($this->w - 1, $this->h - 1);
if($background instanceof awImage) {
$driver->copyImage(
$background,
$p1,
$p2
);
} else {
$driver->filledRectangle(
$background,
new awLine($p1, $p2)
);
}
}
}
/**
* Finalize the drawing of the component
*/
public function finalize(awDriver $driver) {
// Draw component title
$point = new awPoint(
$this->w / 2,
$this->padding->top - 8
);
$this->title->draw($driver, $point);
// Draw legend
$this->legend->draw($driver);
}
/**
* Draw the grid around your component
*
* @param Driver A driver
* @return array Coords for the component
*/
abstract public function drawEnvelope(awDriver $driver);
/**
* Draw the component on the graph
* Component should be drawed into specified coords
*
* @param Driver A driver
* @param int $x1
* @param int $y1
* @param int $x2
* @param int $y2
* @param bool $aliasing Use anti-aliasing to draw the component ?
*/
abstract public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing);
/**
* Get space width in pixels
*
* @param int $width Component width
* @param int $height Component height
* @return array
*/
protected function getSpace($width, $height) {
$left = (int)($width * $this->space->left / 100);
$right = (int)($width * $this->space->right / 100);
$top = (int)($height * $this->space->top / 100);
$bottom = (int)($height * $this->space->bottom / 100);
return array($left, $right, $top, $bottom);
}
}
 
registerClass('Component', TRUE);
?>
/tags/v1.0-Homere/bibliotheque/artichow/BarPlot.class.php
New file
0,0 → 1,364
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/Plot.class.php";
 
/**
* BarPlot
*
* @package Artichow
*/
class awBarPlot extends awPlot implements awLegendable {
/**
* Labels on your bar plot
*
* @var Label
*/
public $label;
/**
* Bar plot identifier
*
* @var int
*/
protected $identifier;
/**
* Bar plot number
*
* @var int
*/
protected $number;
/**
* Bar plot depth
*
* @var int
*/
protected $depth;
/**
* For moving bars
*
* @var int
*/
protected $move;
/**
* Bars shadow
*
* @var Shadow
*/
public $barShadow;
/**
* Bars border
*
* @var Border
*/
public $barBorder;
/**
* Bars padding
*
* @var Side
*/
protected $barPadding;
/**
* Bars space
*
* @var int
*/
protected $barSpace = 0;
/**
* Bars background
*
* @var Color, Gradient
*/
protected $barBackground;
/**
* Construct a new awBarPlot
*
* @param array $values Some numeric values for Y axis
* @param int $identifier Plot identifier
* @param int $number Bar plot number
* @param int $depth Bar plot depth in pixels
*/
public function __construct($values, $identifier = 1, $number = 1, $depth = 0) {
parent::__construct();
$this->label = new awLabel;
$this->barPadding = new awSide(0.08, 0.08, 0, 0);
$this->barShadow = new awShadow(awShadow::RIGHT_TOP);
$this->barBorder = new awBorder;
$this->setValues($values);
$this->identifier = (int)$identifier;
$this->number = (int)$number;
$this->depth = (int)$depth;
$this->move = new awSide;
// Hide vertical grid
$this->grid->hideVertical(TRUE);
}
/**
* Change bars padding
* This method is not compatible with awBarPlot::setBarPadding()
*
* @param float $left Left padding (between 0 and 1)
* @param float $right Right padding (between 0 and 1)
*/
public function setBarPadding($left = NULL, $right = NULL) {
$this->barPadding->set($left, $right);
}
/**
* Change bars size
* This method is not compatible with awBarPlot::setBarPadding()
*
* @param int $width Bars size (between 0 and 1)
*/
public function setBarSize($size) {
$padding = (1 - $size) / 2;
$this->barPadding->set($padding, $padding);
}
/**
* Move bars
*
* @param int $x
* @param int $y
*/
public function move($x, $y) {
$this->move->set($x, NULL, $y, NULL);
}
/**
* Change bars space
*
* @param int $space Space in pixels
*/
public function setBarSpace($space) {
$this->barSpace = (int)$space;
}
/**
* Change line background color
*
* @param awColor $color
*/
public function setBarColor(awColor $color) {
$this->barBackground = $color;
}
/**
* Change line background gradient
*
* @param awGradient $gradient
*/
public function setBarGradient(awGradient $gradient) {
$this->barBackground = $gradient;
}
 
/**
* Get the line thickness
*
* @return int
*/
public function getLegendLineThickness() {
}
 
/**
* Get the line type
*
* @return int
*/
public function getLegendLineStyle() {
}
 
/**
* Get the color of line
*
* @return Color
*/
public function getLegendLineColor() {
}
 
/**
* Get the background color or gradient of an element of the component
*
* @return Color, Gradient
*/
public function getLegendBackground() {
return $this->barBackground;
}
 
/**
* Get a mark object
*
* @return Mark
*/
public function getLegendMark() {
}
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
$count = count($this->datay);
$max = $this->getRealYMax(NULL);
$min = $this->getRealYMin(NULL);
// Find zero for bars
if($this->xAxisZero and $min <= 0 and $max >= 0) {
$zero = 0;
} else if($max < 0) {
$zero = $max;
} else {
$zero = $min;
}
// Get base position
$zero = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint(0, $zero));
// Distance between two values on the graph
$distance = $this->xAxis->getDistance(0, 1);
// Compute paddings
$leftPadding = $this->barPadding->left * $distance;
$rightPadding = $this->barPadding->right * $distance;
$padding = $leftPadding + $rightPadding;
$space = $this->barSpace * ($this->number - 1);
$barSize = ($distance - $padding - $space) / $this->number;
$barPosition = $leftPadding + $barSize * ($this->identifier - 1);
for($key = 0; $key < $count; $key++) {
$value = $this->datay[$key];
if($value !== NULL) {
$position = awAxis::toPosition(
$this->xAxis,
$this->yAxis,
new awPoint($key, $value)
);
$barStart = $barPosition + ($this->identifier - 1) * $this->barSpace + $position->x;
$barStop = $barStart + $barSize;
$t1 = min($zero->y, $position->y);
$t2 = max($zero->y, $position->y);
if(round($t2 - $t1) == 0) {
continue;
}
$p1 = new awPoint(
round($barStart) + $this->depth + $this->move->left,
round($t1) - $this->depth + $this->move->top
);
$p2 = new awPoint(
round($barStop) + $this->depth + $this->move->left,
round($t2) - $this->depth + $this->move->top
);
$this->drawBar($driver, $p1, $p2);
}
}
// Draw labels
foreach($this->datay as $key => $value) {
if($value !== NULL) {
$position = awAxis::toPosition(
$this->xAxis,
$this->yAxis,
new awPoint($key, $value)
);
$point = new awPoint(
$barPosition + ($this->identifier - 1) * $this->barSpace + $position->x + $barSize / 2 + 1 + $this->depth,
$position->y - $this->depth
);
$this->label->draw($driver, $point, $key);
}
}
}
public function getXAxisNumber() {
return count($this->datay) + 1;
}
// ça bidouille à fond ici !
public function getXMax() {
return array_max($this->datax) + 1;
}
public function getXCenter() {
return TRUE;
}
protected function drawBar(awDriver $driver, awPoint $p1, awPoint $p2) {
// Draw shadow
$this->barShadow->draw(
$driver,
$p1,
$p2,
awShadow::OUT
);
if(abs($p2->y - $p1->y) > 1) {
$this->barBorder->rectangle(
$driver,
$p1,
$p2
);
if($this->barBackground !== NULL) {
$size = $this->barBorder->visible() ? 1 : 0;
$b1 = $p1->move($size, $size);
$b2 = $p2->move(-1 * $size, -1 * $size);
// Draw background
$driver->filledRectangle(
$this->barBackground,
new awLine($b1, $b2)
);
}
}
}
 
}
 
registerClass('BarPlot');
?>
/tags/v1.0-Homere/bibliotheque/artichow/README
New file
0,0 → 1,120
I. Installation
II. Configuration
III. Utilisation
IV. Divers
 
 
I. Installation
------------
 
*** Première installation ***
 
L'installation de Artichow se résume à décompresser l'archive dans le dossier
de votre choix sur votre serveur. Veillez simplement à télécharger l'archive
dont vous avez vraiment besoin (PHP 5 ou PHP 4 & 5).
Notez que Artichow requiert GD 2 et PHP 4.3.0 au minimum pour fonctionner.
 
*** Mise à jour ***
 
Lorsque vous souhaitez mettre à jour Artichow avec la dernière version,
essayez de suivre pas à pas ces étapes :
1) Décompressez la dernière version de Artichow dans un dossier
2) Ecrasez le fichier Artichow.cfg.php avec votre ancien fichier
3) Copiez vos patterns dans le dossier patterns/ de la nouvelle version
4) Supprimez l'ancienne version de Artichow de votre disque
5) Copiez la nouvelle version là où était l'ancienne
Une fois ces cinq étapes effectuées, vous n'aurez plus qu'à mettre
éventuellement à jour vos graphiques, en fonction des dernières évolutions de
l'API de Artichow. Pour cela, voyez le titre "Migrer d'une version à l'autre"
sur la page :
http://www.artichow.org/documentation
 
II. Configuration
-------------
 
Même si une utilisation normale de Artichow ne nécessite pas de configuration
particulière, il existe un fichier Artichow.cfg.php qui permet de modifier
quelques paramètres de la librairie.
Vous pouvez notamment configurer le répertoire vers les polices de caractère
en modifiant la constante ARTICHOW_FONT (par exemple en choisissant
'c:\Windows\font' si vous êtes sous Windows).
Vous pouvez également redéfinir la variable $fonts. Cette variable contient une
liste de polices TTF (sans l'extension) présentes dans votre répertoire
ARTICHOW_FONT. Pour toutes les polices de cette liste, une classe du même nom
est créée. Les polices ainsi définies peuvent ensuite être utilisées de cette
manière :
<?php
$font = new Verdana(12); // 12 représente la taille en points
?>
Il existe également une constante ARTICHOW_DEPRECATED. Si cette constante vaut
TRUE, alors un message d'erreur sera affiché lorsque vous utiliserez une
fonctionnalité dépréciée de Artichow. A l'inverse, avec la valeur FALSE,
vous pourrez continuer à utiliser les fonctions dépréciées sans soucis.
Cependant, dans un souci de compatibilité, il est préférable de mettre à
jour vos graphiques dès lors qu'un message de ce type apparaît (et donc de
laisser la constante à TRUE). Les fonctionnalités dépréciées sont toujours
potentiellement susceptibles de disparaître d'une version à l'autre de la
librairie.
La constante ARTICHOW_PREFIX est vide par défaut et correspond à un préfixe qui
est ajouté au nom de chaque classe utilisée sur Artichow. Certains noms de
classe (Graph, Image, Text, Font, etc.) sont utilisés par d'autres librairies
et cela peut aboutir à des conflits. Pour résoudre ce problème, choisissez par
exemple 'xyz' comme préfixe et toutes les classes de Artichow s'appèleront
désormais xyz[Nom normal]. Exemple d'utilisation de Artichow avec
ARTICHOW_PREFIX à 'xyz' :
<?php
require_once "Artichow/LinePlot.class.php";
 
$plot = new xyzLinePlot(array(1, 2, 3));
$plot->title->set('Mon graphique');
$plot->title->setFont(new xyzFont4);
 
$graph = new xyzGraph(400, 300);
$graph->add($plot);
$graph->draw();
?>
 
 
III. Utilisation
-----------
 
Si vous utilisez la version conçue exclusivement pour PHP 5, vous pouvez vous
référer aux exemples et aux tutoriels afin de bien prendre en main la
librairie.
Si vous utilisez la version pour PHP 4 & 5, référez vous également aux exemples
et tutoriels mais faîtes attention lors de l'inclusion des fichiers de
Artichow. N'incluez pas les fichiers de cette manière :
<?php
// Ceci ne fonctionnera pas
require_once "Artichow/php5/LinePlot.class.php";
// Cela non plus
require_once "Artichow/php4/LinePlot.class.php";
?>
Préférez plutôt :
<?php
// Fonctionnera correctement
require_once "Artichow/LinePlot.class.php";
?>
C'est la librairie qui se charge de sélectionner les bons fichiers en fonction
de la version de PHP dont vous disposez.
 
IV. Divers
------
 
La documentation de Artichow est disponible sur :
http://www.artichow.org/documentation
 
Des tutoriels sont accessibles sur :
http://www.artichow.org/tutorial
 
Un forum de support peut être trouvé sur :
http://www.artichow.org/forum/
 
N'oubliez pas que Artichow est dans le domaine public. Vous pouvez donc faire
CE QUE VOUS SOUHAITEZ avec cette librairie, y compris ajouter votre nom dans
chaque fichier, et la redistribuer ainsi.
 
Si vous souhaitez aider et participer au développement de Artichow, n'hésitez
pas à consulter cette page :
http://www.artichow.org/help
 
/tags/v1.0-Homere/bibliotheque/artichow/ScatterPlot.class.php
New file
0,0 → 1,300
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/Plot.class.php";
 
/**
* ScatterPlot
*
* @package Artichow
*/
class awScatterPlot extends awPlot implements awLegendable {
/**
* Add marks to the scatter plot
*
* @var Mark
*/
public $mark;
/**
* Labels on the plot
*
* @var Label
*/
public $label;
/**
* Link points ?
*
* @var bool
*/
protected $link = FALSE;
/**
* Display impulses
*
* @var bool
*/
protected $impulse = NULL;
/**
* Link NULL points ?
*
* @var bool
*/
protected $linkNull = FALSE;
/**
* Line color
*
* @var Color
*/
protected $lineColor;
/**
* Line type
*
* @var int
*/
protected $lineStyle = awLine::SOLID;
/**
* Line thickness
*
* @var int
*/
protected $lineThickness = 1;
/**
* Construct a new awScatterPlot
*
* @param array $datay Numeric values for Y axis
* @param array $datax Numeric values for X axis
* @param int $mode
*/
public function __construct($datay, $datax = NULL) {
parent::__construct();
// Defaults marks
$this->mark = new awMark;
$this->mark->setType(awMark::CIRCLE);
$this->mark->setSize(7);
$this->mark->border->show();
$this->label = new awLabel;
$this->setValues($datay, $datax);
$this->setColor(new awBlack);
}
/**
* Display plot as impulses
*
* @param awColor $impulse Impulses color (or NULL to disable impulses)
*/
public function setImpulse($color) {
$this->impulse = $color;
}
/**
* Link scatter plot points
*
* @param bool $link
* @param awColor $color Line color (default to black)
*/
public function link($link, $color = NULL) {
$this->link = (bool)$link;
if($color instanceof awColor) {
$this->setColor($color);
}
}
/**
* Ignore null values for Y data and continue linking
*
* @param bool $link
*/
public function linkNull($link) {
$this->linkNull = (bool)$link;
}
/**
* Change line color
*
* @param awColor $color
*/
public function setColor(awColor $color) {
$this->lineColor = $color;
}
/**
* Change line style
*
* @param int $style
*/
public function setStyle($style) {
$this->lineStyle = (int)$style;
}
/**
* Change line tickness
*
* @param int $tickness
*/
public function setThickness($tickness) {
$this->lineThickness = (int)$tickness;
}
 
/**
* Get the line thickness
*
* @return int
*/
public function getLegendLineThickness() {
return $this->lineThickness;
}
 
/**
* Get the line type
*
* @return int
*/
public function getLegendLineStyle() {
return $this->lineStyle;
}
 
/**
* Get the color of line
*
* @return Color
*/
public function getLegendLineColor() {
return $this->lineColor;
}
 
/**
* Get the background color or gradient of an element of the component
*
* @return Color, Gradient
*/
public function getLegendBackground() {
return NULL;
}
 
/**
* Get a mark object
*
* @return Mark
*/
public function getLegendMark() {
return $this->mark;
}
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
$count = count($this->datay);
// Get start and stop values
list($start, $stop) = $this->getLimit();
// Build the polygon
$polygon = new awPolygon;
for($key = 0; $key < $count; $key++) {
$x = $this->datax[$key];
$y = $this->datay[$key];
if($y !== NULL) {
$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($x, $y));
$polygon->set($key, $p);
} else if($this->linkNull === FALSE) {
$polygon->set($key, NULL);
}
}
// Link points if needed
if($this->link) {
$prev = NULL;
foreach($polygon->all() as $point) {
if($prev !== NULL and $point !== NULL) {
$driver->line(
$this->lineColor,
new awLine(
$prev,
$point,
$this->lineStyle,
$this->lineThickness
)
);
}
$prev = $point;
}
}
// Draw impulses
if($this->impulse instanceof awColor) {
foreach($polygon->all() as $key => $point) {
if($point !== NULL) {
$zero = awAxis::toPosition(
$this->xAxis,
$this->yAxis,
new awPoint($key, 0)
);
$driver->line(
$this->impulse,
new awLine(
$zero,
$point,
awLine::SOLID,
1
)
);
}
}
}
// Draw marks and labels
foreach($polygon->all() as $key => $point) {
 
$this->mark->draw($driver, $point);
$this->label->draw($driver, $point, $key);
}
}
protected function xAxisPoint($position) {
$y = $this->xAxisZero ? 0 : $this->getRealYMin();
return awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($position, $y));
}
public function getXCenter() {
return FALSE;
}
 
}
 
registerClass('ScatterPlot');
?>
/tags/v1.0-Homere/bibliotheque/artichow/patterns/BarDepth.php
New file
0,0 → 1,85
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once ARTICHOW."/BarPlot.class.php";
 
class BarDepthPattern extends Pattern {
 
protected function getPlot($y, $depth) {
$plot = new BarPlot($y, 1, 1, $depth);
$plot->barShadow->setSize(2);
$plot->barShadow->smooth(TRUE);
$plot->barShadow->setColor(new Color(160, 160, 160, 10));
return $plot;
}
 
public function create() {
 
$group = new PlotGroup;
$group->setSpace(2, 2, 2, 0);
$group->setPadding(30, 10, NULL, NULL);
$group->grid->hideVertical(TRUE);
$group->grid->setType(Line::DASHED);
$yForeground = $this->getArg('yForeground');
$yBackground = $this->getArg('yBackground');
$legendForeground = $this->getArg('legendForeground');
$legendBackground = $this->getArg('legendBackground');
$colorForeground = $this->getArg('colorForeground', new LightBlue(10));
$colorBackground = $this->getArg('colorBackground', new Orange(25));
if($yForeground === NULL) {
awImage::drawError("Class BarDepthPattern: Argument 'yForeground' must not be NULL.");
}
// Background
if($yBackground !== NULL) {
$plot = $this->getPlot($yBackground, 6);
$plot->setBarColor($colorBackground);
$group->add($plot);
if($legendBackground !== NULL) {
$group->legend->add($plot, $legendBackground, Legend::BACKGROUND);
}
}
// Foreground
$plot = $this->getPlot($yForeground, 0);
$plot->setBarColor($colorForeground);
$group->add($plot);
if($legendForeground !== NULL) {
$group->legend->add($plot, $legendForeground, Legend::BACKGROUND);
}
$group->axis->bottom->hideTicks(TRUE);
$group->legend->shadow->setSize(0);
$group->legend->setAlign(Legend::CENTER);
$group->legend->setSpace(6);
$group->legend->setTextFont(new Tuffy(8));
$group->legend->setPosition(0.50, 0.10);
$group->legend->setBackgroundColor(new Color(255, 255, 255, 10));
$group->legend->setColumns(2);
return $group;
 
}
 
}
?>
/tags/v1.0-Homere/bibliotheque/artichow/patterns/LightLine.php
New file
0,0 → 1,50
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once ARTICHOW."/LinePlot.class.php";
 
class LightLinePattern extends Pattern {
 
public function create() {
$legend = $this->getArg('legend');
$y = $this->getArg('y');
if($y === NULL) {
awImage::drawError("Class LightLinePattern: Argument 'y' must not be NULL.");
}
$plot = new LinePlot($y);
$plot->setSize(0.7, 1);
$plot->setCenter(0.35, 0.5);
$plot->setPadding(35, 15, 35, 30);
$plot->setColor(new Orange());
$plot->setFillColor(new LightOrange(80));
$plot->grid->setType(Line::DASHED);
$plot->mark->setType(Mark::CIRCLE);
$plot->mark->setFill(new MidRed);
$plot->mark->setSize(6);
$plot->legend->setPosition(1, 0.5);
$plot->legend->setAlign(Legend::LEFT);
$plot->legend->shadow->smooth(TRUE);
if($legend !== NULL) {
$plot->legend->add($plot, $legend, Legend::MARK);
}
return $plot;
 
}
 
}
?>
/tags/v1.0-Homere/bibliotheque/artichow/DEPRECATED
New file
0,0 → 1,3
Artichow 1.0.9
 
- Pie::setBorder(): replaced by Pie::setBorderColor()
/tags/v1.0-Homere/bibliotheque/artichow/cache/Abel
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/cache/Abel
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/cache/Albert-time
New file
0,0 → 1,2
1166203480
png
/tags/v1.0-Homere/bibliotheque/artichow/cache/Albert
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/cache/Albert
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/cache/Example-006-time
New file
0,0 → 1,2
1166203465
png
/tags/v1.0-Homere/bibliotheque/artichow/cache/Example-006
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/cache/Example-006
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/cache/Abel-time
New file
0,0 → 1,2
1166203484
png
/tags/v1.0-Homere/bibliotheque/artichow/Artichow.cfg.php
New file
0,0 → 1,85
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
/*
* Path to Artichow
*/
 
define('ARTICHOW', dirname(__FILE__));
 
 
/*
* Path to TrueType fonts
* DO NOT USE FONT PATH WITH SPACE CHARACTER (" ") WITH GD <= 2.0.18
*/
if(!defined('ARTICHOW_FONT')) {
define('ARTICHOW_FONT', ARTICHOW.DIRECTORY_SEPARATOR.'font');
}
 
/*
* Patterns directory
*/
if(!defined('ARTICHOW_PATTERN')) {
define('ARTICHOW_PATTERN', ARTICHOW.DIRECTORY_SEPARATOR.'patterns');
}
 
/*
* Images directory
*/
if(!defined('ARTICHOW_IMAGE')) {
define('ARTICHOW_IMAGE', ARTICHOW.DIRECTORY_SEPARATOR.'images');
}
 
/*
* Enable/disable cache support
*/
define('ARTICHOW_CACHE', TRUE);
 
/*
* Cache directory
*/
if(!defined('ARTICHOW_CACHE_DIRECTORY')) {
define('ARTICHOW_CACHE_DIRECTORY', ARTICHOW.DIRECTORY_SEPARATOR.'cache');
}
 
/*
* Prefix for class names
* No prefix by default
*/
define('ARTICHOW_PREFIX', '');
 
/*
* Trigger errors when use of a deprecated feature
*/
define('ARTICHOW_DEPRECATED', TRUE);
 
/*
* Defines the default driver
*/
define('ARTICHOW_DRIVER', 'gd');
 
/*
* Fonts to use
*/
$fonts = array(
'Tuffy',
'TuffyBold',
'TuffyBoldItalic',
'TuffyItalic'
);
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/images/book.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/images/book.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/images/paperclip.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/images/paperclip.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/images/error.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/images/error.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/images/errors/missing-gd2.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/images/errors/missing-gd2.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/images/errors/missing-anti-aliasing.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/images/errors/missing-anti-aliasing.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/images/star.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/images/star.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/Border.html
New file
0,0 → 1,154
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Border</h2><div class="description">
<p>La classe <a href="Border.html">Border</a> permet de centraliser la gestion des bordures sur Artichow.</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">protected</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Border.html#property.color"><span class="argument">$color</span></a> := <span class="default">new Black</span>
</li>
<li>
<span class="access">protected</span> <span class="type">int</span> <a href="Border.html#property.style"><span class="argument">$style</span></a> := <span class="default">Line::SOLID</span>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Border.html#property.hide"><span class="argument">$hide</span></a> := <span class="default">FALSE</span>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Border.html#method.__construct">__construct</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span> := <span class="default">new Black</span>, <span class="type">int</span> <span class="argument">$style</span> := <span class="default">Line::SOLID</span>)
</li>
<li>
<span class="access">public</span> <a href="Border.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Border.html#method.setStyle">setStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
</li>
<li>
<span class="access">public</span> <a href="Border.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="Border.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <span class="type">bool</span> <a href="Border.html#method.visible">visible</a>()
</li>
<li>
<span class="access">public</span> <a href="Border.html#method.rectangle">rectangle</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
</li>
<li>
<span class="access">public</span> <a href="Border.html#method.ellipse">ellipse</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
</li>
<li>
<span class="access">public</span> <a href="Border.html#method.polygon">polygon</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.color"></a><span class="access">protected</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Border.html#property.color"><span class="argument">$color</span></a> := <span class="default">new Black</span><div class="description">
La couleur de la bordure
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.style"></a><span class="access">protected</span> <span class="type">int</span> <a href="Border.html#property.style"><span class="argument">$style</span></a> := <span class="default">Line::SOLID</span><div class="description">
Style de la ligne qui compose la bordure.
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.hide"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Border.html#property.hide"><span class="argument">$hide</span></a> := <span class="default">FALSE</span><div class="description">
Est-ce que la bordure doit être cachée ?
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Border.html#method.__construct">__construct</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span> := <span class="default">new Black</span>, <span class="type">int</span> <span class="argument">$style</span> := <span class="default">Line::SOLID</span>)
<div class="description">
Déclare une nouvelle bordure de couleur $color et avec pour style $style.
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColor"></a><span class="access">public</span> <a href="Border.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de la bordure pour $color.
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setStyle"></a><span class="access">public</span> <a href="Border.html#method.setStyle">setStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
<div class="description">
Change le style de la bordure pour $style.
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hide"></a><span class="access">public</span> <a href="Border.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
<div class="description">
Détermine si la bordure doit être cachée ou non.
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.show"></a><span class="access">public</span> <a href="Border.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span> := <span class="default">TRUE</span>)
<div class="description">
Détermine si la bordure doit être affichée ou non.
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.visible"></a><span class="access">public</span> <span class="type">bool</span> <a href="Border.html#method.visible">visible</a>()
<div class="description">
Retourne TRUE si la bordure doit être affichée, FALSE sinon.
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.rectangle"></a><span class="access">public</span> <a href="Border.html#method.rectangle">rectangle</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
<div class="description">
Dessine la bordure sous la forme d'un rectangle dont la diagonale s'étend des points $p1 à $p2.
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.ellipse"></a><span class="access">public</span> <a href="Border.html#method.ellipse">ellipse</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
<div class="description">
Dessine la bordure sous la forme d'une ellipse de centre $center et de largeur et hauteur respectives $width et $height.
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.polygon"></a><span class="access">public</span> <a href="Border.html#method.polygon">polygon</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Dessine la bordure comme un polygone entourant celui passé en argument.
</div>
<div class="description-bottom"><a href="Border.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/PHPFont.html
New file
0,0 → 1,73
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class PHPFont</h2><div class="extends"><ul>
<li><a href="Font.html">Font</a></li>
<ul><li>PHPFont</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="PHPFont.html">PHPFont</a> permet de gérer les polices fournie avec PHP. Ce sont des polices pouvant subir peu de transformation (rotation de 90° uniquement par exemple).
</p>
<p>
Il existe 5 polices prédéfinies, ainsi que les 5 classes "raccourcies" correspondantes:
<pre>
 
&lt;?php
 
// Equivalent à new <a href="PHPFont.html">PHPFont</a>(1);
$font = new Font1;
 
// Equivalent à new <a href="PHPFont.html">PHPFont</a>(2);
$font = new Font2;
 
// etc.
 
?&gt;
 
</pre>
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties"><li>
<span class="access">public</span> <span class="type">int</span> <a href="PHPFont.html#property.font"><span class="argument">$font</span></a>
</li></ul><ul class="methods"><li>
<span class="access">public</span> <a href="PHPFont.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$font</span>)
</li></ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.font"></a><span class="access">public</span> <span class="type">int</span> <a href="PHPFont.html#property.font"><span class="argument">$font</span></a><div class="description">
L'identifiant de la police, de 1 à 5.
</div>
<div class="description-bottom"><a href="PHPFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="PHPFont.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$font</span>)
<div class="description">
Construit la police d'identifiant $font.
</div>
<div class="description-bottom"><a href="PHPFont.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Color.html
New file
0,0 → 1,168
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Color</h2><div class="description">
<p>
La classe <a href="Color.html">Color</a> permet de gérer les couleurs de manière uniforme sur Artichow.
</p>
<p>
Afin de simplifier l'utilisation de cette classe, plusieurs couleurs sont déjà prédéfinies sur Artichow.
Chacune de ces couleurs est une classe qui dérive de <a href="Color.html">Color</a> et dont le constructeur ne prend qu'un paramètre, le degré de transparence. Voici les couleurs prédéfinies triées par ton :
</p>
<ul>
<li>
<em>Gris :</em> Black, AlmostBlack, VeryDarkGray, DarkGray, MidGray, LightGray, VeryLightGray, White</li>
<li>
<em>Rouge :</em> VeryDarkRed, DarkRed, MidRed, Red, LightRed</li>
<li>
<em>Vert :</em> VeryDarkGreen, DarkGreen, MidGreen, Green, LightGreen</li>
<li>
<em>Bleu :</em> VeryDarkBlue, DarkBlue, MidBlue, Blue, LightBlue</li>
<li>
<em>Jaune :</em> VeryDarkYellow, DarkYellow, MidYellow, Yellow, LightYellow</li>
<li>
<em>Cyan :</em> VeryDarkCyan, DarkCyan, MidCyan, Cyan, LightCyan</li>
<li>
<em>Magenta :</em> VeryDarkMagenta, DarkMagenta, MidMagenta, Magenta, LightMagenta</li>
<li>
<em>Orange :</em> DarkOrange, Orange, LightOrange, VeryLightOrange</li>
<li>
<em>Rose :</em> DarkPink, Pink, LightPink, VeryLightPink</li>
<li>
<em>Violet :</em> DarkPurple, Purple, LightPurple, VeryLightPurple</li>
</ul>
<p>
Voici un exemple d'utilisation pour les couleurs prédéfinies :
<pre>
 
&lt;?php
 
// On créé un bleu foncé
$blue = new DarkBlue; // Equivalent à new <a href="Color.html">Color</a>(0, 0, 128);
 
// On créé de l'orange transparent à 50 %
$orange = new Orange(50); // Equivalent à new <a href="Color.html">Color</a>(255, 128, 0, 50);
 
?&gt;
 
</pre>
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Color.html#property.red"><span class="argument">$red</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Color.html#property.green"><span class="argument">$green</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Color.html#property.blue"><span class="argument">$blue</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Color.html#property.alpha"><span class="argument">$alpha</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Color.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$red</span>, <span class="type">int</span> <span class="argument">$green</span>, <span class="type">int</span> <span class="argument">$blue</span>, <span class="type">int</span> <span class="argument">$alpha</span> := <span class="default">0</span>)
</li>
<li>
<span class="access">public</span> <a href="Color.html#method.brightness">brightness</a>(<span class="type">int</span> <span class="argument">$brightness</span>)
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Color.html#method.getColor">getColor</a>()
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Color.html#method.rgba">rgba</a>()
</li>
<li>
<span class="access">public</span> <a href="Color.html#method.free">free</a>()
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.red"></a><span class="access">public</span> <span class="type">int</span> <a href="Color.html#property.red"><span class="argument">$red</span></a><div class="description">
Intensité en rouge de la couleur (entre 0 et 255)
</div>
<div class="description-bottom"><a href="Color.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.green"></a><span class="access">public</span> <span class="type">int</span> <a href="Color.html#property.green"><span class="argument">$green</span></a><div class="description">
Intensité en vert de la couleur (entre 0 et 255)
</div>
<div class="description-bottom"><a href="Color.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.blue"></a><span class="access">public</span> <span class="type">int</span> <a href="Color.html#property.blue"><span class="argument">$blue</span></a><div class="description">
Intensité en blue de la couleur (entre 0 et 255)
</div>
<div class="description-bottom"><a href="Color.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.alpha"></a><span class="access">public</span> <span class="type">int</span> <a href="Color.html#property.alpha"><span class="argument">$alpha</span></a><div class="description">
Degré de transparence de la couleur (entre 0 et 100)
</div>
<div class="description-bottom"><a href="Color.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Color.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$red</span>, <span class="type">int</span> <span class="argument">$green</span>, <span class="type">int</span> <span class="argument">$blue</span>, <span class="type">int</span> <span class="argument">$alpha</span> := <span class="default">0</span>)
<div class="description">
Construit une nouvelle couleur. Les trois premiers paramètres représentent l'intensité en rouge, vert et bleu pour cette couleur. L'intensité de chaque couleur est un nombre compris entre 0 et 255 (du foncé vers le clair). Le paramètre $alpha représente le dégré de transparence de la couleur, et doit être compris entre 0 et 100.
</div>
<div class="description-bottom"><a href="Color.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.brightness"></a><span class="access">public</span> <a href="Color.html#method.brightness">brightness</a>(<span class="type">int</span> <span class="argument">$brightness</span>)
<div class="description">
Change la luminosité de la couleur, en ajoutant la valeur $brightness à chaque composante (rouge, vert, bleu) de cette couleur.
$brightness peut prendre des valeurs comprises entre -255 et +255.
</div>
<div class="description-bottom"><a href="Color.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getColor"></a><span class="access">public</span> <span class="type">array</span> <a href="Color.html#method.getColor">getColor</a>()
<div class="description">
Retourne un tableau de quatre valeurs qui représentent l'intensité en rouge, vert et bleu ainsi que le degré de transparence de la couleur.
</div>
<div class="description-bottom"><a href="Color.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.rgba"></a><span class="access">public</span> <span class="type">array</span> <a href="Color.html#method.rgba">rgba</a>()
<div class="description">
Retourne un tableau de quatre valeurs qui représentent l'intensité en rouge, vert et bleu ainsi que le degré de transparence de la couleur.
</div>
<div class="description-bottom"><a href="Color.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.free"></a><span class="access">public</span> <a href="Color.html#method.free">free</a>()
<ul class="version"><li>
Supprimé à partir d'Artichow 1.1.0</li></ul>
<div class="description">
Libère les ressources allouées lors de l'appel à <a href="Color.html#method.getColor">getColor()</a>.
</div>
<div class="description-bottom"><a href="Color.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Label.html
New file
0,0 → 1,423
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Label</h2><div class="description">
<p>
La classe <a href="Label.html">Label</a> permet de créer et d'afficher des étiquettes de texte sur des images.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <a href="Border.html"><span class="type">Border</span></a> <a href="Label.html#property.border"><span class="argument">$border</span></a> := <span class="default">new Border</span>
</li>
<li>
<span class="access">protected</span> <a href="Font.html"><span class="type">Font</span></a> <a href="Label.html#property.font"><span class="argument">$font</span></a> := <span class="default">new Font(Font::FONT_2)</span>
</li>
<li>
<span class="access">protected</span> <span class="type">int</span> <a href="Label.html#property.angle"><span class="argument">$angle</span></a> := <span class="default">0</span>
</li>
<li>
<span class="access">protected</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Label.html#property.color"><span class="argument">$color</span></a> := <span class="default">new Color(0, 0, 0)</span>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Label.html#property.hide"><span class="argument">$hide</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Label.html#property.hideFirst"><span class="argument">$hideFirst</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Label.html#property.hideLast"><span class="argument">$hideLast</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">int</span> <a href="Label.html#property.interval"><span class="argument">$interval</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">int</span> <a href="Label.html#property.hAlign"><span class="argument">$hAlign</span></a> := <span class="default">Label::CENTER</span>
</li>
<li>
<span class="access">protected</span> <span class="type">int</span> <a href="Label.html#property.vAlign"><span class="argument">$vAlign</span></a> := <span class="default">Label::MIDDLE</span>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Label.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$label</span> := <span class="default">NULL</span>, <a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span> := <span class="default">new Font(Text::FONT_2)</span>, <a href="color.html"><span class="type">color</span></a> <span class="argument">$color</span> := <span class="default">new Color(0, 0, 0)</span>, <span class="type">int</span> <span class="argument">$angle</span> := <span class="default">0</span>)
</li>
<li>
<span class="access">public</span> <span class="type">mixed</span> <a href="Label.html#method.get">get</a>(<span class="type">int</span> <span class="argument">$key</span>)
</li>
<li>
<span class="access">public</span> <span class="type">mixed</span> <a href="Label.html#method.all">all</a>()
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.set">set</a>(<span class="type">mixed</span> <span class="argument">$labels</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Label.html#method.count">count</a>()
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setCallbackFunction">setCallbackFunction</a>(<span class="type">mixed</span> <span class="argument">$function</span>)
</li>
<li>
<span class="access">public</span> <span class="type">string</span> <a href="Label.html#method.getCallbackFunction">getCallbackFunction</a>()
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setFormat">setFormat</a>(<span class="type">string</span> <span class="argument">$format</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setFont">setFont</a>(<a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setAngle">setAngle</a>(<span class="type">int</span> <span class="argument">$angle</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setBackground">setBackground</a>(<span class="type">mixed</span> <span class="argument">$background</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setBackgroundGradient">setBackgroundGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setPadding">setPadding</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>, <span class="type">int</span> <span class="argument">$top</span>, <span class="type">int</span> <span class="argument">$bottom</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.hideKey">hideKey</a>(<span class="type">int</span> <span class="argument">$key</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.hideFirst">hideFirst</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.hideLast">hideLast</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setInterval">setInterval</a>(<span class="type">int</span> <span class="argument">$interval</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.move">move</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.setAlign">setAlign</a>(<span class="type">int</span> <span class="argument">$h</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$v</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="Text.html"><span class="type">Text</span></a> <a href="Label.html#method.getText">getText</a>(<span class="type">int</span> <span class="argument">$key</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Label.html#method.getMaxWidth">getMaxWidth</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Label.html#method.getMaxHeight">getMaxHeight</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
</li>
<li>
<span class="access">public</span> <a href="Label.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>, <span class="type">int</span> <span class="argument">$key</span> := <span class="default">0</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.border"></a><span class="access">public</span> <a href="Border.html"><span class="type">Border</span></a> <a href="Label.html#property.border"><span class="argument">$border</span></a> := <span class="default">new Border</span><div class="description">
La bordure associée à l'étiquette.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.font"></a><span class="access">protected</span> <a href="Font.html"><span class="type">Font</span></a> <a href="Label.html#property.font"><span class="argument">$font</span></a> := <span class="default">new Font(Font::FONT_2)</span><div class="description">
La police utilisée pour ce paragraphe.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.angle"></a><span class="access">protected</span> <span class="type">int</span> <a href="Label.html#property.angle"><span class="argument">$angle</span></a> := <span class="default">0</span><div class="description">
L'angle du texte du paragraphe.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.color"></a><span class="access">protected</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Label.html#property.color"><span class="argument">$color</span></a> := <span class="default">new Color(0, 0, 0)</span><div class="description">
La couleur du texte du paragraphe.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.hide"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Label.html#property.hide"><span class="argument">$hide</span></a><div class="description">
Détermine si les étiquettes doivent être cachées.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.hideFirst"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Label.html#property.hideFirst"><span class="argument">$hideFirst</span></a><div class="description">
Détermine si la première étiquette doit être cachée.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.hideLast"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Label.html#property.hideLast"><span class="argument">$hideLast</span></a><div class="description">
Détermine si la dernière étiquette doit être cachée.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.interval"></a><span class="access">protected</span> <span class="type">int</span> <a href="Label.html#property.interval"><span class="argument">$interval</span></a><div class="description">
L'interval d'affichage des étiquettes.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.hAlign"></a><span class="access">protected</span> <span class="type">int</span> <a href="Label.html#property.hAlign"><span class="argument">$hAlign</span></a> := <span class="default">Label::CENTER</span><div class="description">
L'alignement horizontal des étiquettes.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.vAlign"></a><span class="access">protected</span> <span class="type">int</span> <a href="Label.html#property.vAlign"><span class="argument">$vAlign</span></a> := <span class="default">Label::MIDDLE</span><div class="description">
L'alignement vertical des étiquettes.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Label.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$label</span> := <span class="default">NULL</span>, <a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span> := <span class="default">new Font(Text::FONT_2)</span>, <a href="color.html"><span class="type">color</span></a> <span class="argument">$color</span> := <span class="default">new Color(0, 0, 0)</span>, <span class="type">int</span> <span class="argument">$angle</span> := <span class="default">0</span>)
<div class="description">
Construit un nouvel objet qui permettra l'affichage d'étiquettes sur une image.
$label est un chaîne de caractères qui représente la première étiquette (peut être laissée à NULL).
$font est la police à utiliser pour l'étiquette tandis que $color sera utilisé pour la couleur du texte.
Enfin, l'angle du texte prendra la valeur de $angle.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.get"></a><span class="access">public</span> <span class="type">mixed</span> <a href="Label.html#method.get">get</a>(<span class="type">int</span> <span class="argument">$key</span>)
<div class="description">
Retourne la valeur de l'élément de l'étiquette dont la clé vaut $key.
Si la clé n'est associée à aucune valeur, alors cette méthode retourne NULL.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.all"></a><span class="access">public</span> <span class="type">mixed</span> <a href="Label.html#method.all">all</a>()
<div class="description">
Retourne toutes la valeur de toutes les étiquettes sous la forme d'un tableau.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.set"></a><span class="access">public</span> <a href="Label.html#method.set">set</a>(<span class="type">mixed</span> <span class="argument">$labels</span>)
<div class="description">
Change le texte des étiquettes à afficher sur l'image.
$labels peut être une chaîne de caractères si vous n'avez besoin que d'une étiquette, ou un tableau de chaînes de caractères si vous avez besoin de plusieurs étiquettes.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.count"></a><span class="access">public</span> <span class="type">int</span> <a href="Label.html#method.count">count</a>()
<div class="description">
Retourne le nombre de textes dans le paragraphe.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setCallbackFunction"></a><span class="access">public</span> <a href="Label.html#method.setCallbackFunction">setCallbackFunction</a>(<span class="type">mixed</span> <span class="argument">$function</span>)
<div class="description">
Change le nom de la fonction de callback qui sera appelé lors du dessin des textes du paragraphe. $function peut être une simple chaîne de caractères, ou un tableau du type <span style="font-style: italic;">array($this, 'methodName')</span> pour permettre d'appeler des méthodes statiques.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getCallbackFunction"></a><span class="access">public</span> <span class="type">string</span> <a href="Label.html#method.getCallbackFunction">getCallbackFunction</a>()
<div class="description">
Retourne le nom de la fonction de callback actuellement utilisée.
Si aucune fonction de callback n'a été spécifiée, alors NULL sera retourné.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setFormat"></a><span class="access">public</span> <a href="Label.html#method.setFormat">setFormat</a>(<span class="type">string</span> <span class="argument">$format</span>)
<div class="description">
Formate le texte de chaque étiquette selon $format.
$format est du même format que les fonctions printf ou sprintf.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setFont"></a><span class="access">public</span> <a href="Label.html#method.setFont">setFont</a>(<a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span>)
<div class="description">
Change la police utilisée pour le texte de l'étiquette.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAngle"></a><span class="access">public</span> <a href="Label.html#method.setAngle">setAngle</a>(<span class="type">int</span> <span class="argument">$angle</span>)
<div class="description">
Change l'angle du texte de l'étiquette. Les valeurs possibles sont 0 ou 90°.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColor"></a><span class="access">public</span> <a href="Label.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur du texte de l'étiquette.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackground"></a><span class="access">public</span> <a href="Label.html#method.setBackground">setBackground</a>(<span class="type">mixed</span> <span class="argument">$background</span>)
<div class="description">
Change le fond du texte de l'étiquette.
$background peut être soit une couleur, soit un dégradé;
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundColor"></a><span class="access">public</span> <a href="Label.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de fond du texte de l'étiquette.
<div class="see">
Voir aussi :
<ul><li><a href="Label.html#method.setBackground">Label::setBackground()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundGradient"></a><span class="access">public</span> <a href="Label.html#method.setBackgroundGradient">setBackgroundGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
<div class="description">
Change le dégradé de fond du texte de l'étiquette.
<div class="see">
Voir aussi :
<ul><li><a href="Label.html#method.setBackground">Label::setBackground()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setPadding"></a><span class="access">public</span> <a href="Label.html#method.setPadding">setPadding</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>, <span class="type">int</span> <span class="argument">$top</span>, <span class="type">int</span> <span class="argument">$bottom</span>)
<div class="description">
Change la valeur de l'espace qui entoure le texte par rapport à sa bordure.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hide"></a><span class="access">public</span> <a href="Label.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
<div class="description">
Détermine si toutes les étiquettes doivent être cachées ou non.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.show"></a><span class="access">public</span> <a href="Label.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span>)
<div class="description">
Détermine si toutes les étiquettes doivent être affichées ou non.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hideKey"></a><span class="access">public</span> <a href="Label.html#method.hideKey">hideKey</a>(<span class="type">int</span> <span class="argument">$key</span>)
<div class="description">
Détermine si l'étiquette de clé $key doit être cachée ou non.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hideFirst"></a><span class="access">public</span> <a href="Label.html#method.hideFirst">hideFirst</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
<div class="description">
Détermine si la première étiquette doit être cachée ou non.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hideLast"></a><span class="access">public</span> <a href="Label.html#method.hideLast">hideLast</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
<div class="description">
Détermine si la dernière étiquette doit être cachée ou non.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setInterval"></a><span class="access">public</span> <a href="Label.html#method.setInterval">setInterval</a>(<span class="type">int</span> <span class="argument">$interval</span>)
<div class="description">
Change l'interval d'affichage des étiquettes.
L'interval est à 1 par défaut, ce qui signifie que toutes les étiquettes sont affichées.
Si cet interval est placé à 2 par exemple, alors la méthode <a href="Label.html#method.draw">draw()</a> n'affichera qu'une étiquette sur 2.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.move"></a><span class="access">public</span> <a href="Label.html#method.move">move</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
<div class="description">
Déplace l'affichage de l'étiquette de $x pixels sur l'axe des abscisses et de $y pixels sur l'axe des ordonnées.
Les appels à <a href="Label.html#method.move">move()</a> sont cumulés, c'est-à-dire qu'un appel avec de nouvelles valeurs additionnera ces valeurs avec les anciennes.
Par défaut, $x et $y sont à 0.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAlign"></a><span class="access">public</span> <a href="Label.html#method.setAlign">setAlign</a>(<span class="type">int</span> <span class="argument">$h</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$v</span> := <span class="default">NULL</span>)
<div class="description">
Change l'alignement de l'étiquette par rapport au point où elle sera affichée.
$h correspond à l'alignement horizontal (<a href="Label.html#constant.LEFT">Positionable::LEFT</a>, <a href="Label.html#constant.RIGHT">Positionable::RIGHT</a> ou <a href="Label.html#constant.CENTER">Positionable::CENTER</a>) et $v à l'alignement vertical (<a href="Label.html#constant.TOP">Positionable::TOP</a>, <a href="Label.html#constant.BOTTOM">Positionable::BOTTOM</a> ou <a href="Label.html#constant.MIDDLE">Positionable::MIDDLE</a>).
Si vous ne souhaitez pas modifier une des deux valeurs, vous pouvez passer NULL.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getText"></a><span class="access">public</span> <a href="Text.html"><span class="type">Text</span></a> <a href="Label.html#method.getText">getText</a>(<span class="type">int</span> <span class="argument">$key</span>)
<div class="description">
Retourne un objet de type <a href="Text.html">Text</a> qui correspond à la valeur du tableau de textes passé au constructeur ou à <a href="Label.html#method.set">Label::set()</a> pour la clé $key.
Cette object <a href="Text.html">Text</a> se verra attribué toutes les propriétés (couleur, police, angle, etc.) définies pour le paragraphe.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getMaxWidth"></a><span class="access">public</span> <span class="type">int</span> <a href="Label.html#method.getMaxWidth">getMaxWidth</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
<div class="description">
Essaie de déterminer la longueur maximale des étiquettes. Cette méthode a besoin d'un <a href="Driver.html">Driver</a> pour établir la taille de chaque texte.
La longueur maximale trouvée est déterminée et rétournée en pixels.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getMaxHeight"></a><span class="access">public</span> <span class="type">int</span> <a href="Label.html#method.getMaxHeight">getMaxHeight</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
<div class="description">
Essaie de déterminer la hauteur maximale des étiquettes. Cette méthode a besoin d'un <a href="Driver.html">Driver</a> pour établir la taille de chaque texte.
La hauteur maximale trouvée est déterminée et rétournée en pixels.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.draw"></a><span class="access">public</span> <a href="Label.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>, <span class="type">int</span> <span class="argument">$key</span> := <span class="default">0</span>)
<div class="description">
Dessine l'étiquette identifiée par $key avec le pilote $driver. L'étiquette sera placée au point $point décalé des valeurs successivement passées à <a href="Label.html#method.move">move()</a>, et alignée par rapport à ce point selon les valeurs passées à <a href="Label.html#method.setAlign">setAlign()</a>.
L'étiquette ne sera pas affichée si sa clé $key n'est pas dans l'interval d'affichage donné avec <a href="Label.html#method.setInterval">setInterval()</a>.
</div>
<div class="description-bottom"><a href="Label.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-hd-transparent.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-hd-transparent.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-hd.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-hd.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-hg-transparent.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-hg-transparent.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-hg.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-hg.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/fond.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/fond.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/back-rayures.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/back-rayures.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/fond-flou.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/fond-flou.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-bd.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-bd.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-bd.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-bd.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-bg-long.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-bg-long.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-bg.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/doc/image/coin-bg.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/doc/Legendable.html
New file
0,0 → 1,86
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Legendable</h2><div class="description">
<p>
<a href="Legendable.html">Legendable</a> est une <span style="text-decoration: underline">interface</span> que doivent implémenter toutes les classes qui veulent profiter des possibilités offertes par la classe <a href="Legend.html">Legend</a>.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="methods">
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Legendable.html#method.getLegendLineStyle">getLegendLineStyle</a>()
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Legendable.html#method.getLegendLineThickness">getLegendLineThickness</a>()
</li>
<li>
<span class="access">public</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Legendable.html#method.getLegendLineColor">getLegendLineColor</a>()
</li>
<li>
<span class="access">public</span> <span class="type">mixed</span> <a href="Legendable.html#method.getLegendBackground">getLegendBackground</a>()
</li>
<li>
<span class="access">public</span> <a href="Mark.html"><span class="type">Mark</span></a> <a href="Legendable.html#method.getLegendMark">getLegendMark</a>()
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="method">
<a id="method.getLegendLineStyle"></a><span class="access">public</span> <span class="type">int</span> <a href="Legendable.html#method.getLegendLineStyle">getLegendLineStyle</a>()
<div class="description">
Retourne le type de ligne utilisé (<a href="Line.html#constant.SOLID">Line::SOLID</a>, <a href="Line.html#constant.DOTTED">Line::DOTTED</a> ou <a href="Line.html#constant.DASHED">Line::DASHED</a>).
</div>
<div class="description-bottom"><a href="Legendable.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getLegendLineThickness"></a><span class="access">public</span> <span class="type">int</span> <a href="Legendable.html#method.getLegendLineThickness">getLegendLineThickness</a>()
<div class="description">
Retourne une épaisseur de ligne pour la légende.
</div>
<div class="description-bottom"><a href="Legendable.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getLegendLineColor"></a><span class="access">public</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Legendable.html#method.getLegendLineColor">getLegendLineColor</a>()
<div class="description">
Retourne une couleur de ligne pour la légende.
</div>
<div class="description-bottom"><a href="Legendable.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getLegendBackground"></a><span class="access">public</span> <span class="type">mixed</span> <a href="Legendable.html#method.getLegendBackground">getLegendBackground</a>()
<div class="description">
Retourne une couleur de fond pour la légende.
</div>
<div class="description-bottom"><a href="Legendable.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getLegendMark"></a><span class="access">public</span> <a href="Mark.html"><span class="type">Mark</span></a> <a href="Legendable.html#method.getLegendMark">getLegendMark</a>()
<div class="description">
Retourne l'objet qui gère les marques affichées sur les éléments représentatifs de la classe qui implémente cette interface.
</div>
<div class="description-bottom"><a href="Legendable.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/TTFFont.html
New file
0,0 → 1,58
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class TTFFont</h2><div class="extends"><ul>
<li><a href="FileFont.html">FileFont</a></li>
<ul><li>TTFFont</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="TTFFont.html">TTFFont</a> permet de manipuler des polices TrueType.
Quelques polices sont disponibles dans le répertoire <span style="font-weight: bold">font/</span> de Artichow.
Si vous connaissez d'autres polices intéressantes et dans le domaine public, n'hésitez pas à le signaler à <span style="text-decoration: underline">vincent</span> sur <span style="text-decoration: underline">artichow point org</span>.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties"><li>
<span class="access">public</span> <span class="type">int</span> <a href="TTFFont.html#property.size"><span class="argument">$size</span></a>
</li></ul><ul class="methods"><li>
<span class="access">public</span> <a href="TTFFont.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$font</span>, <span class="type">int</span> <span class="argument">$size</span>)
</li></ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.size"></a><span class="access">public</span> <span class="type">int</span> <a href="TTFFont.html#property.size"><span class="argument">$size</span></a><div class="description">
La taille de la police en pixels.
</div>
<div class="description-bottom"><a href="TTFFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="TTFFont.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$font</span>, <span class="type">int</span> <span class="argument">$size</span>)
<div class="description">
Construit la police $font de taille $size pixels.
La chaîne $font peut être soit le chemin vers un fichier de police TrueType, soit juste le nom de ce fichier. Dans ce dernier cas, le fichier de police sera recherché dans le dossier <span style="font-weight: bold">font/</span> du répertoire d'Artichow qui contient les quelques polices disponible de base.
</div>
<div class="description-bottom"><a href="TTFFont.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Drawer.html
New file
0,0 → 1,425
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Driver</h2><div class="description">
<p>
La classe <a href="Driver.html">Driver</a> est une couche d'abstraction à GD et permet de dessiner toutes sortes de formes géométriques sur une <a href="Image.html">Image</a>.
</p>
<p>
Sur une image, l'axe des abscisses rejoint l'axe des ordonnées sur le coin haut-gauche. Le coin haut-gauche de l'image a donc pour coordonnées (0, 0) et le coin bas-droite (largeur, hauteur). Par exemple, sur une image de largeur 100 et de hauteur 50, un point à 50 sur l'axe des abscisses et 25 sur l'axe des ordonnées sera au centre de l'image.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <span class="type">resource</span> <a href="Driver.html#property.resource"><span class="argument">$resource</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Driver.html#property.imageWidth"><span class="argument">$imageWidth</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Driver.html#property.imageHeight"><span class="argument">$imageHeight</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Driver.html#property.antiAliasing"><span class="argument">$antiAliasing</span></a> := <span class="default">FALSE</span>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Driver.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.init">init</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.initFromFile">initFromFile</a>(<a href="FileImage.html"><span class="type">FileImage</span></a> <span class="argument">$fileImage</span>, <span class="type">string</span> <span class="argument">$file</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setImageSize">setImageSize</a>(<span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setPosition">setPosition</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.movePosition">movePosition</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setAbsPosition">setAbsPosition</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setSize">setSize</a>(<span class="type">float</span> <span class="argument">$w</span>, <span class="type">float</span> <span class="argument">$h</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setAbsSize">setAbsSize</a>(<span class="type">int</span> <span class="argument">$w</span>, <span class="type">int</span> <span class="argument">$h</span>)
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Driver.html#method.getSize">getSize</a>()
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Driver.html#method.getColor">getColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.send">send</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.get">get</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setAntiAliasing">setAntiAliasing</a>(<span class="type">bool</span> <span class="argument">$bool</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.copyImage">copyImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.copyResizeImage">copyResizeImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$d1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$d2</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$s1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$s2</span>, <span class="type">bool</span> <span class="argument">$resampled</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.string">string</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>, <span class="type">int</span> <span class="argument">$width</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.point">point</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.line">line</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Line.html"><span class="type">Line</span></a> <span class="argument">$line</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.arc">arc</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>, <span class="type">float</span> <span class="argument">$from</span>, <span class="type">float</span> <span class="argument">$to</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.filledArc">filledArc</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>, <span class="type">float</span> <span class="argument">$from</span>, <span class="type">float</span> <span class="argument">$to</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.ellipse">ellipse</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.filledEllipse">filledEllipse</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.rectangle">rectangle</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.filledRectangle">filledRectangle</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.polygon">polygon</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.filledPolygon">filledPolygon</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.resource"></a><span class="access">public</span> <span class="type">resource</span> <a href="Driver.html#property.resource"><span class="argument">$resource</span></a><div class="description">
La ressource GD utilisée par le pilote.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.imageWidth"></a><span class="access">public</span> <span class="type">int</span> <a href="Driver.html#property.imageWidth"><span class="argument">$imageWidth</span></a><div class="description">
La largeur de l'image gérée par le pilote.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.imageHeight"></a><span class="access">public</span> <span class="type">int</span> <a href="Driver.html#property.imageHeight"><span class="argument">$imageHeight</span></a><div class="description">
La hauteur de l'image gérée par le pilote.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.antiAliasing"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Driver.html#property.antiAliasing"><span class="argument">$antiAliasing</span></a> := <span class="default">FALSE</span><div class="description">
Doit-on utiliser l'anti-aliasing sur ce dessin ?
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Driver.html#method.__construct">__construct</a>()
<div class="description">
Construit le pilote.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.init"></a><span class="access">public</span> <a href="Driver.html#method.init">init</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1.0</li></ul>
<div class="description">
Crée la ressource GD dont a besoin le Driver pour dessiner l'Image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.initFromFile"></a><span class="access">public</span> <a href="Driver.html#method.initFromFile">initFromFile</a>(<a href="FileImage.html"><span class="type">FileImage</span></a> <span class="argument">$fileImage</span>, <span class="type">string</span> <span class="argument">$file</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1.0</li></ul>
<div class="description">
Crée la ressource GD dont a besoin le Driver à partir d'un fichier déjà existant dont le nom est $file.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setImageSize"></a><span class="access">public</span> <a href="Driver.html#method.setImageSize">setImageSize</a>(<span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
<div class="description">
Change la taille de l'image gérée par le pilote pour la largeur $width et la hauteur $height.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setPosition"></a><span class="access">public</span> <a href="Driver.html#method.setPosition">setPosition</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
<div class="description">
Informe le pilote de la position de la sous-image sur l'image.
Les positions X et Y sont données via les paramètres $x et $y, qui représentent une fraction de la taille de l'image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.movePosition"></a><span class="access">public</span> <a href="Driver.html#method.movePosition">movePosition</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
<div class="description">
Demande au pilote de déplacer la position de la sous-image sur l'image.
$x et $y représentent respectivement les déplacements latéral et vertical de la position en pixels.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAbsPosition"></a><span class="access">public</span> <a href="Driver.html#method.setAbsPosition">setAbsPosition</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
<div class="description">
Informe le pilote de la position de la sous-image sur l'image.
Les positions X et Y sont données via les paramètres $x et $y, dont l'unité est le pixel.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSize"></a><span class="access">public</span> <a href="Driver.html#method.setSize">setSize</a>(<span class="type">float</span> <span class="argument">$w</span>, <span class="type">float</span> <span class="argument">$h</span>)
<div class="description">
Informe le pilote de la taille de la sous-image sur l'image.
Les largeur et hauteur de la sous-image sont données via les paramètres $w et $h, qui représentent une fraction de la taille de l'image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAbsSize"></a><span class="access">public</span> <a href="Driver.html#method.setAbsSize">setAbsSize</a>(<span class="type">int</span> <span class="argument">$w</span>, <span class="type">int</span> <span class="argument">$h</span>)
<div class="description">
Informe le pilote de la taille de la sous-image sur l'image.
Les largeur et hauteur de la sous-image sont données via les paramètres $w et $h, dont l'unité est le pixel.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getSize"></a><span class="access">public</span> <span class="type">array</span> <a href="Driver.html#method.getSize">getSize</a>()
<div class="description">
Retourne la taille de la sous-image en pixels.
Les valeurs sont retournées sous la forme d'un tableau, de la forme array(largeur, hauteur).
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getColor"></a><span class="access">public</span> <span class="type">int</span> <a href="Driver.html#method.getColor">getColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Retourne la couleur sous la forme d'un entier numérique, utilisable ensuite avec les fonctions GD de PHP.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.send"></a><span class="access">public</span> <a href="Driver.html#method.send">send</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
<div class="description">
Construit l'image passée en paramètre et l'envoie sur la sortie standard accompagnée des en-têtes HTTP correspondants.
A aucun moment vous ne devriez avoir besoin d'appeler vous-même cette méthode. Pour générez les images, utilisez <a href="Graph.html#method.draw">Graph::draw()</a>.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.get"></a><span class="access">public</span> <a href="Driver.html#method.get">get</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1.0</li></ul>
<div class="description">
Construit l'image passée en paramètre et la renvoie sous forme de données binaires. Vous pouvez donc la stocker dans une variable si vous voulez faire des manipulations spécifiques.
A aucun moment vous ne devriez avoir besoin d'appeler vous-même cette méthode. Pour générez les images, utilisez <a href="Graph.html#method.draw">Graph::draw()</a>.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAntiAliasing"></a><span class="access">public</span> <a href="Driver.html#method.setAntiAliasing">setAntiAliasing</a>(<span class="type">bool</span> <span class="argument">$bool</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Active ou désactive l'anti-aliasing lors du dessin.
L'anti-aliasing permet d'avoir des graphiques plus propres mais demande plus de ressources.
L'anti-aliasing n'est pas activé par défaut.
<div class="see">
Voir aussi :
<ul><li><a href="Image.html#method.setAntiAliasing">Image::setAntiAliasing()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.copyImage"></a><span class="access">public</span> <a href="Driver.html#method.copyImage">copyImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
<div class="description">
Copie l'image $image vers la sous-image courante.
L'image sera copiée sur la sous-image du point $p1 (coin haut-gauche) ou point $p2 (coin bas-droit).
Les coordonnées de $p1 et $p2 doivent être relatives à celles de la sous-image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.copyResizeImage"></a><span class="access">public</span> <a href="Driver.html#method.copyResizeImage">copyResizeImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$d1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$d2</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$s1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$s2</span>, <span class="type">bool</span> <span class="argument">$resampled</span>)
<div class="description">
Copie l'image $image vers l'image courante.
L'image $image sera copiée des points $s1 (coin haut-gauche) et $s2 (coin bas-droit) vers les points $d1 (coin haut-gauche) et $d2 (coin bas-droit) de l'image courante.
Si $resampled est placé à TRUE, l'image sera rééchantillonée.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.string"></a><span class="access">public</span> <a href="Driver.html#method.string">string</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>, <span class="type">int</span> <span class="argument">$width</span> := <span class="default">NULL</span>)
<div class="description">
Dessine la chaîne de caractères $text à partir du point $point.
Les coordonnées de $point doivent être relatives à celles de la sous-image.
Le paramètre $width permet de spécifier la largeur maximale en pixels de la boîte de texte.
<div class="see">
Voir aussi :
<ul>
<li><a href="Driver.html#method.getTextHeight">Driver::getTextHeight()</a></li>
<li><a href="Driver.html#method.getTextWidth">Driver::getTextWidth()</a></li>
</ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.point"></a><span class="access">public</span> <a href="Driver.html#method.point">point</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
<div class="description">
Dessine un pixel de couleur $color au point $point.
Les coordonnées de $point doivent être relatives à celles de la sous-image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.line"></a><span class="access">public</span> <a href="Driver.html#method.line">line</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Line.html"><span class="type">Line</span></a> <span class="argument">$line</span>)
<div class="description">
Dessine la ligne $line de couleur $color.
Les coordonnées de la ligne doivent être relatives à celles de la sous-image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.arc"></a><span class="access">public</span> <a href="Driver.html#method.arc">arc</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>, <span class="type">float</span> <span class="argument">$from</span>, <span class="type">float</span> <span class="argument">$to</span>)
<div class="description">
Dessine un arc d'ellipse de couleur $color dont les deux extrémités sont reliées au centre de l'ellipse.
L'ellipse a pour centre $center et est de largeur et hauteur respectives $width et $height.
L'angle de départ pour l'arc est $from et l'angle d'arrivée $to.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.filledArc">Driver::filledArc()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.filledArc"></a><span class="access">public</span> <a href="Driver.html#method.filledArc">filledArc</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>, <span class="type">float</span> <span class="argument">$from</span>, <span class="type">float</span> <span class="argument">$to</span>)
<div class="description">
Dessine un arc d'ellipse dont les deux extrémités sont reliées au centre de l'ellipse et le remplit avec la couleur ou le dégradé $background.
L'ellipse a pour centre $center et est de largeur et hauteur respectives $width et $height.
L'angle de départ pour l'arc est $from et l'angle d'arrivée $to.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.arc">Driver::arc()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.ellipse"></a><span class="access">public</span> <a href="Driver.html#method.ellipse">ellipse</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
<div class="description">
Dessine une ellipse de couleur $color, ayant pour centre $center et de largeur et hauteur respectives $width et $height.
Les coordonnées de l'ellipse doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.filledEllipse">Driver::filledEllipse()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.filledEllipse"></a><span class="access">public</span> <a href="Driver.html#method.filledEllipse">filledEllipse</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
<div class="description">
Dessine et remplit une ellipse avec la couleur ou le dégradé $background. Cette ellipse a pour centre $center et est de largeur et hauteur respectives $width et $height.
Les coordonnées de l'ellipse doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.ellipse">Driver::ellipse()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.rectangle"></a><span class="access">public</span> <a href="Driver.html#method.rectangle">rectangle</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
<div class="description">
Dessine un rectangle de couleur $color des points $p1 à $p2 (le segment qui relie ces points représente la diagonale du rectangle).
Les coordonnées du rectangle doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.filledRectangle">Driver::filledRectangle()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.filledRectangle"></a><span class="access">public</span> <a href="Driver.html#method.filledRectangle">filledRectangle</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
<div class="description">
Dessine et remplit un rectangle avec la couleur ou le dégradé $background des points $p1 à $p2 (le segment qui relie ces points représente la diagonale du rectangle).
Les coordonnées du rectangle doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.rectangle">Driver::rectangle()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.polygon"></a><span class="access">public</span> <a href="Driver.html#method.polygon">polygon</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
<div class="description">
Dessine le polygone $polygon de couleur $color.
Les coordonnées de chaque point du polygone doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.filledPolygon">Driver::filledPolygon()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.filledPolygon"></a><span class="access">public</span> <a href="Driver.html#method.filledPolygon">filledPolygon</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
<div class="description">
Dessine et remplit le polygone $polygon avec la couleur ou le dégradé $background.
Les coordonnées de chaque point du polygone doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.polygon">Driver::polygon()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Side.html
New file
0,0 → 1,94
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Side</h2><div class="description">
<p>
La classe <a href="Side.html">Side</a> est un objet qui fournit des méthodes pour gérer des situations où il est besoin de valoriser les côtés gauche, droit, haut et bas avec des entiers.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Side.html#property.left"><span class="argument">$left</span></a> := <span class="default">0</span>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Side.html#property.right"><span class="argument">$right</span></a> := <span class="default">0</span>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Side.html#property.top"><span class="argument">$top</span></a> := <span class="default">0</span>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Side.html#property.bottom"><span class="argument">$bottom</span></a> := <span class="default">0</span>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Side.html#method.__construct">__construct</a>(<span class="type">mixed</span> <span class="argument">$left</span>, <span class="type">mixed</span> <span class="argument">$right</span>, <span class="type">mixed</span> <span class="argument">$top</span>, <span class="type">mixed</span> <span class="argument">$bottom</span>)
</li>
<li>
<span class="access">public</span> <a href="Side.html#method.set">set</a>(<span class="type">mixed</span> <span class="argument">$left</span>, <span class="type">mixed</span> <span class="argument">$right</span>, <span class="type">mixed</span> <span class="argument">$top</span>, <span class="type">mixed</span> <span class="argument">$bottom</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.left"></a><span class="access">public</span> <span class="type">int</span> <a href="Side.html#property.left"><span class="argument">$left</span></a> := <span class="default">0</span><div class="description">
Le côté gauche.
</div>
<div class="description-bottom"><a href="Side.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.right"></a><span class="access">public</span> <span class="type">int</span> <a href="Side.html#property.right"><span class="argument">$right</span></a> := <span class="default">0</span><div class="description">
Le côté droit.
</div>
<div class="description-bottom"><a href="Side.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.top"></a><span class="access">public</span> <span class="type">int</span> <a href="Side.html#property.top"><span class="argument">$top</span></a> := <span class="default">0</span><div class="description">
Le côté haut.
</div>
<div class="description-bottom"><a href="Side.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.bottom"></a><span class="access">public</span> <span class="type">int</span> <a href="Side.html#property.bottom"><span class="argument">$bottom</span></a> := <span class="default">0</span><div class="description">
Le côté bas.
</div>
<div class="description-bottom"><a href="Side.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Side.html#method.__construct">__construct</a>(<span class="type">mixed</span> <span class="argument">$left</span>, <span class="type">mixed</span> <span class="argument">$right</span>, <span class="type">mixed</span> <span class="argument">$top</span>, <span class="type">mixed</span> <span class="argument">$bottom</span>)
<div class="description">
Construit l'objet <a href="Side.html">Side</a> avec les valeurs $left, $right, $top et $bottom pour les côtés gauche, droit, haut et bas.
</div>
<div class="description-bottom"><a href="Side.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.set"></a><span class="access">public</span> <a href="Side.html#method.set">set</a>(<span class="type">mixed</span> <span class="argument">$left</span>, <span class="type">mixed</span> <span class="argument">$right</span>, <span class="type">mixed</span> <span class="argument">$top</span>, <span class="type">mixed</span> <span class="argument">$bottom</span>)
<div class="description">
Change les valeurs associées aux côtés gauche, droit, haut et bas.
Laisser un paramètre à NULL permet d'éviter que la valeur du côté soit modifiée.
</div>
<div class="description-bottom"><a href="Side.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Text.html
New file
0,0 → 1,186
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Text</h2><div class="description">
<p>
La classe <a href="Text.html">Text</a> permet de manipuler du texte de manière uniforme sur Artichow.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties"><li>
<span class="access">public</span> <a href="Border.html"><span class="type">Border</span></a> <a href="Text.html#property.border"><span class="argument">$border</span></a>
</li></ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Text.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$text</span>, <a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span> := <span class="default">new Font(Text::FONT_2)</span>, <a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$angle</span> := <span class="default">0</span>)
</li>
<li>
<span class="access">public</span> <span class="type">string</span> <a href="Text.html#method.getText">getText</a>()
</li>
<li>
<span class="access">public</span> <a href="Text.html#method.setText">setText</a>(<span class="type">string</span> <span class="argument">$text</span>)
</li>
<li>
<span class="access">public</span> <a href="Font.html"><span class="type">Font</span></a> <a href="Text.html#method.getFont">getFont</a>()
</li>
<li>
<span class="access">public</span> <a href="Text.html#method.setFont">setFont</a>(<a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Text.html#method.getAngle">getAngle</a>()
</li>
<li>
<span class="access">public</span> <a href="Text.html#method.setAngle">setAngle</a>(<span class="type">int</span> <span class="argument">$angle</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Text.html#method.getColor">getColor</a>()
</li>
<li>
<span class="access">public</span> <a href="Text.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <span class="type">mixed</span> <a href="Text.html#method.getBackground">getBackground</a>()
</li>
<li>
<span class="access">public</span> <a href="Text.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Text.html#method.setBackgroundGradient">setBackgroundGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Text.html#method.getPadding">getPadding</a>()
</li>
<li>
<span class="access">public</span> <a href="Text.html#method.setPadding">setPadding</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>, <span class="type">int</span> <span class="argument">$top</span>, <span class="type">int</span> <span class="argument">$bottom</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.border"></a><span class="access">public</span> <a href="Border.html"><span class="type">Border</span></a> <a href="Text.html#property.border"><span class="argument">$border</span></a><div class="description">
La bordure qui entoure le texte.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Text.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$text</span>, <a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span> := <span class="default">new Font(Text::FONT_2)</span>, <a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$angle</span> := <span class="default">0</span>)
<div class="description">
Créé un nouveau pavé de texte avec pour texte $text. $font représente la police utilisée pour le texte tandis que $color représente sa couleur.
L'angle est définit par le paramètre $angle, qui peut prendre les valeurs de 0 et 90°.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getText"></a><span class="access">public</span> <span class="type">string</span> <a href="Text.html#method.getText">getText</a>()
<div class="description">
Retourne le texte de la classe.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setText"></a><span class="access">public</span> <a href="Text.html#method.setText">setText</a>(<span class="type">string</span> <span class="argument">$text</span>)
<div class="description">
Change le texte associé à l'objet pour $text.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getFont"></a><span class="access">public</span> <a href="Font.html"><span class="type">Font</span></a> <a href="Text.html#method.getFont">getFont</a>()
<div class="description">
Retourne la police utilisée pour le texte.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setFont"></a><span class="access">public</span> <a href="Text.html#method.setFont">setFont</a>(<a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span>)
<div class="description">
Change la police utilisée pour le texte.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getAngle"></a><span class="access">public</span> <span class="type">int</span> <a href="Text.html#method.getAngle">getAngle</a>()
<div class="description">
Retourne l'angle du texte.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAngle"></a><span class="access">public</span> <a href="Text.html#method.setAngle">setAngle</a>(<span class="type">int</span> <span class="argument">$angle</span>)
<div class="description">
Change l'angle du texte. Les valeurs possibles sont 0 ou 90°.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getColor"></a><span class="access">public</span> <span class="type">int</span> <a href="Text.html#method.getColor">getColor</a>()
<div class="description">
Retourne la couleur du texte.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColor"></a><span class="access">public</span> <a href="Text.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur du texte.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getBackground"></a><span class="access">public</span> <span class="type">mixed</span> <a href="Text.html#method.getBackground">getBackground</a>()
<div class="description">
Retourne le fond du texte. Si aucun fond n'a été spécifié, cette méthode retourne NULL.
Dans le cas contraire, elle retourne un objet de la classe Color pour les couleurs, soit une instance de Gradient pour les dégradés.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundColor"></a><span class="access">public</span> <a href="Text.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de fond du texte.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundGradient"></a><span class="access">public</span> <a href="Text.html#method.setBackgroundGradient">setBackgroundGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
<div class="description">
Change le dégradé de fond du texte.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getPadding"></a><span class="access">public</span> <span class="type">array</span> <a href="Text.html#method.getPadding">getPadding</a>()
<div class="description">
Retourne la valeur de l'espace qui entoure le texte par rapport à sa bordure. Cette méthode retourne un tableau de quatre valeurs, qui correspondent à l'espace de gauche, droite, haut et bas.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setPadding"></a><span class="access">public</span> <a href="Text.html#method.setPadding">setPadding</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>, <span class="type">int</span> <span class="argument">$top</span>, <span class="type">int</span> <span class="argument">$bottom</span>)
<div class="description">
Change la valeur de l'espace qui entoure le texte par rapport à sa bordure.
</div>
<div class="description-bottom"><a href="Text.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/style.css
New file
0,0 → 1,383
body {
font-family: "Trebuchet MS", Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif;
font-size: 0.75em;
margin: 0px;
padding: 0px;
background-color: #c2d2c4;
background-image: url("image/fond.png");
background-repeat: repeat-x;
padding-top: 20px;
}
 
 
a {
color: #000055;
text-decoration: none;
}
 
a:hover {
color: #295F37;
text-decoration: underline;
}
 
p {
padding-left: 1em;
padding-right: 1em;
text-align: justify;
}
 
p:first-letter {
float: left;
font-size: 160%;
font-weight: bold;
color: #646464;
background-color: white;
margin-top: -7px;
margin-right: 3px;
padding-right: 0px;
padding-left: 2px;
margin-bottom: -10px;
}
 
pre {
margin: 0px;
padding: 0px;
font-size: 1.25em;
}
 
span.php4 {
color: red;
font-weight: bold;
}
 
.borderhg {
border-top: 1px solid black;
border-left: 1px solid black;
}
 
.borderd {
border-right: 1px solid black;
}
 
.borderg {
border-left: 1px solid black;
}
 
.borderh {
border-top: 1px solid black;
}
 
.borderb {
border-bottom: 1px solid black;
}
 
 
table#page {
width: 900px;
margin: auto;
text-align: left;
}
 
table#page td {
vertical-align: top;
}
 
table#page div.logo {
text-align: center;
}
 
table#page td table.features td {
vertical-align: middle;
}
 
table#menuhaut, table#menubas {
width: 200px;
background-color: white;
}
 
table#menuhaut td.cornerhg {
width: 30px;
height: 30px;
background: transparent url("image/coin-hg.gif") no-repeat;
}
table#menubas td.cornerbg {
width: 30px;
height: 30px;
background: url("image/coin-bg.gif") no-repeat;
}
 
 
div#menu {
border-left: 1px solid black;
background-color: white;
}
 
 
div#menu ul.ulmenu {
padding: 0px;
margin: 0px;
background-color: #dddddd;
}
 
div#menu ul.ulmenu li {
margin: 0px;
list-style-type: none;
}
 
div#menu ul.ulmenu a {
display: block;
text-decoration: none;
padding-left: 1em;
color: black;
width: 100%;
border-top: 1px solid black;
 
}
 
div#menu ul.ulmenu a:hover {
color: #dddddd;
background-color: #a43030;
display: block;
}
 
table#contenu {
width: 100%;
color: #2d2d2d;
background-color: white;
}
 
table#contenu td.cornerhd, table#contenu td.cornerhg, table#contenu td.cornerbd, table#contenu td.cornerbg {
width: 30px;
height: 30px;
}
 
table#contenu td.cornerhd {
background: transparent url("image/coin-hd.gif") no-repeat;
}
 
table#contenu td.cornerbd {
background: url("image/coin-bd.gif") no-repeat;
}
 
table#contenu td.cornerbg {
background: url("image/coin-bg.gif") no-repeat;
}
 
table#contenu table {
width: 95%;
margin: auto;
}
 
table#contenu h1 {
text-align: center;
margin: auto;
width: 100%;
color: #a43030;
}
 
table#contenu h2:after {
border: 0px;
background-color: transparent;
display: block;
margin-left: -1px;
padding-top: 31px;
width: 97%;
line-height: 1em;
margin-bottom: -25px;
text-align: left;
background: transparent url("image/back-rayures.png") repeat-x;
content: "";
 
}
 
table#contenu h4 {
margin-top: 0.3em;
margin-left: 1em;
margin-bottom: 0.5em;
font-size: 1.25em;
}
 
table#contenu h5 {
margin-top: 0.3em;
margin-left: 1em;
margin-bottom: 0.5em;
font-size: 1.0em;
}
 
table#contenu pre {
margin-left: 1em;
}
 
table#contenu ul.features li {
list-style-type: armenian;
margin-left: 3em;
}
 
table#contenu div.graph {
padding-top: 8px;
text-align: center;
}
 
table#contenu div.graph img {
border: 0px;
}
 
table#contenu div.image {
text-align: center;
margin-top: 2em;
}
 
table#contenu span.type {
color: #0000FF;
}
 
table#contenu span.default {
color: #A000A0;
}
 
table#contenu span.interface {
font-weight: bold;
}
 
table#contenu span.argument {
color: #880000;
}
 
table#contenu span.access {
font-weight: bold;
color: #3B3F3C;
 
}
 
table#contenu div.description {
margin-right: 3em;
margin-left: 2em;
border: 1px solid #A7BFAD;
padding: 4px;
}
 
table#contenu ul.news li {
list-style-type: none;
}
 
table#contenu ul.news li ul li {
list-style-type: square;
margin-left: 20px;
}
 
table#contenu div.description ul li {
list-style-type: circle;
font-size: 95%;
}
 
table#contenu div.description div.see {
margin-right: 1em;
margin-left: 1em;
background-color: #f0f0f0;
padding: 3px;
}
 
table#contenu div.description div.see ul li {
list-style-type: circle;
margin-bottom: 0em;
margin-top: 0em;
padding-bottom: 0em;
padding-top: 0em;
}
 
table#contenu div.inherit {
border-bottom: 1px solid #a43030;
margin-right: 3em;
margin-left: 2em;
padding: 4px;
}
 
 
table#contenu ul.doc li.method {
}
 
table#contenu ul.doc li.property {
}
 
table#contenu ul.doc li {
margin-bottom: 0.5em;
padding: 0.3em;
}
 
table#contenu ul {
margin-left: 1.5em;
padding-left: 0px;
padding-right: 1em;
}
 
table#contenu ul li {
list-style-type: square;
margin-left: 1em;
}
 
table#contenu ul.constants li, table#contenu ul.methods li, table#contenu ul.properties li,
table#contenu ul li.constant, table#contenu ul li.method, table#contenu ul li.property
{
list-style-type: none;
margin-left: 0px;
}
 
table#contenu ul.links li {
}
 
table#contenu a.easy {
color: red;
}
 
div.release {
background-color: #eeeeee;
padding-left: 20px;
}
 
div#imagemenu {
background-image: url("mini.php");
height: 100px;
width: 150px;
margin-left: 25px;
margin-top: 30px;
border: 0px;
}
 
td#textebas {
text-align: center;
}
table#bas {
float:left;
width: 100%;
background-color: white;
margin-top: 10px;
}
 
table#bas td.cornerhd, table#bas td.cornerhg, table#bas td.cornerbd, table#bas td.cornerbg {
width: 30px;
height: 30px;
}
 
table#bas td.cornerhd {
background: url("image/coin-hd-transparent.gif") no-repeat;
}
 
table#bas td.cornerhg {
background: url("image/coin-hg-transparent.gif") no-repeat;
}
 
table#bas td.cornerbd {
background: url("image/coin-bd.gif") no-repeat;
}
 
table#bas td.cornerbg {
background: url("image/coin-bg.gif") no-repeat;
}
 
table#contenu ul.demo li {
list-style-type : circle;
}
/tags/v1.0-Homere/bibliotheque/artichow/doc/Grid.html
New file
0,0 → 1,157
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Grid</h2><div class="description">
<p>
La classe <a href="Grid.html">Grid</a> permet de manipuler des grilles de fond sur les <a href="Plot.html">Plot</a> ou <a href="PlotGroup.html">groupes de Plot</a>.
Une grille facilite la lecture des données pour l'utilisateur.
Un exemple de grille est montré ci-dessous.
</p>
<div class="image">
<img src="image/grid.png">
</div>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="methods">
<li>
<span class="access">public</span> <a href="Grid.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="Grid.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="Grid.html#method.hideHorizontal">hideHorizontal</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="Grid.html#method.hideVertical">hideVertical</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="Grid.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Grid.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Grid.html#method.setType">setType</a>(<span class="type">int</span> <span class="argument">$type</span>)
</li>
<li>
<span class="access">public</span> <a href="Grid.html#method.setInterval">setInterval</a>(<span class="type">int</span> <span class="argument">$hInterval</span>, <span class="type">int</span> <span class="argument">$vInterval</span>)
</li>
<li>
<span class="access">public</span> <a href="Grid.html#method.setSpace">setSpace</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>, <span class="type">int</span> <span class="argument">$top</span>, <span class="type">int</span> <span class="argument">$bottom</span>)
</li>
<li>
<span class="access">public</span> <a href="Grid.html#method.setGrid">setGrid</a>(<span class="type">array</span> <span class="argument">$xgrid</span>, <span class="type">array</span> <span class="argument">$ygrid</span>)
</li>
<li>
<span class="access">public</span> <a href="Grid.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <span class="type">int</span> <span class="argument">$x1</span>, <span class="type">int</span> <span class="argument">$y1</span>, <span class="type">int</span> <span class="argument">$x2</span>, <span class="type">int</span> <span class="argument">$y2</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Grid.html#method.__construct">__construct</a>()
<div class="description">
Construit et initialise une grille.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hide"></a><span class="access">public</span> <a href="Grid.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
<div class="description">
Cache ou affiche la grille sur le composant.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hideHorizontal"></a><span class="access">public</span> <a href="Grid.html#method.hideHorizontal">hideHorizontal</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
<div class="description">
Cache ou affiche les lignes horizontales de la grille sur le composant.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hideVertical"></a><span class="access">public</span> <a href="Grid.html#method.hideVertical">hideVertical</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
<div class="description">
Cache ou affiche les lignes verticales de la grille sur le composant.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColor"></a><span class="access">public</span> <a href="Grid.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de la grille pour la couleur $color.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundColor"></a><span class="access">public</span> <a href="Grid.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de fond de la grille pour la couleur $color.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setType"></a><span class="access">public</span> <a href="Grid.html#method.setType">setType</a>(<span class="type">int</span> <span class="argument">$type</span>)
<div class="description">
Change le type de ligne à utiliser sur la grille. $type peut être <a href="Line.html#constant.SOLID">Line::SOLID</a> pour une ligne continue, <a href="Line.html#constant.DOTTED">Line::DOTTED</a> pour une ligne pointillée ou encore <a href="Line.html#constant.DASHED">Line::DASHED</a>.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setInterval"></a><span class="access">public</span> <a href="Grid.html#method.setInterval">setInterval</a>(<span class="type">int</span> <span class="argument">$hInterval</span>, <span class="type">int</span> <span class="argument">$vInterval</span>)
<div class="description">
Change l'interval d'affichage des lignes horizontales de la grille avec $hInterval et verticales avec $vInterval.
Par défaut, cet interval est à 1 et toutes les lignes sont affichées.
Si vous choisissez un interval de 2 par exemple, une ligne sur deux sera affichée sur la grille.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSpace"></a><span class="access">public</span> <a href="Grid.html#method.setSpace">setSpace</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>, <span class="type">int</span> <span class="argument">$top</span>, <span class="type">int</span> <span class="argument">$bottom</span>)
<div class="description">
Change l'espace interne de la grille.
Les valeurs $left, $right, $top et $bottom représentent respectivement les nouvelles valeurs pour l'espace gauche, droit, haut et bas de la grille.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setGrid"></a><span class="access">public</span> <a href="Grid.html#method.setGrid">setGrid</a>(<span class="type">array</span> <span class="argument">$xgrid</span>, <span class="type">array</span> <span class="argument">$ygrid</span>)
<div class="description">
Précise la position sur la grille des lignes horizontales avec $ygrid et verticales avec $xgrid.
Ces deux paramètres sont des tableaux qui contiennent des entiers entre 0 et 1. Chaque valeur représente la position d'une ligne comme une fraction de la taille de la grille.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.draw"></a><span class="access">public</span> <a href="Grid.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <span class="type">int</span> <span class="argument">$x1</span>, <span class="type">int</span> <span class="argument">$y1</span>, <span class="type">int</span> <span class="argument">$x2</span>, <span class="type">int</span> <span class="argument">$y2</span>)
<div class="description">
Dessine la grille avec le pilote $driver.
La grille sera dessinée dans un rectangle dont la diagonale est le segment qui relie les points ($x1, $y1) et ($x2, $y2).
Les lignes dessinées auront été préalablement précisées avec <a href="Grid.html#method.setGrid">setGrid()</a>.
</div>
<div class="description-bottom"><a href="Grid.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Shadow.html
New file
0,0 → 1,234
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Shadow</h2><div class="description">
<p>
La classe <a href="Shadow.html">Shadow</a> permet de manipuler des ombres sur des rectangles.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.LEFT_TOP">LEFT_TOP</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.LEFT_BOTTOM">LEFT_BOTTOM</a> := <span class="default">2</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.RIGHT_TOP">RIGHT_TOP</a> := <span class="default">3</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.RIGHT_BOTTOM">RIGHT_BOTTOM</a> := <span class="default">4</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.IN">IN</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.OUT">OUT</a> := <span class="default">2</span>
</li>
</ul><ul class="properties">
<li>
<span class="access">protected</span> <span class="type">int</span> <a href="Shadow.html#property.size"><span class="argument">$size</span></a> := <span class="default">0</span>
</li>
<li>
<span class="access">protected</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Shadow.html#property.color"><span class="argument">$color</span></a> := <span class="default">new Color(100, 100, 100)</span>
</li>
<li>
<span class="access">protected</span> <span class="type">int</span> <a href="Shadow.html#property.position"><span class="argument">$position</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Shadow.html#property.hide"><span class="argument">$hide</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Shadow.html#property.smooth"><span class="argument">$smooth</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Shadow.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$position</span>)
</li>
<li>
<span class="access">public</span> <a href="Shadow.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
</li>
<li>
<span class="access">public</span> <a href="Shadow.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span>)
</li>
<li>
<span class="access">public</span> <a href="Shadow.html#method.setSize">setSize</a>(<span class="type">int</span> <span class="argument">$size</span>)
</li>
<li>
<span class="access">public</span> <a href="Shadow.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Shadow.html#method.setPosition">setPosition</a>(<span class="type">int</span> <span class="argument">$position</span>)
</li>
<li>
<span class="access">public</span> <a href="Shadow.html#method.smooth">smooth</a>(<span class="type">bool</span> <span class="argument">$smooth</span>)
</li>
<li>
<span class="access">public</span> <a href="Side.html"><span class="type">Side</span></a> <a href="Shadow.html#method.getSpace">getSpace</a>()
</li>
<li>
<span class="access">public</span> <a href="Shadow.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>, <span class="type">int</span> <span class="argument">$mode</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.LEFT_TOP"></a><span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.LEFT_TOP">LEFT_TOP</a> := <span class="default">1</span><div class="description">
Dessine l'ombre sur les côtés haut et gauche.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.LEFT_BOTTOM"></a><span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.LEFT_BOTTOM">LEFT_BOTTOM</a> := <span class="default">2</span><div class="description">
Dessine l'ombre sur les côtés bas et gauche.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.RIGHT_TOP"></a><span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.RIGHT_TOP">RIGHT_TOP</a> := <span class="default">3</span><div class="description">
Dessine l'ombre sur les côtés haut et droit.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.RIGHT_BOTTOM"></a><span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.RIGHT_BOTTOM">RIGHT_BOTTOM</a> := <span class="default">4</span><div class="description">
Dessine l'ombre sur les côtés bas et droit.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.IN"></a><span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.IN">IN</a> := <span class="default">1</span><div class="description">
Spécifie que l'ombre doit être dessinée à l'intérieur.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.OUT"></a><span class="access">const</span> <span class="type">int</span> <a href="Shadow.html#constant.OUT">OUT</a> := <span class="default">2</span><div class="description">
Spécifie que l'ombre doit être dessinée à l'extérieur.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.size"></a><span class="access">protected</span> <span class="type">int</span> <a href="Shadow.html#property.size"><span class="argument">$size</span></a> := <span class="default">0</span><div class="description">
Taille de l'ombre.
Cette valeur est par défaut à 0, ce qui signifie qu'aucune ombre n'est affichée.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.color"></a><span class="access">protected</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Shadow.html#property.color"><span class="argument">$color</span></a> := <span class="default">new Color(100, 100, 100)</span><div class="description">
Taille de l'ombre.
Cette valeur est par défaut à 0, ce qui signifie qu'aucune ombre n'est affichée.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.position"></a><span class="access">protected</span> <span class="type">int</span> <a href="Shadow.html#property.position"><span class="argument">$position</span></a><div class="description">
Détermine la position de l'ombre.
Les valeurs possible sont <a href="Shadow.html#constant.LEFT_TOP">Shadow::LEFT_TOP</a>, <a href="Shadow.html#constant.RIGHT_TOP">Shadow::RIGHT_TOP</a>, <a href="Shadow.html#constant.LEFT_BOTTOM">Shadow::LEFT_BOTTOM</a> ou <a href="Shadow.html#constant.RIGHT_BOTTOM">Shadow::RIGHT_BOTTOM</a>.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.hide"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Shadow.html#property.hide"><span class="argument">$hide</span></a><div class="description">
Détermine si l'ombre doit être cachée.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.smooth"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Shadow.html#property.smooth"><span class="argument">$smooth</span></a><div class="description">
Détermine si l'ombre doit être lissée ou non.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Shadow.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$position</span>)
<div class="description">
Déclare une ombre à la position $position.
$position peut prendre les valeurs <a href="Shadow.html#constant.LEFT_TOP">Shadow::LEFT_TOP</a>, <a href="Shadow.html#constant.RIGHT_TOP">Shadow::RIGHT_TOP</a>, <a href="Shadow.html#constant.LEFT_BOTTOM">Shadow::LEFT_BOTTOM</a> ou <a href="Shadow.html#constant.RIGHT_BOTTOM">Shadow::RIGHT_BOTTOM</a>.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hide"></a><span class="access">public</span> <a href="Shadow.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
<div class="description">
Détermine si l'ombre doit être cachée ou non.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.show"></a><span class="access">public</span> <a href="Shadow.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span>)
<div class="description">
Détermine si l'ombre doit être affichée ou non.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSize"></a><span class="access">public</span> <a href="Shadow.html#method.setSize">setSize</a>(<span class="type">int</span> <span class="argument">$size</span>)
<div class="description">
Change la taille de l'ombre pour $size.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColor"></a><span class="access">public</span> <a href="Shadow.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de l'ombre pour $color.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setPosition"></a><span class="access">public</span> <a href="Shadow.html#method.setPosition">setPosition</a>(<span class="type">int</span> <span class="argument">$position</span>)
<div class="description">
Change la position de l'ombre.
$position peut prendre les valeurs <a href="Shadow.html#constant.LEFT_TOP">Shadow::LEFT_TOP</a>, <a href="Shadow.html#constant.RIGHT_TOP">Shadow::RIGHT_TOP</a>, <a href="Shadow.html#constant.LEFT_BOTTOM">Shadow::LEFT_BOTTOM</a> ou <a href="Shadow.html#constant.RIGHT_BOTTOM">Shadow::RIGHT_BOTTOM</a>.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.smooth"></a><span class="access">public</span> <a href="Shadow.html#method.smooth">smooth</a>(<span class="type">bool</span> <span class="argument">$smooth</span>)
<div class="description">
Détermine si l'ombre doit être lissée ou non.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getSpace"></a><span class="access">public</span> <a href="Side.html"><span class="type">Side</span></a> <a href="Shadow.html#method.getSpace">getSpace</a>()
<div class="description">
Retourne l'espace pris par l'ombre à gauche, droit, en haut et en bas.
Les espaces sont retournés en pixels.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.draw"></a><span class="access">public</span> <a href="Shadow.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>, <span class="type">int</span> <span class="argument">$mode</span>)
<div class="description">
Dessine l'ombre avec le pilote $driver dans un rectangle dont la diagonale est le segment qui relie les points $p1 et $p2.
Le paramètre $mode détermine le mode d'affichage de l'ombre. Si <a href="Shadow.html#constant.OUT">Shadow::OUT</a> est spécifié, alors l'ombre sera dessinée en dehors du rectangle. Si <a href="Shadow.html#constant.IN">Shadow::IN</a> est spécifié, alors l'ombre sera dessinée à l'intérieur du rectangle.
</div>
<div class="description-bottom"><a href="Shadow.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Line.html
New file
0,0 → 1,279
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Line</h2><div class="extends"><ul>
<li><a href="Shape.html">Shape</a></li>
<ul><li>Line</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="Line.html">Line</a> permet de manipuler des lignes de manière uniforme sur Artichow. Une ligne est composée de deux Point.
</p>
</div><div class="inherit">
Les classes suivantes dérivent de Line :
<ul><li><a href="Vector.html">Vector</a></li></ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">protected</span> <a href="Point.html"><span class="type">Point</span></a> <a href="Line.html#property.p1"><span class="argument">$p1</span></a>
</li>
<li>
<span class="access">protected</span> <a href="Point.html"><span class="type">Point</span></a> <a href="Line.html#property.p2"><span class="argument">$p2</span></a>
</li>
<li>
<span class="access">private</span> <span class="type">float</span> <a href="Line.html#property.slope"><span class="argument">$slope</span></a>
</li>
<li>
<span class="access">private</span> <span class="type">float</span> <a href="Line.html#property.origin"><span class="argument">$origin</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Line.html#method.__construct">__construct</a>(<a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>, <span class="type">int</span> <span class="argument">$style</span> := <span class="default">Line::SOLID</span>, <span class="type">int</span> <span class="argument">$thickness</span> := <span class="default">1</span>)
</li>
<li>
<span class="access">public static</span> <a href="Line.html#method.build">build</a>(<span class="type">int</span> <span class="argument">$x1</span>, <span class="type">int</span> <span class="argument">$y1</span>, <span class="type">int</span> <span class="argument">$x2</span>, <span class="type">int</span> <span class="argument">$y2</span>)
</li>
<li>
<span class="access">public</span> <a href="Line.html#method.setX">setX</a>(<span class="type">int</span> <span class="argument">$x1</span>, <span class="type">int</span> <span class="argument">$x2</span>)
</li>
<li>
<span class="access">public</span> <a href="Line.html#method.setY">setY</a>(<span class="type">int</span> <span class="argument">$y1</span>, <span class="type">int</span> <span class="argument">$y2</span>)
</li>
<li>
<span class="access">public</span> <a href="Line.html#method.setLocation">setLocation</a>(<a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Line.html#method.getLocation">getLocation</a>()
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Line.html#method.getSize">getSize</a>()
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Line.html#method.getSlope">getSlope</a>()
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Line.html#method.getOrigin">getOrigin</a>()
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Line.html#method.getEquation">getEquation</a>()
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Line.html#method.getXFrom">getXFrom</a>(<span class="type">float</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Line.html#method.getYFrom">getYFrom</a>(<span class="type">float</span> <span class="argument">$x</span>)
</li>
<li>
<span class="access">public</span> <span class="type">bool</span> <a href="Line.html#method.isPoint">isPoint</a>()
</li>
<li>
<span class="access">public</span> <span class="type">bool</span> <a href="Line.html#method.isHorizontal">isHorizontal</a>()
</li>
<li>
<span class="access">public</span> <span class="type">bool</span> <a href="Line.html#method.isVertical">isVertical</a>()
</li>
<li>
<span class="access">public</span> <span class="type">bool</span> <a href="Line.html#method.isTopToBottom">isTopToBottom</a>(<a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
</li>
<li>
<span class="access">public</span> <span class="type">bool</span> <a href="Line.html#method.isLeftToRight">isLeftToRight</a>(<a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.p1"></a><span class="access">protected</span> <a href="Point.html"><span class="type">Point</span></a> <a href="Line.html#property.p1"><span class="argument">$p1</span></a><div class="description">
Le premier point de la ligne.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.p2"></a><span class="access">protected</span> <a href="Point.html"><span class="type">Point</span></a> <a href="Line.html#property.p2"><span class="argument">$p2</span></a><div class="description">
Le second point de la ligne.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.slope"></a><span class="access">private</span> <span class="type">float</span> <a href="Line.html#property.slope"><span class="argument">$slope</span></a><div class="description">
La pente (ou coefficient directeur) de la droite.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.origin"></a><span class="access">private</span> <span class="type">float</span> <a href="Line.html#property.origin"><span class="argument">$origin</span></a><div class="description">
La valeur de l'ordonnée à l'origine de la droite.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Line.html#method.__construct">__construct</a>(<a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>, <span class="type">int</span> <span class="argument">$style</span> := <span class="default">Line::SOLID</span>, <span class="type">int</span> <span class="argument">$thickness</span> := <span class="default">1</span>)
<div class="description">
Déclare une nouvelle ligne des points $p1 à $p2. La ligne est de style $style (<a href="Line.html#constant.SOLID">Line::SOLID</a> pour une ligne continue, <a href="Line.html#constant.DOTTED">Line::DOTTED</a> pour une ligne pointillée ou encore <a href="Line.html#constant.DASHED">Line::DASHED</a>) et d'épaisseur $thickness.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.build"></a><span class="access">public static</span> <a href="Line.html#method.build">build</a>(<span class="type">int</span> <span class="argument">$x1</span>, <span class="type">int</span> <span class="argument">$y1</span>, <span class="type">int</span> <span class="argument">$x2</span>, <span class="type">int</span> <span class="argument">$y2</span>)
<div class="description">
Construit une ligne à partir des coordonnées ($x1, $y1) et ($x2, $y2)
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setX"></a><span class="access">public</span> <a href="Line.html#method.setX">setX</a>(<span class="type">int</span> <span class="argument">$x1</span>, <span class="type">int</span> <span class="argument">$x2</span>)
<div class="description">
Change les coordonnées X des deux points de la ligne pour $x1 et $x2.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setY"></a><span class="access">public</span> <a href="Line.html#method.setY">setY</a>(<span class="type">int</span> <span class="argument">$y1</span>, <span class="type">int</span> <span class="argument">$y2</span>)
<div class="description">
Change les coordonnées Y des deux points de la ligne pour $y1 et $y2.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLocation"></a><span class="access">public</span> <a href="Line.html#method.setLocation">setLocation</a>(<a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
<div class="description">
Change l'emplacement de la ligne pour les points $p1 et $p2 passés en paramètre.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getLocation"></a><span class="access">public</span> <span class="type">array</span> <a href="Line.html#method.getLocation">getLocation</a>()
<div class="description">
Retourne la position de la ligne dans un tableau à deux valeurs.
<pre>
 
&lt;?php
$line = new Line(new Point(1, 2), new Point(3, 4));
list($p1, $p2) = $line-&gt;getLocation();
// $p1 == new Point(1, 2)
// $p2 == new Point(3, 4)
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getSize"></a><span class="access">public</span> <span class="type">float</span> <a href="Line.html#method.getSize">getSize</a>()
<div class="description">
Retourne la taille de la ligne en pixels.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getSlope"></a><span class="access">public</span> <span class="type">float</span> <a href="Line.html#method.getSlope">getSlope</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie la valeur de la pente de la ligne.
Si celle-ci est verticale, la pente vaudra NULL; si elle est horizontale, la pente vaudra 0.
La valeur est calculée uniquement lorsqu'elle est demandée.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getOrigin"></a><span class="access">public</span> <span class="type">float</span> <a href="Line.html#method.getOrigin">getOrigin</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie la valeur de l'ordonnée à l'origine.
Si la ligne est verticale, l'ordonnée à l'origine vaudra NULL.
La valeur est calculée uniquement lorsqu'elle est demandée.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getEquation"></a><span class="access">public</span> <span class="type">array</span> <a href="Line.html#method.getEquation">getEquation</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie un tableau contenant la pente et l'ordonnée à l'origine de la ligne.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getXFrom"></a><span class="access">public</span> <span class="type">float</span> <a href="Line.html#method.getXFrom">getXFrom</a>(<span class="type">float</span> <span class="argument">$y</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie la valeur de l'abscisse du point d'ordonnée $y situé sur la droite portant la ligne.
Si la ligne est horizontale et que $y est différent de l'ordonnée à l'origine, aucun point ne pourra être trouvé et la méthode renverra NULL.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getYFrom"></a><span class="access">public</span> <span class="type">float</span> <a href="Line.html#method.getYFrom">getYFrom</a>(<span class="type">float</span> <span class="argument">$x</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie la valeur de l'ordonnée du point d'abscisse $x situé sur la droite portant la ligne.
Si la ligne est verticale et qu'aucun point correspondant à $x ne peut être trouvé, la méthode renverra NULL.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.isPoint"></a><span class="access">public</span> <span class="type">bool</span> <a href="Line.html#method.isPoint">isPoint</a>()
<div class="description">
Retourne TRUE si la ligne peut être considérée comme un point, FALSE sinon.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.isHorizontal"></a><span class="access">public</span> <span class="type">bool</span> <a href="Line.html#method.isHorizontal">isHorizontal</a>()
<div class="description">
Retourne TRUE si la ligne est horizontale, FALSE sinon.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.isVertical"></a><span class="access">public</span> <span class="type">bool</span> <a href="Line.html#method.isVertical">isVertical</a>()
<div class="description">
Retourne TRUE si la ligne est verticale, FALSE sinon.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.isTopToBottom"></a><span class="access">public</span> <span class="type">bool</span> <a href="Line.html#method.isTopToBottom">isTopToBottom</a>(<a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie TRUE si la ligne remplit toute la hauteur du rectangle encadrant le polygone $polygon, FALSE sinon.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.isLeftToRight"></a><span class="access">public</span> <span class="type">bool</span> <a href="Line.html#method.isLeftToRight">isLeftToRight</a>(<a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie TRUE si la ligne remplit toute la largeur du rectangle encadrant le polygone $polygon, FALSE sinon.
</div>
<div class="description-bottom"><a href="Line.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/MathPlot.html
New file
0,0 → 1,124
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class MathPlot</h2><div class="extends"><ul>
<li><a href="Component.html">Component</a></li>
<ul><li>MathPlot</li></ul>
</ul></div><div class="description">
<p>
Cette classe permet de représenter simplement des fonctions f(x) sur un graphique.
L'archive de Artichow contient plusieurs exemples pour vous aider dans la conception de ces graphiques.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <a href="Grid.html"><span class="type">Grid</span></a> <a href="MathPlot.html#property.grid"><span class="argument">$grid</span></a>
</li>
<li>
<span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="MathPlot.html#property.xAxis"><span class="argument">$xAxis</span></a>
</li>
<li>
<span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="MathPlot.html#property.yAxis"><span class="argument">$yAxis</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="MathPlot.html#method.__construct">__construct</a>(<span class="type">float</span> <span class="argument">$xMin</span>, <span class="type">float</span> <span class="argument">$xMax</span>, <span class="type">float</span> <span class="argument">$yMax</span>, <span class="type">float</span> <span class="argument">$yMin</span>)
</li>
<li>
<span class="access">public</span> <a href="MathPlot.html#method.setInterval">setInterval</a>(<span class="type">int</span> <span class="argument">$interval</span>)
</li>
<li>
<span class="access">public</span> <a href="MathPlot.html#method.add">add</a>(<a href="MathFunction.html"><span class="type">MathFunction</span></a> <span class="argument">$function</span>, <span class="type">string</span> <span class="argument">$name</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$type</span> := <span class="default">Legend::LINE</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.grid"></a><span class="access">public</span> <a href="Grid.html"><span class="type">Grid</span></a> <a href="MathPlot.html#property.grid"><span class="argument">$grid</span></a><div class="description">
Représente la grille de fond du graphique.
</div>
<div class="description-bottom"><a href="MathPlot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.xAxis"></a><span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="MathPlot.html#property.xAxis"><span class="argument">$xAxis</span></a><div class="description">
Représente l'axe des abscisses.
</div>
<div class="description-bottom"><a href="MathPlot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.yAxis"></a><span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="MathPlot.html#property.yAxis"><span class="argument">$yAxis</span></a><div class="description">
Représente l'axe des ordonnées.
</div>
<div class="description-bottom"><a href="MathPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="MathPlot.html#method.__construct">__construct</a>(<span class="type">float</span> <span class="argument">$xMin</span>, <span class="type">float</span> <span class="argument">$xMax</span>, <span class="type">float</span> <span class="argument">$yMax</span>, <span class="type">float</span> <span class="argument">$yMin</span>)
<div class="description">
Construit le graphique.
L'axe des X va des valeurs $xMin à $xMax tandis que l'axe de Y va des valeurs $yMin à $yMax.
<pre>
 
&lt;?php
 
require_once "MathPlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(300, 300);
 
 
$plot = new <a href="MathPlot.html">MathPlot</a>(-3, 3, 3, -3);
$plot-&gt;<a href="MathPlot.html#method.setInterval">setInterval</a>(0.1);
 
// On dessine cos(x)
$function = new <a href="MathFunction.html">MathFunction</a>('cos');
$plot-&gt;<a href="MathPlot.html#method.add">add</a>($function);
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="MathPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setInterval"></a><span class="access">public</span> <a href="MathPlot.html#method.setInterval">setInterval</a>(<span class="type">int</span> <span class="argument">$interval</span>)
<div class="description">
Change l'interval sur lequel sont calculées les valeurs affichées sur le graphique.
Par défaut, cet interval est de 1, c'est-à-dire que Artichow calcule f(x) pour toutes les valeurs entières de x.
</div>
<div class="description-bottom"><a href="MathPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.add"></a><span class="access">public</span> <a href="MathPlot.html#method.add">add</a>(<a href="MathFunction.html"><span class="type">MathFunction</span></a> <span class="argument">$function</span>, <span class="type">string</span> <span class="argument">$name</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$type</span> := <span class="default">Legend::LINE</span>)
<div class="description">
Ajoute une fonction mathématique au graphique.
Sur la légende, la fonction aura pour nom $name et le type de légende utilisé sera $type (<a href="Legend.html#constant.LINE">Legend::LINE</a>, <a href="Legend.html#constant.BACKGROUND">Legend::BACKGROUND</a> ou encore <a href="Legend.html#constant.MARK">Legend::MARK</a>).
Si vous ne souhaitez pas associer de légende à cette fonction, laissez l'argument $name à NULL.
</div>
<div class="description-bottom"><a href="MathPlot.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Point.html
New file
0,0 → 1,134
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Point</h2><div class="extends"><ul>
<li><a href="Shape.html">Shape</a></li>
<ul><li>Point</li></ul>
</ul></div><div class="description">
<p>La classe <a href="Point.html">Point</a> permet de manipuler des points dans un espace de deux dimensions.</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Point.html#property.x"><span class="argument">$x</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Point.html#property.y"><span class="argument">$y</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Point.html#method.__construct">__construct</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Point.html#method.setX">setX</a>(<span class="type">float</span> <span class="argument">$x</span>)
</li>
<li>
<span class="access">public</span> <a href="Point.html#method.setY">setY</a>(<span class="type">float</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Point.html#method.setLocation">setLocation</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Point.html#method.getLocation">getLocation</a>()
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Point.html#method.getDistance">getDistance</a>(<a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p</span>)
</li>
<li>
<span class="access">public</span> <a href="Point.html#method.move">move</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.x"></a><span class="access">public</span> <span class="type">float</span> <a href="Point.html#property.x"><span class="argument">$x</span></a><div class="description">
La position du point sur l'axe des abscisses.
</div>
<div class="description-bottom"><a href="Point.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.y"></a><span class="access">public</span> <span class="type">float</span> <a href="Point.html#property.y"><span class="argument">$y</span></a><div class="description">
La position du point sur l'axe des ordonnées.
</div>
<div class="description-bottom"><a href="Point.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Point.html#method.__construct">__construct</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
<div class="description">
Déclare un nouveau point avec des coordonnées x et y.
</div>
<div class="description-bottom"><a href="Point.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setX"></a><span class="access">public</span> <a href="Point.html#method.setX">setX</a>(<span class="type">float</span> <span class="argument">$x</span>)
<div class="description">
Change la position X du point.
</div>
<div class="description-bottom"><a href="Point.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setY"></a><span class="access">public</span> <a href="Point.html#method.setY">setY</a>(<span class="type">float</span> <span class="argument">$y</span>)
<div class="description">
Change la position Y du point.
</div>
<div class="description-bottom"><a href="Point.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLocation"></a><span class="access">public</span> <a href="Point.html#method.setLocation">setLocation</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
<div class="description">
Change la position du point pour les valeurs x et y passées en paramètre.
</div>
<div class="description-bottom"><a href="Point.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getLocation"></a><span class="access">public</span> <span class="type">array</span> <a href="Point.html#method.getLocation">getLocation</a>()
<div class="description">
Retourne la position du point dans un tableau à deux valeurs.
<pre>
 
&lt;?php
$p = new Point(3, 7);
list($x, $y) = $p-&gt;getLocation(); // array(3, 7)
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="Point.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getDistance"></a><span class="access">public</span> <span class="type">float</span> <a href="Point.html#method.getDistance">getDistance</a>(<a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p</span>)
<div class="description">
Retourne la distance entre le point et le point $p.
</div>
<div class="description-bottom"><a href="Point.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.move"></a><span class="access">public</span> <a href="Point.html#method.move">move</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
<div class="description">
Change la position du point en ajoutant à ses coordonnées actuelles les valeurs x et y passées en paramètre.
</div>
<div class="description-bottom"><a href="Point.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Mark.html
New file
0,0 → 1,265
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Mark</h2><div class="description">
<p>
La classe <a href="Mark.html">Mark</a> permet de créer des marques, qui peuvent être affichées n'importe où sur une image.
Typiquement, les marques sont affichées sur les courbes pour mettre en valeur chaque point.
</p>
<div class="image">
<img src="doc/image/marks.png">
</div>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.CIRCLE">CIRCLE</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.SQUARE">SQUARE</a> := <span class="default">2</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.TRIANGLE">TRIANGLE</a> := <span class="default">3</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.INVERTED_TRIANGLE">INVERTED_TRIANGLE</a> := <span class="default">4</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.RHOMBUS">RHOMBUS</a> := <span class="default">5</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.CROSS">CROSS</a> := <span class="default">6</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.PLUS">PLUS</a> := <span class="default">7</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.IMAGE">IMAGE</a> := <span class="default">8</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.STAR">STAR</a> := <span class="default">9</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.PAPERCLIP">PAPERCLIP</a> := <span class="default">10</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.BOOK">BOOK</a> := <span class="default">11</span>
</li>
</ul><ul class="properties">
<li>
<span class="access">protected</span> <a href="Point.html"><span class="type">Point</span></a> <a href="Mark.html#property.move"><span class="argument">$move</span></a>
</li>
<li>
<span class="access">public</span> <a href="Border.html"><span class="type">Border</span></a> <a href="Mark.html#property.border"><span class="argument">$border</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Mark.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="Mark.html#method.move">move</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Mark.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="Mark.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="Mark.html#method.setSize">setSize</a>(<span class="type">int</span> <span class="argument">$size</span>)
</li>
<li>
<span class="access">public</span> <a href="Mark.html#method.setType">setType</a>(<span class="type">int</span> <span class="argument">$type</span>, <span class="type">int</span> <span class="argument">$size</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="Mark.html#method.setFill">setFill</a>(<span class="type">mixed</span> <span class="argument">$fill</span>)
</li>
<li>
<span class="access">public</span> <a href="Mark.html#method.setImage">setImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
</li>
<li>
<span class="access">public</span> <a href="Mark.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.CIRCLE"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.CIRCLE">CIRCLE</a> := <span class="default">1</span><div class="description">
Pour les marques de la forme d'un cercle.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.SQUARE"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.SQUARE">SQUARE</a> := <span class="default">2</span><div class="description">
Pour les marques de la forme d'un carré.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.TRIANGLE"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.TRIANGLE">TRIANGLE</a> := <span class="default">3</span><div class="description">
Pour les marques de la forme d'un trianble.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.INVERTED_TRIANGLE"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.INVERTED_TRIANGLE">INVERTED_TRIANGLE</a> := <span class="default">4</span><div class="description">
Pour les marques de la forme d'un triangle inversé (sommet vers le bas).
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.RHOMBUS"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.RHOMBUS">RHOMBUS</a> := <span class="default">5</span><div class="description">
Représente une marque de type rhombus (carré à 45°).
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.CROSS"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.CROSS">CROSS</a> := <span class="default">6</span><div class="description">
Représente une marque de la forme d'une croix (X).
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.PLUS"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.PLUS">PLUS</a> := <span class="default">7</span><div class="description">
Représente une marque de la forme d'un plus (+).
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.IMAGE"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.IMAGE">IMAGE</a> := <span class="default">8</span><div class="description">
Pour les marques de type image.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.STAR"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.STAR">STAR</a> := <span class="default">9</span><div class="description">
Représente une marque de type étoile.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.PAPERCLIP"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.PAPERCLIP">PAPERCLIP</a> := <span class="default">10</span><div class="description">
Représente une marque de type trombonne.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.BOOK"></a><span class="access">const</span> <span class="type">int</span> <a href="Mark.html#constant.BOOK">BOOK</a> := <span class="default">11</span><div class="description">
Représente une marque de type livre.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.move"></a><span class="access">protected</span> <a href="Point.html"><span class="type">Point</span></a> <a href="Mark.html#property.move"><span class="argument">$move</span></a><div class="description">
Le déplacement de la marque défini par l'utilisateur.
<div class="see">
Voir aussi :
<ul><li><a href="Mark.html#method.move">Mark::move()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.border"></a><span class="access">public</span> <a href="Border.html"><span class="type">Border</span></a> <a href="Mark.html#property.border"><span class="argument">$border</span></a><div class="description">
La bordure qui entoure la marque.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Mark.html#method.__construct">__construct</a>()
<div class="description">
Construit un nouvel objet qui permettra l'affichage de marques sur une image.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.move"></a><span class="access">public</span> <a href="Mark.html#method.move">move</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
<div class="description">
Déplace l'affichage des marques de $x pixels sur l'axe des abscisses et de $y pixels sur l'axe des ordonnées.
Les appels à <a href="Mark.html#method.move">move()</a> sont cumulés, c'est-à-dire qu'un appel avec de nouvelles valeurs additionnera ces valeurs avec les anciennes.
Par défaut, $x et $y sont à 0 pixel.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hide"></a><span class="access">public</span> <a href="Mark.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
<div class="description">
Permet de cacher (par défaut) ou d'afficher les marques.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.show"></a><span class="access">public</span> <a href="Mark.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span> := <span class="default">TRUE</span>)
<div class="description">
Permet d'afficher (par défaut) ou de cacher les marques.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSize"></a><span class="access">public</span> <a href="Mark.html#method.setSize">setSize</a>(<span class="type">int</span> <span class="argument">$size</span>)
<div class="description">
Change la taille des marques pour $size. Cette méthode n'a aucun effet pour les marques de type <a href="Mark.html#constant.IMAGE"></a>, <a href="Mark.html#constant.STAR"></a>, <a href="Mark.html#constant.PAPERCLIP"></a> ou <a href="Mark.html#constant.BOOK"></a>.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setType"></a><span class="access">public</span> <a href="Mark.html#method.setType">setType</a>(<span class="type">int</span> <span class="argument">$type</span>, <span class="type">int</span> <span class="argument">$size</span> := <span class="default">NULL</span>)
<div class="description">
Change le type de marque à utiliser.
Les valeurs possibles sont <a href="Mark.html#constant.CIRCLE"></a>, <a href="Mark.html#constant.SQUARE"></a>, <a href="Mark.html#constant.TRIANGLE"></a>, <a href="Mark.html#constant.IMAGE"></a>, <a href="Mark.html#constant.STAR"></a>, <a href="Mark.html#constant.PAPERCLIP"></a> ou encore <a href="Mark.html#constant.BOOK"></a>.
L'argument optionnel $size permet de déterminer la taille de la marque et n'a aucun effet sur <a href="Mark.html#constant.IMAGE"></a>, <a href="Mark.html#constant.PAPERCLIP"></a> et <a href="Mark.html#constant.BOOK"></a>.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setFill"></a><span class="access">public</span> <a href="Mark.html#method.setFill">setFill</a>(<span class="type">mixed</span> <span class="argument">$fill</span>)
<div class="description">
Remplit la marque avec la couleur ou le dégradé $fill. Cette méthode n'a aucun effet pour les marques de type <a href="Mark.html#constant.IMAGE">Mark::IMAGE</a>.
<div class="see">
Voir aussi :
<ul><li><a href="Mark.html#method.setType">Mark::setType()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setImage"></a><span class="access">public</span> <a href="Mark.html#method.setImage">setImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
<div class="description">
Change l'image à afficher sur la marque. Cette méthode n'a de sens que pour les marques de type <a href="Mark.html#constant.IMAGE">Mark::IMAGE</a>.
<div class="see">
Voir aussi :
<ul><li><a href="Mark.html#method.setType">Mark::setType()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.draw"></a><span class="access">public</span> <a href="Mark.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
<div class="description">
Dessine la marque avec le pilote $driver. Le centre de la marque sera sur le point $point.
</div>
<div class="description-bottom"><a href="Mark.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Tick.html
New file
0,0 → 1,188
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Tick</h2><div class="description">
<p>
La classe <a href="Tick.html">Tick</a> permet de représenter des ticks, petits traits réguliers associés à un axe.
</p>
<div class="image">
<img src="doc/image/ticks-out.png" style="margin-right: 42px" alt="Ticks à l'extérieur">
<img src="doc/image/ticks-in.png" alt="Ticks à l'intérieur">
</div>
<p>
De nombreuses méthodes de la classe <a href="Tick.html">Tick</a> ne sont pas documentées,
car elles ne sont utilisées qu'en interne par Artichow.
Néanmoins, si vous développez Artichow, vous aurez besoin de ces méthodes.
N'hésitez donc pas à parcourir le code source de cette classe.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">string</span> <a href="Tick.html#constant.OUT">OUT</a> := <span class="default">0</span>
</li>
<li>
<span class="access">const</span> <span class="type">string</span> <a href="Tick.html#constant.IN">IN</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">string</span> <a href="Tick.html#constant.IN_OUT">IN_OUT</a> := <span class="default">2</span>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Tick.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$number</span>, <span class="type">int</span> <span class="argument">$size</span>)
</li>
<li>
<span class="access">public</span> <a href="Tick.html#method.setStyle">setStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
</li>
<li>
<span class="access">public</span> <a href="Tick.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Tick.html#method.setSize">setSize</a>(<span class="type">int</span> <span class="argument">$size</span>)
</li>
<li>
<span class="access">public</span> <a href="Tick.html#method.setInterval">setInterval</a>(<span class="type">int</span> <span class="argument">$interval</span>)
</li>
<li>
<span class="access">public</span> <a href="Tick.html#method.setNumber">setNumber</a>(<span class="type">int</span> <span class="argument">$number</span>)
</li>
<li>
<span class="access">public</span> <a href="Tick.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
</li>
<li>
<span class="access">public</span> <a href="Tick.html#method.hideFirst">hideFirst</a>(<span class="type">bool</span> <span class="argument">$hideFirst</span>)
</li>
<li>
<span class="access">public</span> <a href="Tick.html#method.hideLast">hideLast</a>(<span class="type">bool</span> <span class="argument">$hideLast</span>)
</li>
<li>
<span class="access">public</span> <a href="Tick.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Vector.html"><span class="type">Vector</span></a> <span class="argument">$vector</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.OUT"></a><span class="access">const</span> <span class="type">string</span> <a href="Tick.html#constant.OUT">OUT</a> := <span class="default">0</span><div class="description">
Indique que les ticks doivent être tournés vers l'extérieur.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.IN"></a><span class="access">const</span> <span class="type">string</span> <a href="Tick.html#constant.IN">IN</a> := <span class="default">1</span><div class="description">
Indique que les types doivent être tournés vers l'intérieur.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.IN_OUT"></a><span class="access">const</span> <span class="type">string</span> <a href="Tick.html#constant.IN_OUT">IN_OUT</a> := <span class="default">2</span><div class="description">
Indique que les ticks sont et tournés vers l'extérieur, et tournés vers l'intérieur.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Tick.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$number</span>, <span class="type">int</span> <span class="argument">$size</span>)
<div class="description">
Construit un nouvel objet <a href="Tick.html">Tick</a>.
$number représente un nombre de ticks et $size leur taille en pixels.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setStyle"></a><span class="access">public</span> <a href="Tick.html#method.setStyle">setStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
<div class="description">
Change le style des ticks. Peut être <a href="Tick.html#constant.IN">Tick::IN</a>, <a href="Tick.html#constant.OUT">Tick::OUT</a> ou <a href="Tick.html#constant.IN_OUT">Tick::IN_OUT</a>.
Dans le premier cas, les ticks seront tournés vers l'intérieur. Dans le second vers l'extérieur et dans le troisième et vers l'extérieur et vers l'intérieur.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColor"></a><span class="access">public</span> <a href="Tick.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur des ticks pour $color.
Par défaut, les ticks sont dessinés en noir.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSize"></a><span class="access">public</span> <a href="Tick.html#method.setSize">setSize</a>(<span class="type">int</span> <span class="argument">$size</span>)
<div class="description">
Change la taille des ticks pour $size.
$size doit être donné en pixels.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setInterval"></a><span class="access">public</span> <a href="Tick.html#method.setInterval">setInterval</a>(<span class="type">int</span> <span class="argument">$interval</span>)
<div class="description">
Change l'intervalle d'affichage des ticks par rapport à leur nombre.
Si $interval vaut 1, alors tous les ticks seront affichés.
Si $interval vaut 0.5, alors un tick sur deux sera affiché.
<div class="see">
Voir aussi :
<ul><li><a href="Tick.html#method.setNumber">Tick::setNumber()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setNumber"></a><span class="access">public</span> <a href="Tick.html#method.setNumber">setNumber</a>(<span class="type">int</span> <span class="argument">$number</span>)
<div class="description">
Change le nombre de ticks à afficher pour $number.
<div class="see">
Voir aussi :
<ul><li><a href="Tick.html#method.setInterval">Tick::setInterval()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hide"></a><span class="access">public</span> <a href="Tick.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
<div class="description">
Permet de cache ou d'afficher les ticks.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hideFirst"></a><span class="access">public</span> <a href="Tick.html#method.hideFirst">hideFirst</a>(<span class="type">bool</span> <span class="argument">$hideFirst</span>)
<div class="description">
Permet de cache ou d'afficher le premier tick.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hideLast"></a><span class="access">public</span> <a href="Tick.html#method.hideLast">hideLast</a>(<span class="type">bool</span> <span class="argument">$hideLast</span>)
<div class="description">
Permet de cache ou d'afficher le dernier tick.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.draw"></a><span class="access">public</span> <a href="Tick.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Vector.html"><span class="type">Vector</span></a> <span class="argument">$vector</span>)
<div class="description">
Dessine les ticks sur le vecteur $vector.
</div>
<div class="description-bottom"><a href="Tick.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Gradient.html
New file
0,0 → 1,82
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2>
<small>abstract</small> Class Gradient</h2><div class="description">
<p>
Toutes les classes qui décrivent un dégradé dérivent de cette classe abstraite.
</p>
</div><div class="inherit">
Les classes suivantes dérivent de Gradient :
<ul>
<li><a href="LinearGradient.html">LinearGradient</a></li>
<li><a href="RadialGradient.html">RadialGradient</a></li>
</ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Gradient.html#property.from"><span class="argument">$from</span></a>
</li>
<li>
<span class="access">public</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Gradient.html#property.to"><span class="argument">$to</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Gradient.html#method.__construct">__construct</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$from</span>, <a href="Color.html"><span class="type">Color</span></a> <span class="argument">$to</span>)
</li>
<li>
<span class="access">public</span> <a href="Gradient.html#method.free">free</a>()
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.from"></a><span class="access">public</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Gradient.html#property.from"><span class="argument">$from</span></a><div class="description">
La couleur de départ pour le dégradé
</div>
<div class="description-bottom"><a href="Gradient.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.to"></a><span class="access">public</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Gradient.html#property.to"><span class="argument">$to</span></a><div class="description">
La couleur d'arrivée pour le dégradé
</div>
<div class="description-bottom"><a href="Gradient.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Gradient.html#method.__construct">__construct</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$from</span>, <a href="Color.html"><span class="type">Color</span></a> <span class="argument">$to</span>)
<div class="description">
Construit une nouveu dégradé. Cette méthode doit être appelée par toutes les classes qui dérivent de celle-ci. Le paramètre $from décrit la couleur de départ du dégradé et le paramètre $to celle de fin.
</div>
<div class="description-bottom"><a href="Gradient.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.free"></a><span class="access">public</span> <a href="Gradient.html#method.free">free</a>()
<div class="description">
Libère les ressources allouées lors de la création du dégradé.
</div>
<div class="description-bottom"><a href="Gradient.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Legend.html
New file
0,0 → 1,442
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Legend</h2><div class="description">
<p>
La classe <a href="Legend.html">Legend</a> permet de manipuler des légendes.
Un objet de la classe <a href="Legend.html">Legend</a> est disponible sur tous les <a href="Component.html">composants</a>.
N'importe quel objet peut être légendé à condition qu'il implémente l'interface <a href="Legendable.html">Legendable</a>.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.LINE">LINE</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.BACKGROUND">BACKGROUND</a> := <span class="default">2</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.MARK">MARK</a> := <span class="default">3</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.MARKONLY">MARKONLY</a> := <span class="default">4</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.MODEL_RIGHT">MODEL_RIGHT</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.MODEL_BOTTOM">MODEL_BOTTOM</a> := <span class="default">2</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.LEFT">LEFT</a> := <span class="default">0</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.RIGHT">RIGHT</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.CENTER">CENTER</a> := <span class="default">2</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.TOP">TOP</a> := <span class="default">3</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.BOTTOM">BOTTOM</a> := <span class="default">4</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.MIDDLE">MIDDLE</a> := <span class="default">5</span>
</li>
</ul><ul class="properties">
<li>
<span class="access">public</span> <a href="Shadow.html"><span class="type">Shadow</span></a> <a href="Legend.html#property.shadow"><span class="argument">$shadow</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Legend.html#property.hide"><span class="argument">$hide</span></a>
</li>
<li>
<span class="access">protected</span> <a href="ArrayOject.html"><span class="type">ArrayOject</span></a> <a href="Legend.html#property.legends"><span class="argument">$legends</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Legend.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$model</span> := <span class="default">Legend::MODEL_RIGHT</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setModel">setModel</a>(<span class="type">int</span> <span class="argument">$model</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.add">add</a>(<a href="Legendable.html"><span class="type">Legendable</span></a> <span class="argument">$legendable</span>, <span class="type">string</span> <span class="argument">$title</span>, <span class="type">int</span> <span class="argument">$type</span> := <span class="default">Legend::LINE</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setPadding">setPadding</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>, <span class="type">int</span> <span class="argument">$top</span>, <span class="type">int</span> <span class="argument">$bottom</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setSpace">setSpace</a>(<span class="type">int</span> <span class="argument">$space</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setAlign">setAlign</a>(<span class="type">int</span> <span class="argument">$h</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$v</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setColumns">setColumns</a>(<span class="type">int</span> <span class="argument">$columns</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setRows">setRows</a>(<span class="type">int</span> <span class="argument">$rows</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setPosition">setPosition</a>(<span class="type">float</span> <span class="argument">$x</span> := <span class="default">NULL</span>, <span class="type">float</span> <span class="argument">$y</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="Point.html"><span class="type">Point</span></a> <a href="Legend.html#method.getPosition">getPosition</a>()
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setTextFont">setTextFont</a>(<a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setTextMargin">setTextMargin</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setTextColor">setTextColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setBackground">setBackground</a>(<span class="type">mixed</span> <span class="argument">$background</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setBackgroundGradient">setBackgroundGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setBorderSize">setBorderSize</a>(<span class="type">int</span> <span class="argument">$size</span>)
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.setBorderColor">setBorderColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Legend.html#method.count">count</a>()
</li>
<li>
<span class="access">public</span> <a href="Legend.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.LINE"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.LINE">LINE</a> := <span class="default">1</span><div class="description">
Utilise une couleur de ligne pour identifier un objet dans la légende.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.BACKGROUND"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.BACKGROUND">BACKGROUND</a> := <span class="default">2</span><div class="description">
Utilise une couleur de fond pour identifier un objet dans la légende.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.MARK"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.MARK">MARK</a> := <span class="default">3</span><div class="description">
Utilise un objet Mark et une ligne pour identifier un objet dans la légende.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.MARKONLY"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.MARKONLY">MARKONLY</a> := <span class="default">4</span><div class="description">
Utilise un objet Mark seulement pour identifier un objet dans la légende.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.MODEL_RIGHT"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.MODEL_RIGHT">MODEL_RIGHT</a> := <span class="default">1</span><div class="description">
Modèle prédéfini qui place la légende à droite.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.MODEL_BOTTOM"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.MODEL_BOTTOM">MODEL_BOTTOM</a> := <span class="default">2</span><div class="description">
Modèle prédéfini qui place la légende en bas.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.LEFT"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.LEFT">LEFT</a> := <span class="default">0</span><div class="description">
Aligne horizontalement la légende à gauche.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.RIGHT"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.RIGHT">RIGHT</a> := <span class="default">1</span><div class="description">
Aligne horizontalement la légende à droite.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.CENTER"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.CENTER">CENTER</a> := <span class="default">2</span><div class="description">
Centre la légende horizontalement.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.TOP"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.TOP">TOP</a> := <span class="default">3</span><div class="description">
Aligne verticalement la légende en haut.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.BOTTOM"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.BOTTOM">BOTTOM</a> := <span class="default">4</span><div class="description">
Aligne verticalement la légende en bas.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.MIDDLE"></a><span class="access">const</span> <span class="type">int</span> <a href="Legend.html#constant.MIDDLE">MIDDLE</a> := <span class="default">5</span><div class="description">
Aligne verticalement la légende au milieu.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.shadow"></a><span class="access">public</span> <a href="Shadow.html"><span class="type">Shadow</span></a> <a href="Legend.html#property.shadow"><span class="argument">$shadow</span></a><div class="description">
Cette propriété permet de manipuler l'ombre associée éventuellement avec la légende.
Par défaut, aucune ombre n'est affichée. Si vous souhaitez afficher une ombre, il vous suffit de lui donner une taille :
<pre>
 
&lt;?php
 
require_once "Tools.class.php";
 
$legend = new <a href="Legend.html">Legend</a>();
 
// On associe une ombre de 4 pixels à la légende
$legend-&gt;shadow-&gt;<a href="Legend.html#method.setSize">setSize</a>(4);
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.hide"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Legend.html#property.hide"><span class="argument">$hide</span></a><div class="description">
Détermine si la légende doit être cachée ou non.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.legends"></a><span class="access">protected</span> <a href="ArrayOject.html"><span class="type">ArrayOject</span></a> <a href="Legend.html#property.legends"><span class="argument">$legends</span></a><div class="description">
Les objets <a href="Legendable.html">Legendable</a> à afficher sur la légende.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Legend.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$model</span> := <span class="default">Legend::MODEL_RIGHT</span>)
<div class="description">
Construit une nouvelle légende avec le modèle $model.
Les valeurs possibles pour $model sont <a href="Legend.html#constant.MODEL_BOTTOM">Legend::MODEL_BOTTOM</a> et <a href="Legend.html#constant.MODEL_RIGHT">Legend::MODEL_RIGHT</a>.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hide"></a><span class="access">public</span> <a href="Legend.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
<div class="description">
Permet de cacher (par défaut) ou d'afficher la légende.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.show"></a><span class="access">public</span> <a href="Legend.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span> := <span class="default">TRUE</span>)
<div class="description">
Permet d'afficher (par défaut) ou de cacher la légende.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setModel"></a><span class="access">public</span> <a href="Legend.html#method.setModel">setModel</a>(<span class="type">int</span> <span class="argument">$model</span>)
<div class="description">
Change le modèle de légende pour $model.
L'appel à cette méthode peut écraser les valeurs passées à d'autres méthodes comme <a href="Legend.html#method.setPadding">setPadding()</a> ou <a href="Legend.html#method.setHorizontalAlign">setHorizontalAlign()</a> par exemple (liste non exhaustive).
Les valeurs possibles pour $model sont <a href="Legend.html#constant.MODEL_BOTTOM">Legend::MODEL_BOTTOM</a> et <a href="Legend.html#constant.MODEL_RIGHT">Legend::MODEL_RIGHT</a>.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.add"></a><span class="access">public</span> <a href="Legend.html#method.add">add</a>(<a href="Legendable.html"><span class="type">Legendable</span></a> <span class="argument">$legendable</span>, <span class="type">string</span> <span class="argument">$title</span>, <span class="type">int</span> <span class="argument">$type</span> := <span class="default">Legend::LINE</span>)
<div class="description">
Ajoute un nouvel objet <a href="Legendable.html">légendable</a> avec pour titre $title à cette légende.
$type permet de spécifier le type de légende, qui peut être <a href="Legend.html#constant.LINE">Legend::LINE</a>, <a href="Legend.html#constant.BACKGROUND">Legend::BACKGROUND</a>, <a href="Legend.html#constant.MARK">Legend::MARK</a> ou encore <a href="Legend.html#constant.MARKONLY">Legend::MARKONLY</a>.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setPadding"></a><span class="access">public</span> <a href="Legend.html#method.setPadding">setPadding</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>, <span class="type">int</span> <span class="argument">$top</span>, <span class="type">int</span> <span class="argument">$bottom</span>)
<div class="description">
Change l'espace interne de la légende.
Les nouvelles valeurs doivent être données en pixels.
Laissez les paramètres dont vous ne souhaitez pas modifier la valeur à NULL.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSpace"></a><span class="access">public</span> <a href="Legend.html#method.setSpace">setSpace</a>(<span class="type">int</span> <span class="argument">$space</span>)
<div class="description">
Change l'espace entre chaque valeur.
Cet espace doit être donné en pixels.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAlign"></a><span class="access">public</span> <a href="Legend.html#method.setAlign">setAlign</a>(<span class="type">int</span> <span class="argument">$h</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$v</span> := <span class="default">NULL</span>)
<div class="description">
Change l'alignement de la légende par rapport au point où elle sera affichée.
$h correspond à l'alignement horizontal (<a href="Legend.html#constant.LEFT">Legend::LEFT</a>, <a href="Legend.html#constant.RIGHT">Legend::RIGHT</a> ou <a href="Legend.html#constant.CENTER">Legend::CENTER</a>) et $v à l'alignement vertical (<a href="Legend.html#constant.TOP">Legend::TOP</a>, <a href="Legend.html#constant.BOTTOM">Legend::BOTTOM</a> ou <a href="Legend.html#constant.MIDDLE">Legend::MIDDLE</a>).
Si vous ne souhaitez pas modifier une des deux valeurs, vous pouvez passer NULL.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColumns"></a><span class="access">public</span> <a href="Legend.html#method.setColumns">setColumns</a>(<span class="type">int</span> <span class="argument">$columns</span>)
<div class="description">
Change le nombre de colonnes qui seront affichées dans la légende pour $columns.
Cette méthode est incompatible avec <a href="Legend.html#method.setRows">setRows()</a>.
<div class="see">
Voir aussi :
<ul><li><a href="Legend.html#method.setColumns">Legend::setColumns()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setRows"></a><span class="access">public</span> <a href="Legend.html#method.setRows">setRows</a>(<span class="type">int</span> <span class="argument">$rows</span>)
<div class="description">
Change le nombre de lignes qui seront affichées dans la légende pour $rows.
Cette méthode est incompatible avec <a href="Legend.html#method.setColumns">setColumns()</a>.
<div class="see">
Voir aussi :
<ul><li><a href="Legend.html#method.setRows">Legend::setRows()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setPosition"></a><span class="access">public</span> <a href="Legend.html#method.setPosition">setPosition</a>(<span class="type">float</span> <span class="argument">$x</span> := <span class="default">NULL</span>, <span class="type">float</span> <span class="argument">$y</span> := <span class="default">NULL</span>)
<div class="description">
Change la position de la légende sur l'objet légendé.
Les positions $x et $y sont des fractions des largeur et hauteur de l'objet légendé.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getPosition"></a><span class="access">public</span> <a href="Point.html"><span class="type">Point</span></a> <a href="Legend.html#method.getPosition">getPosition</a>()
<div class="description">
Retourne la position courante de la légende sur l'objet légendé sous la forme d'un <a href="Point.html">point</a>.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setTextFont"></a><span class="access">public</span> <a href="Legend.html#method.setTextFont">setTextFont</a>(<a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span>)
<div class="description">
Change la police à utiliser sur la légende.
Voir la classe <a href="Font.html">Font</a> pour une liste des polices disponibles.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setTextMargin"></a><span class="access">public</span> <a href="Legend.html#method.setTextMargin">setTextMargin</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>)
<div class="description">
Change la marge gauche et droite autour du texte des légendes.
$left et $right sont à donner en pixels.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setTextColor"></a><span class="access">public</span> <a href="Legend.html#method.setTextColor">setTextColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur du texte de la légende.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackground"></a><span class="access">public</span> <a href="Legend.html#method.setBackground">setBackground</a>(<span class="type">mixed</span> <span class="argument">$background</span>)
<div class="description">
Change le fond de la légende.
$background peut être soit une couleur, soit un dégradé.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundColor"></a><span class="access">public</span> <a href="Legend.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de fond de la légende.
<div class="see">
Voir aussi :
<ul><li><a href="Legend.html#method.setBackground">Legend::setBackground()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundGradient"></a><span class="access">public</span> <a href="Legend.html#method.setBackgroundGradient">setBackgroundGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
<div class="description">
Change le dégradé de fond de la légende.
<div class="see">
Voir aussi :
<ul><li><a href="Legend.html#method.setBackground">Legend::setBackground()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBorderSize"></a><span class="access">public</span> <a href="Legend.html#method.setBorderSize">setBorderSize</a>(<span class="type">int</span> <span class="argument">$size</span>)
<div class="description">
Change la taille de la bordure qui entoure la légende.
Les valeurs possibles sont 0 et 1.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBorderColor"></a><span class="access">public</span> <a href="Legend.html#method.setBorderColor">setBorderColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de la bordure qui entoure la légende.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.count"></a><span class="access">public</span> <span class="type">int</span> <a href="Legend.html#method.count">count</a>()
<div class="description">
Retourne le nombre d'objets <a href="Legendable.html">légendable</a> qui ont été ajoutés à cette légende.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.draw"></a><span class="access">public</span> <a href="Legend.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
<div class="description">
Dessine la légende avec le pilote $driver.
</div>
<div class="description-bottom"><a href="Legend.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/MathFunction.html
New file
0,0 → 1,87
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class MathFunction</h2><div class="description">
<p>
Cette classe permet de représenter une fonction mathématique f(x) à afficher sur un graphique de type <a href="MathPlot.html">MathPlot</a>.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <a href="Line.html"><span class="type">Line</span></a> <a href="MathFunction.html#property.line"><span class="argument">$line</span></a>
</li>
<li>
<span class="access">public</span> <a href="Mark.html"><span class="type">Mark</span></a> <a href="MathFunction.html#property.mark"><span class="argument">$mark</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="MathFunction.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$f</span>, <span class="type">float</span> <span class="argument">$fromX</span>, <span class="type">float</span> <span class="argument">$toX</span>)
</li>
<li>
<span class="access">public</span> <a href="MathFunction.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Color.html"><span class="type">Color</span></a> <a href="MathFunction.html#method.getColor">getColor</a>()
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.line"></a><span class="access">public</span> <a href="Line.html"><span class="type">Line</span></a> <a href="MathFunction.html#property.line"><span class="argument">$line</span></a><div class="description">
La ligne qui sera utilisée pour représenter la fonction.
</div>
<div class="description-bottom"><a href="MathFunction.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.mark"></a><span class="access">public</span> <a href="Mark.html"><span class="type">Mark</span></a> <a href="MathFunction.html#property.mark"><span class="argument">$mark</span></a><div class="description">
Les marques qui seront affichés sur chaque point calculé.
</div>
<div class="description-bottom"><a href="MathFunction.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="MathFunction.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$f</span>, <span class="type">float</span> <span class="argument">$fromX</span>, <span class="type">float</span> <span class="argument">$toX</span>)
<div class="description">
Créé un objet <a href="MathFunction.html">MathFunction</a> avec la fonction $f.
$f est une fonction qui prend un paramètre $x en paramètre et qui doit retourner une valeur $y.
Les valeurs $fromX et $toX représentent les valeurs de X à partir desquelles commencer et terminer le calcul de la courbe représentative de la fonction.
</div>
<div class="description-bottom"><a href="MathFunction.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColor"></a><span class="access">public</span> <a href="MathFunction.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de la courbe représentative de la fonction pour $color.
</div>
<div class="description-bottom"><a href="MathFunction.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getColor"></a><span class="access">public</span> <a href="Color.html"><span class="type">Color</span></a> <a href="MathFunction.html#method.getColor">getColor</a>()
<div class="description">
Retourne la couleur de la courbe représentative de la fonction.
</div>
<div class="description-bottom"><a href="MathFunction.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Graph.html
New file
0,0 → 1,214
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Graph</h2><div class="extends"><ul>
<li><a href="Image.html">Image</a></li>
<ul><li>Graph</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="Graph.html">Graph</a> permet de générer des graphiques, de les mettre éventuellement en cache et d'afficher le temps de génération de l'image. Il est possible de dessiner plusieurs <a href="Component.html">composants</a> sur une <a href="Image.html">image</a> de type <a href="Graph.html">Graph</a>.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Graph.html#constant.DRAW_RETURN">DRAW_RETURN</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Graph.html#constant.DRAW_DISPLAY">DRAW_DISPLAY</a> := <span class="default">2</span>
</li>
</ul><ul class="properties">
<li>
<span class="access">protected</span> <span class="type">string</span> <a href="Graph.html#property.name"><span class="argument">$name</span></a> := <span class="default">NULL</span>
</li>
<li>
<span class="access">protected</span> <span class="type">int</span> <a href="Graph.html#property.timeout"><span class="argument">$timeout</span></a> := <span class="default">0</span>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Graph.html#property.timing"><span class="argument">$timing</span></a> := <span class="default">FALSE</span>
</li>
<li>
<span class="access">protected</span> <span class="type">array</span> <a href="Graph.html#property.labels"><span class="argument">$labels</span></a>
</li>
<li>
<span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="Graph.html#property.title"><span class="argument">$title</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Graph.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$width</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$height</span> := <span class="default">NULL</span>, <span class="type">string</span> <span class="argument">$name</span> := <span class="default">NULL</span>, <span class="type">string</span> <span class="argument">$timeout</span> := <span class="default">0</span>)
</li>
<li>
<span class="access">public</span> <span class="type">bool</span> <a href="Graph.html#method.deleteFromCache">deleteFromCache</a>(<span class="type">string</span> <span class="argument">$name</span>)
</li>
<li>
<span class="access">public</span> <a href="Graph.html#method.deleteAllCache">deleteAllCache</a>()
</li>
<li>
<span class="access">public</span> <a href="Graph.html#method.setTiming">setTiming</a>(<span class="type">bool</span> <span class="argument">$timing</span>)
</li>
<li>
<span class="access">public</span> <a href="Graph.html#method.add">add</a>(<a href="Component.html"><span class="type">Component</span></a> <span class="argument">$component</span>)
</li>
<li>
<span class="access">public</span> <a href="Graph.html#method.addLabel">addLabel</a>(<a href="Label.html"><span class="type">Label</span></a> <span class="argument">$label</span>, <span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Graph.html#method.addAbsLabel">addAbsLabel</a>(<a href="Label.html"><span class="type">Label</span></a> <span class="argument">$label</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
</li>
<li>
<span class="access">public</span> <span class="type">mixed</span> <a href="Graph.html#method.draw">draw</a>(<span class="type">string</span> <span class="argument">
$mode</span> := <span class="default">Graph::DRAW_DISPLAY</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.DRAW_RETURN"></a><span class="access">const</span> <span class="type">int</span> <a href="Graph.html#constant.DRAW_RETURN">DRAW_RETURN</a> := <span class="default">1</span><div class="description">
Pour retourner le graphique après du dessin.
<div class="see">
Voir aussi :
<ul><li><a href="Graph.html#method.draw">Graph::draw()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.DRAW_DISPLAY"></a><span class="access">const</span> <span class="type">int</span> <a href="Graph.html#constant.DRAW_DISPLAY">DRAW_DISPLAY</a> := <span class="default">2</span><div class="description">
Pour afficher le graphique après du dessin.
<div class="see">
Voir aussi :
<ul><li><a href="Graph.html#method.draw">Graph::draw()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.name"></a><span class="access">protected</span> <span class="type">string</span> <a href="Graph.html#property.name"><span class="argument">$name</span></a> := <span class="default">NULL</span><div class="description">
Nom du graphique.
Peut être laissé à NULL pour ne donner aucun nom au graphique.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.timeout"></a><span class="access">protected</span> <span class="type">int</span> <a href="Graph.html#property.timeout"><span class="argument">$timeout</span></a> := <span class="default">0</span><div class="description">
Peut prendre comme valeur 0 pour ne pas utiliser la mise en cache, ou spécifier un timestamp comme date d'expiration de l'image dans le cache.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.timing"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Graph.html#property.timing"><span class="argument">$timing</span></a> := <span class="default">FALSE</span><div class="description">
Activer l'affichage du temps de génération de l'image ?
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.labels"></a><span class="access">protected</span> <span class="type">array</span> <a href="Graph.html#property.labels"><span class="argument">$labels</span></a><div class="description">
Une liste de <a href="Label.html">Label</a> qui seront affichés sur le graphique.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.title"></a><span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="Graph.html#property.title"><span class="argument">$title</span></a><div class="description">
Permet de donner un titre au graphique.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Graph.html#method.__construct">__construct</a>(<span class="type">int</span> <span class="argument">$width</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$height</span> := <span class="default">NULL</span>, <span class="type">string</span> <span class="argument">$name</span> := <span class="default">NULL</span>, <span class="type">string</span> <span class="argument">$timeout</span> := <span class="default">0</span>)
<div class="description">
Construit une image de largeur $width et de hauteur $height au nom $name (ce nom peut être laissé à NULL) et qui expirera dans le cache au timestamp $timeout. Si vous ne souhaitez pas utiliser le cache, vous pouvez laisser ce timestamp à 0.
$name ne représente pas le titre du graphique, c'est uniquement un moyen d'identification pour le cache.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.deleteFromCache"></a><span class="access">public</span> <span class="type">bool</span> <a href="Graph.html#method.deleteFromCache">deleteFromCache</a>(<span class="type">string</span> <span class="argument">$name</span>)
<div class="description">
Supprime manuellement l'image au nom $name du cache.
Cette méthode retourne TRUE si une image a été effectivement supprimée, FALSE sinon.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.deleteAllCache"></a><span class="access">public</span> <a href="Graph.html#method.deleteAllCache">deleteAllCache</a>()
<div class="description">
Supprime toutes les images mises en cache par Artichow.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setTiming"></a><span class="access">public</span> <a href="Graph.html#method.setTiming">setTiming</a>(<span class="type">bool</span> <span class="argument">$timing</span>)
<div class="description">
Active/désactive l'affichage du temps de génération de l'image sur l'image elle-même.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.add"></a><span class="access">public</span> <a href="Graph.html#method.add">add</a>(<a href="Component.html"><span class="type">Component</span></a> <span class="argument">$component</span>)
<div class="description">
Ajoute un <a href="Component.html">composant</a> à dessiner sur l'image.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.addLabel"></a><span class="access">public</span> <a href="Graph.html#method.addLabel">addLabel</a>(<a href="Label.html"><span class="type">Label</span></a> <span class="argument">$label</span>, <span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
<div class="description">
Ajoute une étiquette $label aux positions $x et $y.
Les nouvelles positions $x et $y représentent une fraction des largeur et hauteur du graphique.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.addAbsLabel"></a><span class="access">public</span> <a href="Graph.html#method.addAbsLabel">addAbsLabel</a>(<a href="Label.html"><span class="type">Label</span></a> <span class="argument">$label</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
<div class="description">
Ajoute une étiquette $label en position absolue sur le graphique aux coordonnées X et Y spécifiées par le point $point.
Le point (0, 0) se situe sur le coin haut-gauche du graphique.
</div>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.draw"></a><span class="access">public</span> <span class="type">mixed</span> <a href="Graph.html#method.draw">draw</a>(<span class="type">string</span> <span class="argument">
$mode</span> := <span class="default">Graph::DRAW_DISPLAY</span>)
<div class="description">
Créé et affiche l'image à l'utilisateur. Tous les composants précédemment ajoutés avec <a href="Graph.html#method.add">add()</a> sont dessinés sur l'image.
Cette méthode appelle successivement <a href="Image.html#method.create">create()</a>, <a href="Image.html#method.drawComponent">drawComponent()</a> autant de fois que de composants ont été ajoutés et <a href="Image.html#method.send">send()</a>.
</div>
<ul class="arguments">
<li class="property">
<span class="type">string</span> <a href="Graph.html#property.mode"><span class="argument">$mode</span></a> := <span class="default">Graph::DRAW_DISPLAY</span><ul class="version"><li>
Disponible depuis Artichow 1.0.8</li></ul>
</li>
<li class="property">
<span class="type">string</span> <a href="Graph.html#property.file"><span class="argument">$file</span></a> := <span class="default">NULL</span><ul class="version"><li>
Supprimé à partir d'Artichow 1.0.8</li></ul>
<div class="description">
Si vous souhaitez enregistrer l'image dans un fichier plutôt qu'à l'écran, indiquez un nom de fichier destination pour le paramètre $file.
Ce paramètre est optionnel, et si il n'est pas rempli, alors l'image sera affichée à l'écran.
</div>
</li>
</ul>
<div class="description-bottom"><a href="Graph.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Component.html
New file
0,0 → 1,464
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2>
<small>abstract</small> Class Component</h2><div class="description">
<p>
Un composant est un objet qui peut être ajouté à une <a href="Image.html">Image</a>. Les composants sont indépendants les uns des autres. La classe <a href="Component.html">Component</a> est une classe abstraite, dont doivent dériver tous les objets qui vont pouvoir être ajoutés sur une image.
</p>
<p>
Sur un composant, l'axe des abscisses rejoint l'axe des ordonnées sur le coin haut-gauche. Le coin haut-gauche du composant a donc pour coordonnées (0, 0) et le coin bas-droite (largeur, hauteur). Par exemple, sur une image de largeur 100 et de hauteur 50, un point à 50 sur l'axe des abscisses et 25 sur l'axe des ordonnées sera au centre de l'image.
</p>
</div><div class="inherit">
Les classes suivantes dérivent de Component :
<ul>
<li><a href="ComponentGroup.html">ComponentGroup</a></li>
<li><a href="MathPlot.html">MathPlot</a></li>
<li><a href="Pie.html">Pie</a></li>
<li><a href="Plot.html">Plot</a></li>
</ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">protected</span> <a href="Driver.html"><span class="type">Driver</span></a> <a href="Component.html#property.driver"><span class="argument">$driver</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Component.html#property.width"><span class="argument">$width</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Component.html#property.height"><span class="argument">$height</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Component.html#property.x"><span class="argument">$x</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Component.html#property.y"><span class="argument">$y</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Component.html#property.w"><span class="argument">$w</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Component.html#property.h"><span class="argument">$h</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Component.html#property.top"><span class="argument">$top</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Component.html#property.left"><span class="argument">$left</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">mixed</span> <a href="Component.html#property.background"><span class="argument">$background</span></a>
</li>
<li>
<span class="access">public</span> <a href="Side.html"><span class="type">Side</span></a> <a href="Component.html#property.padding"><span class="argument">$padding</span></a>
</li>
<li>
<span class="access">public</span> <a href="Side.html"><span class="type">Side</span></a> <a href="Component.html#property.space"><span class="argument">$space</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Component.html#property.auto"><span class="argument">$auto</span></a>
</li>
<li>
<span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="Component.html#property.title"><span class="argument">$title</span></a>
</li>
<li>
<span class="access">public</span> <a href="Legend.html"><span class="type">Legend</span></a> <a href="Component.html#property.legend"><span class="argument">$legend</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Component.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.auto">auto</a>(<span class="type">bool</span> <span class="argument">$auto</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.setSize">setSize</a>(<span class="type">float</span> <span class="argument">$width</span>, <span class="type">float</span> <span class="argument">$height</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.setAbsSize">setAbsSize</a>(<span class="type">int</span> <span class="argument">$w</span>, <span class="type">int</span> <span class="argument">$h</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.setBackgroundGradient">setBackgroundGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.setBackgroundImage">setBackgroundImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
</li>
<li>
<span class="access">public</span> <span class="type">mixed</span> <a href="Component.html#method.getBackground">getBackground</a>(<span class="type">int</span> <span class="argument">$type</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.setPadding">setPadding</a>(<span class="type">int</span> <span class="argument">$left</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$right</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$top</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$bottom</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.setSpace">setSpace</a>(<span class="type">int</span> <span class="argument">$left</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$right</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$top</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$bottom</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.setCenter">setCenter</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.setAbsPosition">setAbsPosition</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$top</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.init">init</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
</li>
<li>
<span class="access">public</span> <a href="Component.html#method.finalize">finalize</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
</li>
<li>
<span class="access">abstract public</span> <span class="type">array</span> <a href="Component.html#method.getPosition">getPosition</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
</li>
<li>
<span class="access">abstract public</span> <a href="Component.html#method.drawEnvelope">drawEnvelope</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
</li>
<li>
<span class="access">abstract public</span> <a href="Component.html#method.drawComponent">drawComponent</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <span class="type">int</span> <span class="argument">$x1</span>, <span class="type">int</span> <span class="argument">$y1</span>, <span class="type">int</span> <span class="argument">$x2</span>, <span class="type">int</span> <span class="argument">$y2</span>, <span class="type">bool</span> <span class="argument">$aliasing</span>)
</li>
<li>
<span class="access">protected</span> <a href="Component.html#method.getSpace">getSpace</a>(<span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.driver"></a><span class="access">protected</span> <a href="Driver.html"><span class="type">Driver</span></a> <a href="Component.html#property.driver"><span class="argument">$driver</span></a><div class="description">
Un objet <a href="Driver.html">Driver</a> pour dessiner sur l'image.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.width"></a><span class="access">public</span> <span class="type">float</span> <a href="Component.html#property.width"><span class="argument">$width</span></a><div class="description">
Largeur du composant entre 0 et 1. Représente une fraction de la largeur de l'image.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.height"></a><span class="access">public</span> <span class="type">float</span> <a href="Component.html#property.height"><span class="argument">$height</span></a><div class="description">
Hauteur du composant entre 0 et 1. Représente une fraction de la hauteur de l'image.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.x"></a><span class="access">public</span> <span class="type">float</span> <a href="Component.html#property.x"><span class="argument">$x</span></a><div class="description">
Position du composant sur l'axe des abscisses entre 0 et 1. Représente une fraction de la largeur de l'image.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.y"></a><span class="access">public</span> <span class="type">float</span> <a href="Component.html#property.y"><span class="argument">$y</span></a><div class="description">
Position du composant sur l'axe des ordonnées entre 0 et 1. Représente une fraction de la hauteur de l'image.
Attention, la position 0 correspond au haut de l'image.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.w"></a><span class="access">public</span> <span class="type">int</span> <a href="Component.html#property.w"><span class="argument">$w</span></a><div class="description">
Largeur du composant en pixels.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.h"></a><span class="access">public</span> <span class="type">int</span> <a href="Component.html#property.h"><span class="argument">$h</span></a><div class="description">
Hauteur du composant en pixels.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.top"></a><span class="access">public</span> <span class="type">int</span> <a href="Component.html#property.top"><span class="argument">$top</span></a><div class="description">
Position du composant sur l'axe des ordonnées en pixels.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.left"></a><span class="access">public</span> <span class="type">int</span> <a href="Component.html#property.left"><span class="argument">$left</span></a><div class="description">
Position du composant sur l'axe des abscisses en pixels.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.background"></a><span class="access">protected</span> <span class="type">mixed</span> <a href="Component.html#property.background"><span class="argument">$background</span></a><div class="description">
Fond du composant. Peut être une <a href="Color.html">couleur</a>, un <a href="Gradient.html">dégradé</a> ou peut être laissé à NULL pour ne spécifier aucune couleur de fond.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.padding"></a><span class="access">public</span> <a href="Side.html"><span class="type">Side</span></a> <a href="Component.html#property.padding"><span class="argument">$padding</span></a><div class="description">
Espace interne du composant.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.space"></a><span class="access">public</span> <a href="Side.html"><span class="type">Side</span></a> <a href="Component.html#property.space"><span class="argument">$space</span></a><div class="description">
Espace interne dans la zone de dessin effective du composant. Les valeurs doivent être données en pourcentage de la taille de la zone de dessin.
Le zone de dessin est la zone dans laquelle est dessiné le composant, c'est-à-dire la zone du composant amputée des axes et de l'<a href="Component.html#property.padding">espace interne</a>.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.auto"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Component.html#property.auto"><span class="argument">$auto</span></a><div class="description">
Doit-on ajuster automatiquement le composant ?
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.title"></a><span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="Component.html#property.title"><span class="argument">$title</span></a><div class="description">
Le titre du composant.
Si un titre est spécifié, il sera affiché sur l'image.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.legend"></a><span class="access">public</span> <a href="Legend.html"><span class="type">Legend</span></a> <a href="Component.html#property.legend"><span class="argument">$legend</span></a><div class="description">
La légende associée au composant.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Component.html#method.__construct">__construct</a>()
<div class="description">
Construit le composant en lui affectant une taille égale à celle de l'image et en le positionnant au centre de cette image.
Le composant remplit donc toute la surface de l'image.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.auto"></a><span class="access">public</span> <a href="Component.html#method.auto">auto</a>(<span class="type">bool</span> <span class="argument">$auto</span>)
<div class="description">
TRUE si le composant doit être automatiquement ajusté, FALSE sinon.
La notion d'ajustage automatique est propre à chaque classe qui dérive de celle-ci.
Par exemple, sur les histogrammes, si le composant n'est pas automatiquement ajusté, alors les barres ne seront pas centrées sur zéro mais sur leur valeur minimum.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSize"></a><span class="access">public</span> <a href="Component.html#method.setSize">setSize</a>(<span class="type">float</span> <span class="argument">$width</span>, <span class="type">float</span> <span class="argument">$height</span>)
<div class="description">
Change la largeur $width et la hauteur $height du composant.
Les nouvelles valeurs doivent être comprises entre 0 et 1 et correspondent à une fraction des largeur et hauteur de l'image à laquelle le composant appartient.
<pre>
 
&lt;?php
 
require_once "LinePlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
// LinePLot dérive de Component
$plot = new <a href="LinePlot.html">LinePlot</a>(array(1, 2, 3));
 
// Le taille du composant sera 1 / 3 de celle de l'image, soit 133x133 pixels
$plot-&gt;<a href="Component.html#method.setSize">setSize</a>(1 / 3, 1 / 3);
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAbsSize"></a><span class="access">public</span> <a href="Component.html#method.setAbsSize">setAbsSize</a>(<span class="type">int</span> <span class="argument">$w</span>, <span class="type">int</span> <span class="argument">$h</span>)
<div class="description">
Donne une taille absolue au composant.
La largeur $width et la hauteur $height doivent être données en pixels.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundColor"></a><span class="access">public</span> <a href="Component.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de fond du composant.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundGradient"></a><span class="access">public</span> <a href="Component.html#method.setBackgroundGradient">setBackgroundGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
<div class="description">
Change le dégradé de fond du composant.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundImage"></a><span class="access">public</span> <a href="Component.html#method.setBackgroundImage">setBackgroundImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
<div class="description">
Change l'image de fond du composant.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getBackground"></a><span class="access">public</span> <span class="type">mixed</span> <a href="Component.html#method.getBackground">getBackground</a>(<span class="type">int</span> <span class="argument">$type</span>)
<div class="description">
Retourne le fond de l'image. Cela peut être une <a href="Color.html">couleur</a>, un <a href="Gradient.html">dégradé</a> ou encore une <a href="Image.html">image</a>. Si aucun fond n'a été spécifié, cette méthode retourne NULL.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setPadding"></a><span class="access">public</span> <a href="Component.html#method.setPadding">setPadding</a>(<span class="type">int</span> <span class="argument">$left</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$right</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$top</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$bottom</span> := <span class="default">NULL</span>)
<div class="description">
Change l'espace interne du composant.
Les valeurs doivent être données en pixels.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSpace"></a><span class="access">public</span> <a href="Component.html#method.setSpace">setSpace</a>(<span class="type">int</span> <span class="argument">$left</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$right</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$top</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$bottom</span> := <span class="default">NULL</span>)
<div class="description">
Change l'espace interne dans la zone de dessin effective du composant. Les valeurs doivent être données en pourcentage de la taille de la zone de dessin.
Le zone de dessin est la zone dans laquelle est dessiné le composant, c'est-à-dire la zone du composant amputée des axes et de l'<a href="Component.html#property.padding">espace interne</a>.
<pre>
 
&lt;?php
 
require_once "LinePlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
$plot = new <a href="LinePlot.html">LinePlot</a>(array(43, 23, 65, 37));
$plot-&gt;<a href="Component.html#method.setSpace">setSpace</a>(10, 10, 20, 20);
 
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setCenter"></a><span class="access">public</span> <a href="Component.html#method.setCenter">setCenter</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
<div class="description">
Change la position du centre du composant sur l'image.
Les nouvelles positions $x et $y représentent une fraction des largeur et hauteur de l'image.
Attention, la position 0 pour $y place le centre du composant en haut de l'image. La position 1 le place en bas de l'image.
<pre>
 
&lt;?php
 
require_once "LinePlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
// LinePLot dérive de Component
$plot = new <a href="LinePlot.html">LinePlot</a>(array(1, 2, 3));
 
// Le taille du composant sera 1 / 3 de celle de l'image, soit 133x133 pixels
$plot-&gt;<a href="Component.html#method.setSize">setSize</a>(1 / 3, 1 / 3);
// Place le composant en haut à gauche
$plot-&gt;<a href="Component.html#method.setCenter">setCenter</a>(1 / 6, 1 / 6);
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAbsPosition"></a><span class="access">public</span> <a href="Component.html#method.setAbsPosition">setAbsPosition</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$top</span>)
<div class="description">
Change la position du composant sur l'image.
Contrairement à <a href="Component.html#method.setCenter">setCenter()</a>, cette méthode ne place pas le composant par rapport à son centre, mais par rapport à son coin haut-gauche. Les positions $left à gauche et $top pour la hauteur doivent être données en pixels.
Attention, la position 0 pour $top place le composant en haut de l'image.
<pre>
 
&lt;?php
 
require_once "LinePlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
// LinePLot dérive de Component
$plot = new <a href="LinePlot.html">LinePlot</a>(array(1, 2, 3));
 
// Le taille du composant sera 1 / 3 de celle de l'image, soit 133x133 pixels
$plot-&gt;<a href="Component.html#method.setSize">setSize</a>(1 / 3, 1 / 3);
// Place le composant en haut à gauche
$plot-&gt;<a href="Component.html#method.setAbsPosition">setAbsPosition</a>(0, 0);
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.init"></a><span class="access">public</span> <a href="Component.html#method.init">init</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
<div class="description">
Initialise le composant avant son affichage.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.finalize"></a><span class="access">public</span> <a href="Component.html#method.finalize">finalize</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
<div class="description">
Finalize l'affichage du composant.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getPosition"></a><span class="access">abstract public</span> <span class="type">array</span> <a href="Component.html#method.getPosition">getPosition</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
<div class="description">
Retourne la position de la zone de dessin effective du composant.
Les coordonnées doivent être retournées sous la forme d'un tableau de quatre valeurs.
Les première et deuxième valeurs sont les positions en abscisse et en ordonnée du coin haut-gauche de la zone de dessin.
Les troisième et quatrième valeurs sont les positions en abscisse et en ordonnée du coin bas-droit de la zone de dessin.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.drawEnvelope"></a><span class="access">abstract public</span> <a href="Component.html#method.drawEnvelope">drawEnvelope</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>)
<div class="description">
Dessine l'enveloppe autour de la zone de dessin effective du composant.
Cette enveloppe comprend généralement les axes et la grille du composant.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.drawComponent"></a><span class="access">abstract public</span> <a href="Component.html#method.drawComponent">drawComponent</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <span class="type">int</span> <span class="argument">$x1</span>, <span class="type">int</span> <span class="argument">$y1</span>, <span class="type">int</span> <span class="argument">$x2</span>, <span class="type">int</span> <span class="argument">$y2</span>, <span class="type">bool</span> <span class="argument">$aliasing</span>)
<div class="description">
Dessine effectivement le composant, c'est-à-dire le graphique.
Le paramètre $aliasing est à TRUE si l'anti-aliasing est activé, FALSE sinon.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getSpace"></a><span class="access">protected</span> <a href="Component.html#method.getSpace">getSpace</a>(<span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
<div class="description">
Convertit l'espace interne du composant de pourcentages en pixels, en fonction de la taille $width et de la hauteur $height, exprimées en pixels.
</div>
<div class="description-bottom"><a href="Component.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Vector.html
New file
0,0 → 1,48
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Vector</h2><div class="extends"><ul>
<li><a href="Shape.html">Shape</a></li>
<ul>
<li><a href="Line.html">Line</a></li>
<ul><li>Vector</li></ul>
</ul>
</ul></div><div class="description">
<p>
La classe <a href="Vector.html">Vector</a> permet de représenter un vecteur.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="methods"><li>
<span class="access">public</span> <span class="type">float</span> <a href="Vector.html#method.getAngle">getAngle</a>()
</li></ul><h2>Documentation</h2><ul class="doc"><li class="method">
<a id="method.getAngle"></a><span class="access">public</span> <span class="type">float</span> <a href="Vector.html#method.getAngle">getAngle</a>()
<div class="description">
Retourne l'angle du vecteur en radians.
</div>
<div class="description-bottom"><a href="Vector.html#top">Remonter</a></div>
</li></ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/BarPlot.html
New file
0,0 → 1,199
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class BarPlot</h2><div class="extends"><ul>
<li><a href="Component.html">Component</a></li>
<ul>
<li><a href="Plot.html">Plot</a></li>
<ul><li>BarPlot <span class="interface">implements</span> <a href="Legendable.html">Legendable</a>
</li></ul>
</ul>
</ul></div><div class="description">
<p>
Cette classe permet de dessiner des histogrammes.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="BarPlot.html#property.label"><span class="argument">$label</span></a>
</li>
<li>
<span class="access">public</span> <a href="Shadow.html"><span class="type">Shadow</span></a> <a href="BarPlot.html#property.barShadow"><span class="argument">$barShadow</span></a>
</li>
<li>
<span class="access">public</span> <a href="Border.html"><span class="type">Border</span></a> <a href="BarPlot.html#property.barBorder"><span class="argument">$barBorder</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="BarPlot.html#method.__construct">__construct</a>(<span class="type">array</span> <span class="argument">$values</span>, <span class="type">int</span> <span class="argument">$identifier</span> := <span class="default">1</span>, <span class="type">int</span> <span class="argument">$number</span> := <span class="default">1</span>, <span class="type">int</span> <span class="argument">$depth</span> := <span class="default">0</span>)
</li>
<li>
<span class="access">public</span> <a href="BarPlot.html#method.setBarPadding">setBarPadding</a>(<span class="type">float</span> <span class="argument">$left</span> := <span class="default">NULL</span>, <span class="type">float</span> <span class="argument">$right</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="BarPlot.html#method.setBarSize">setBarSize</a>(<span class="type">float</span> <span class="argument">$size</span>)
</li>
<li>
<span class="access">public</span> <a href="BarPlot.html#method.setBarSpace">setBarSpace</a>(<span class="type">int</span> <span class="argument">$space</span>)
</li>
<li>
<span class="access">public</span> <a href="BarPlot.html#method.setBarColor">setBarColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="BarPlot.html#method.setBarGradient">setBarGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
</li>
<li>
<span class="access">public</span> <a href="BarPlot.html#method.move">move</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.label"></a><span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="BarPlot.html#property.label"><span class="argument">$label</span></a><div class="description">
Représente les étiquettes affichées au-dessus de chaque barre de l'histogramme.
Ces étiquettes contiennent la valeur de chaque barre.
</div>
<div class="description-bottom"><a href="BarPlot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.barShadow"></a><span class="access">public</span> <a href="Shadow.html"><span class="type">Shadow</span></a> <a href="BarPlot.html#property.barShadow"><span class="argument">$barShadow</span></a><div class="description">
Représente l'ombre associée à chaque barre de l'histogramme.
</div>
<div class="description-bottom"><a href="BarPlot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.barBorder"></a><span class="access">public</span> <a href="Border.html"><span class="type">Border</span></a> <a href="BarPlot.html#property.barBorder"><span class="argument">$barBorder</span></a><div class="description">
La bordure à afficher autour de chaque barre de l'histogramme.
</div>
<div class="description-bottom"><a href="BarPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="BarPlot.html#method.__construct">__construct</a>(<span class="type">array</span> <span class="argument">$values</span>, <span class="type">int</span> <span class="argument">$identifier</span> := <span class="default">1</span>, <span class="type">int</span> <span class="argument">$number</span> := <span class="default">1</span>, <span class="type">int</span> <span class="argument">$depth</span> := <span class="default">0</span>)
<div class="description">
Créé un nouvel histogramme avec les valeurs présentes dans $values.
$number représente le nombre d'histogrammes affichés en parallèle tandis que $identifier permet de spécifier où se situe l'histogramme courant.
$depth représente la profondeur de l'histogramme en pixels.
Le tableau $values doit être une liste de valeurs dans un tableau incrémental, c'est-à-dire dont les clés valent de 0 à n - 1 (où n est la taille du tableau).
<pre>
 
&lt;?php
 
require_once "BarPlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
// Tableau de valeurs
$x = array(-19, 42, 31);
 
$plot = new <a href="BarPlot.html">BarPlot</a>($x);
$plot-&gt;<a href="Plot.html#method.setXAxisZero">setXAxisZero</a>(TRUE);
$plot-&gt;<a href="BarPlot.html#method.setBarColor">setBarColor</a>(
new <a href="Color.html">Color</a>(240, 185, 130, 20)
);
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="BarPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBarPadding"></a><span class="access">public</span> <a href="BarPlot.html#method.setBarPadding">setBarPadding</a>(<span class="type">float</span> <span class="argument">$left</span> := <span class="default">NULL</span>, <span class="type">float</span> <span class="argument">$right</span> := <span class="default">NULL</span>)
<div class="description">
Change l'espace interne de gauche et de droite sur chaque barre.
Laisser $left ou $right à NULL permet de ne pas modifier l'ancienne valeur.
Les valeurs données doivent être comprises entre 0 et 1 et représentent une fraction de l'espace réservé à chaque barre.
</div>
<div class="description-bottom"><a href="BarPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBarSize"></a><span class="access">public</span> <a href="BarPlot.html#method.setBarSize">setBarSize</a>(<span class="type">float</span> <span class="argument">$size</span>)
<div class="description">
Change la taille de chaque barre pour $size.
Les valeurs données doivent être comprises entre 0 et 1 et représentent une fraction de l'espace réservé à chaque barre.
</div>
<div class="description-bottom"><a href="BarPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBarSpace"></a><span class="access">public</span> <a href="BarPlot.html#method.setBarSpace">setBarSpace</a>(<span class="type">int</span> <span class="argument">$space</span>)
<div class="description">
Change l'espace entre les histogrammes affichés en parallèle pour $space.
</div>
<div class="description-bottom"><a href="BarPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBarColor"></a><span class="access">public</span> <a href="BarPlot.html#method.setBarColor">setBarColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur des barres de l'histogrammes.
</div>
<div class="description-bottom"><a href="BarPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBarGradient"></a><span class="access">public</span> <a href="BarPlot.html#method.setBarGradient">setBarGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
<div class="description">
Change le dégradé de fond des barres de l'histogramme.
Le dégradé de fond remplit le polygone définit par tous les points de la ligne additionés des points extrêmes de l'axe des abscisses.
<pre>
 
&lt;?php
 
require_once "BarPlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
$x = array(19, 30, 31, -42, 11);
 
$plot = new <a href="BarPlot.html">BarPlot</a>($x);
$plot-&gt;<a href="BarPlot.html#method.setBarGradient">setBarGradient</a>(
new <a href="LinearGradient.html">LinearGradient</a>(
new <a href="Color.html">Color</a>(255, 20, 20, 30),
new <a href="Color.html">Color</a>(20, 255, 20, 30),
90
)
);
 
$plot-&gt;<a href="Plot.html#method.setYMin">setYMin</a>(-100);
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="BarPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.move"></a><span class="access">public</span> <a href="BarPlot.html#method.move">move</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
<div class="description">
Déplace chaque barre de $x pixels sur l'horizontale et $y pixels sur la vertical avant le dessin.
</div>
<div class="description-bottom"><a href="BarPlot.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/BilinearGradient.html
New file
0,0 → 1,61
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class BilinearGradient</h2><div class="extends"><ul>
<li><a href="Gradient.html">Gradient</a></li>
<ul>
<li><a href="LinearGradient.html">LinearGradient</a></li>
<ul><li>BilinearGradient</li></ul>
</ul>
</ul></div><div class="description">
<p>
Cette classe permet de décrire un dégradé bilinéaire. Un dégradé bilinéaire à ceci de particulier par rapport au dégradé linéaire que son centre peut être décalé.
</p>
<p style="font-weight: bold">
ATTENTION, les dégradés bilinéaires sont en cours de développement et ne sont pas encore disponibles sur Artichow.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties"><li>
<span class="access">public</span> <span class="type">int</span> <a href="BilinearGradient.html#property.center"><span class="argument">$center</span></a>
</li></ul><ul class="methods"><li>
<span class="access">public</span> <a href="BilinearGradient.html#method.__construct">__construct</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$from</span>, <a href="Color.html"><span class="type">Color</span></a> <span class="argument">$to</span>, <span class="type">int</span> <span class="argument">$angle</span>, <span class="type">float</span> <span class="argument">$center</span> := <span class="default">0.5</span>)
</li></ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.center"></a><span class="access">public</span> <span class="type">int</span> <a href="BilinearGradient.html#property.center"><span class="argument">$center</span></a><div class="description">
Décrit la position du centre du dégradé. Cette valeur doit être comprise entre 0 et 1.
</div>
<div class="description-bottom"><a href="BilinearGradient.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="BilinearGradient.html#method.__construct">__construct</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$from</span>, <a href="Color.html"><span class="type">Color</span></a> <span class="argument">$to</span>, <span class="type">int</span> <span class="argument">$angle</span>, <span class="type">float</span> <span class="argument">$center</span> := <span class="default">0.5</span>)
<div class="description">
Construit une nouveu dégradé. Cette méthode doit être appelée par toutes les classes qui dérivent de celle-ci. Le paramètre $from décrit la couleur de départ du dégradé et le paramètre $to celle de fin. Le troisième paramètre $angle décrit l'angle du dégradé. Ce peut être un dégradé horizontal (angle de 0°) ou un dégradé vertical (angle de 90°). Le dernier paramètre doit être compris entre 0 et 1 permet de spécifier le centre du dégradé. Une valeur de 0.5 signifie que le dégradé sera symétrique.
</div>
<div class="description-bottom"><a href="BilinearGradient.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/PlotAxis.html
New file
0,0 → 1,79
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class PlotAxis</h2><div class="extends"><ul>
<li><a href="Component.html">Component</a></li>
<ul>
<li><a href="ComponentGroup.html">ComponentGroup</a></li>
<ul><li>PlotAxis</li></ul>
</ul>
</ul></div><div class="description">
<p>
La classe <a href="PlotAxis.html">PlotAxis</a> permet d'utiliser des axes sur les <a href="PlotGroup.html">PlotGroup</a>.
Quatre axes sont disponibles (gauche, bas, droite et haut).
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="PlotAxis.html#property.left"><span class="argument">$left</span></a>
</li>
<li>
<span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="PlotAxis.html#property.right"><span class="argument">$right</span></a>
</li>
<li>
<span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="PlotAxis.html#property.top"><span class="argument">$top</span></a>
</li>
<li>
<span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="PlotAxis.html#property.bottom"><span class="argument">$bottom</span></a>
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.left"></a><span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="PlotAxis.html#property.left"><span class="argument">$left</span></a><div class="description">
L'axe de gauche
</div>
<div class="description-bottom"><a href="PlotAxis.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.right"></a><span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="PlotAxis.html#property.right"><span class="argument">$right</span></a><div class="description">
L'axe de droite
</div>
<div class="description-bottom"><a href="PlotAxis.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.top"></a><span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="PlotAxis.html#property.top"><span class="argument">$top</span></a><div class="description">
L'axe du haut
</div>
<div class="description-bottom"><a href="PlotAxis.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.bottom"></a><span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="PlotAxis.html#property.bottom"><span class="argument">$bottom</span></a><div class="description">
L'axe du bas
</div>
<div class="description-bottom"><a href="PlotAxis.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/ScatterPlot.html
New file
0,0 → 1,164
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class ScatterPlot</h2><div class="extends"><ul>
<li><a href="Component.html">Component</a></li>
<ul>
<li><a href="Plot.html">Plot</a></li>
<ul><li>ScatterPlot <span class="interface">implements</span> <a href="Legendable.html">Legendable</a>
</li></ul>
</ul>
</ul></div><div class="description">
<p>
Les ScatterPlot (ou graphiques libres) permettent de dessiner des points aux coordonnées (x, y) sur une image.
Ce type de graphique est plus pluissant que les <a href="LinePlot.html">LinePlot</a> car plusieurs points de même abscisse peuvent être placés sur le même graphique.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <a href="Mark.html"><span class="type">Mark</span></a> <a href="ScatterPlot.html#property.mark"><span class="argument">$mark</span></a>
</li>
<li>
<span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="ScatterPlot.html#property.label"><span class="argument">$label</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="ScatterPlot.html#method.__construct">__construct</a>(<span class="type">array</span> <span class="argument">$datay</span>, <span class="type">array</span> <span class="argument">$datax</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="ScatterPlot.html#method.setImpulse">setImpulse</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="ScatterPlot.html#method.link">link</a>(<span class="type">bool</span> <span class="argument">$link</span>)
</li>
<li>
<span class="access">public</span> <a href="ScatterPlot.html#method.linkNull">linkNull</a>(<span class="type">bool</span> <span class="argument">$linkNull</span>)
</li>
<li>
<span class="access">public</span> <a href="ScatterPlot.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="ScatterPlot.html#method.setStyle">setStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
</li>
<li>
<span class="access">public</span> <a href="ScatterPlot.html#method.setThickness">setThickness</a>(<span class="type">int</span> <span class="argument">$thickness</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.mark"></a><span class="access">public</span> <a href="Mark.html"><span class="type">Mark</span></a> <a href="ScatterPlot.html#property.mark"><span class="argument">$mark</span></a><div class="description">
Représente les marques affichées sur chaque point.
</div>
<div class="description-bottom"><a href="ScatterPlot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.label"></a><span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="ScatterPlot.html#property.label"><span class="argument">$label</span></a><div class="description">
Représente les étiquettes affichées au-dessus de chaque point.
Ces étiquettes ne sont pas affichées par défaut.
</div>
<div class="description-bottom"><a href="ScatterPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="ScatterPlot.html#method.__construct">__construct</a>(<span class="type">array</span> <span class="argument">$datay</span>, <span class="type">array</span> <span class="argument">$datax</span> := <span class="default">NULL</span>)
<div class="description">
Créé un nouveau ScatterPlot avec des points d'abscisses $datax et d'ordonnées $datay.
Si la valeur $datax est laissée à NULL, alors la librairie utilisera des valeurs incrémentales pour X, en commençant par zéro.
<pre>
 
&lt;?php
 
require_once "ScatterPlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
// Tableaux de valeurs
$y = array(2, 4, 6);
$x = array(1, 4, 3);
 
// On dessine les points (1, 2), (4, 4) et (3, 6)
$plot = new <a href="ScatterPlot.html">ScatterPlot</a>($y, $x);
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="ScatterPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setImpulse"></a><span class="access">public</span> <a href="ScatterPlot.html#method.setImpulse">setImpulse</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Si vous appelez cette méthode, les points de la courbe seront reliés à l'axe des abscisses par des segments de droite verticaux de couleur $color.
Cette méthode permet notamment de représenter des graphiques à impulsions.
</div>
<div class="description-bottom"><a href="ScatterPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.link"></a><span class="access">public</span> <a href="ScatterPlot.html#method.link">link</a>(<span class="type">bool</span> <span class="argument">$link</span>)
<div class="description">
Permet de lier les points du graphique entre eux.
</div>
<div class="description-bottom"><a href="ScatterPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.linkNull"></a><span class="access">public</span> <a href="ScatterPlot.html#method.linkNull">linkNull</a>(<span class="type">bool</span> <span class="argument">$linkNull</span>)
<div class="description">
Si $linkNull vaut TRUE, alors les valeurs en ordonnée égales à nulles n'interrompront pas le lien entre tous les points.
A l'inverse, si $linkNull vaut FALSE, alors le lien sera rompu à chaque fois qu'une valeur égale à NULL sera trouvée.
Cette méthode n'a de sens que lorsque vous avez choisi de relier les points entre eux.
<div class="see">
Voir aussi :
<ul><li><a href="ScatterPlot.html#method.link">ScatterPlot::link()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="ScatterPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColor"></a><span class="access">public</span> <a href="ScatterPlot.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de la ligne qui relie les points du composant entre eux.
</div>
<div class="description-bottom"><a href="ScatterPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setStyle"></a><span class="access">public</span> <a href="ScatterPlot.html#method.setStyle">setStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
<div class="description">
Change le style de ligne (<a href="Line.html#constant.SOLID">Line::SOLID</a>, <a href="Line.html#constant.DOTTED">Line::DOTTED</a> ou <a href="Line.html#constant.DASHED">Line::DASHED</a>) qui relie chaque point.
</div>
<div class="description-bottom"><a href="ScatterPlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setThickness"></a><span class="access">public</span> <a href="ScatterPlot.html#method.setThickness">setThickness</a>(<span class="type">int</span> <span class="argument">$thickness</span>)
<div class="description">
Change l'épaisseur de la ligne qui relie les points du composant entre eux.
L'épaisseur de la ligne doit être toujours positive.
</div>
<div class="description-bottom"><a href="ScatterPlot.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/index.html
New file
0,0 → 1,138
<html>
<head>
<title>Documentation</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="style.css" />
</head>
 
<body>
<div align='center'>
<table cellpadding="0" cellspacing="0" id="contenu" class="round" style='width: 80%; margin-bottom: 20px'>
<tr>
<td class="borderhg">&nbsp;</td>
<td class="borderh">&nbsp;</td>
<td class="cornerhd"></td>
</tr>
<tr>
<td class="borderg">&nbsp;</td>
<td>
<h2>La documentation de Artichow</h2>
<p>
Cette documentation vous explique comment utiliser les classes de Artichow.
Vous retrouverez sur le site de Artichow une <a href="http://www.artichow.org/documentation">documentation plus complète</a>, ainsi que des <a href="http://www.artichow.org/tutorial">tutoriels</a>.
Attention, cette documentation est conçue pour la version <em>PHP 5</em> de Artichow, qui est incompatible avec la version <em>PHP 4 &amp; 5</em>.
Vous pouvez retrouver sur le site une <a href="http://www.artichow.org/incompatibility">liste de ces incompatibilités</a> afin de pouvoir utiliser tout de même cette documentation.
</p>
 
<h2>Les classes de Artichow</h2>
 
<h4>Classes de traitement de l'image</h4>
<ul class='list'>
<li>
<a href='Image.html'>Image</a>
<ul>
<li><a href='Graph.html'>Graph</a></li>
<li><a href='FileImage.html'>FileImage</a></li>
</ul>
</li>
<li><a href='Pattern.html'>Pattern</a></li>
</ul>
 
<h4>Classes de traitement des composants</h4>
<ul class='list'>
<li><a href='AntiSpam.html'>AntiSpam</a></li>
<li>
<a href='Component.html'>Component</a>
<ul>
<li>
<a href='ComponentGroup.html'>ComponentGroup</a>
<ul>
<li><a href='PlotGroup.html'>PlotGroup</a></li>
</ul>
</li>
<li><a href='MathPlot.html'>MathPlot</a> (voir aussi <a href='MathFunction.html'>MathFunction</a>)</li>
<li>
<a href='Plot.html'>Plot</a>
<ul>
<li><a href='LinePlot.html'>LinePlot</a></li>
<li><a href='BarPlot.html'>BarPlot</a></li>
<li><a href='ScatterPlot.html'>ScatterPlot</a></li>
</ul>
</li>
<li><a href='Pie.html'>Pie</a></li>
</ul>
</li>
</ul>
 
<h4>Classe graphique</h4>
<ul class='list'>
<li><a href='Drawer.html'>Drawer</a></li>
</ul>
 
<h4>Classes de dessin</h4>
<ul class='list'>
<li><a href='Color.html'>Color</a></li>
<li>
<a href='Gradient.html'>Gradient</a>
<ul>
<li>
<a href='RadialGradient.html'>RadialGradient</a>
<ul>
<li><a href='BilinearGradient.html'>BilinearGradient</a></li>
</ul>
</li>
<li><a href='LinearGradient.html'>LinearGradient</a></li>
</ul>
</li>
<li>
<a href='Font.html'>Font</a>
<ul>
<li><a href='TTFFont.html'>TTFFont</a></li>
</ul>
</li>
<li><a href='Text.html'>Text</a></li>
</ul>
 
<h4>Classes pour le traitement géométrique</h4>
<ul class='list'>
<li>
<a href='Shape.html'>Shape</a>
<ul>
<li><a href='Point.html'>Point</a></li>
<li>
<a href='Line.html'>Line</a>
<ul>
<li><a href='Vector.html'>Vector</a></li>
</ul>
</li>
<li><a href='Polygon.html'>Polygon</a></li>
</ul>
</li>
</ul>
 
<h4>Outils d'aide au dessin</h4>
<ul class='list'>
<li><a href='Axis.html'>Axis</a></li>
<li><a href='Grid.html'>Grid</a></li>
<li><a href='Border.html'>Border</a></li>
<li><a href='Label.html'>Label</a></li>
<li><a href='Legend.html'>Legend</a></li>
<li><a href='Mark.html'>Mark</a></li>
<li><a href='Shadow.html'>Shadow</a></li>
<li><a href='Side.html'>Side</a></li>
<li><a href='Tick.html'>Tick</a></li>
</ul>
 
</td>
<td class="borderd">&nbsp;</td>
</tr>
<tr>
<td class="cornerbg"></td>
<td class="borderb">&nbsp;</td>
<td class="cornerbd"></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/RadialGradient.html
New file
0,0 → 1,35
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class RadialGradient</h2><div class="extends"><ul>
<li><a href="Gradient.html">Gradient</a></li>
<ul><li>RadialGradient</li></ul>
</ul></div><div class="description">
<p>Cette classe permet de décrire un dégradé radial.</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><h2>Documentation</h2><ul class="doc"></ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/AntiSpam.html
New file
0,0 → 1,137
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class AntiSpam</h2><div class="extends"><ul>
<li><a href="Image.html">Image</a></li>
<ul><li>AntiSpam</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="AntiSpam.html">AntiSpam</a> permet de créer des images pour interdire des requêtes automatisées sur certaines pages.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">protected</span> <span class="type">string</span> <a href="AntiSpam.html#property.string"><span class="argument">$string</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">int</span> <a href="AntiSpam.html#property.noise"><span class="argument">$noise</span></a> := <span class="default">0</span>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="AntiSpam.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$string</span> := <span class="default">''</span>)
</li>
<li>
<span class="access">public</span> <span class="type">string</span> <a href="AntiSpam.html#method.setRand">setRand</a>(<span class="type">int</span> <span class="argument">$length</span>)
</li>
<li>
<span class="access">public</span> <a href="AntiSpam.html#method.setNoise">setNoise</a>(<span class="type">int</span> <span class="argument">$noise</span>)
</li>
<li>
<span class="access">public</span> <a href="AntiSpam.html#method.save">save</a>(<span class="type">string</span> <span class="argument">$qName</span>)
</li>
<li>
<span class="access">public</span> <a href="AntiSpam.html#method.check">check</a>(<span class="type">string</span> <span class="argument">$qName</span>, <span class="type">string</span> <span class="argument">$value</span>, <span class="type">bool</span> <span class="argument">$case</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="AntiSpam.html#method.draw">draw</a>()
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.string"></a><span class="access">protected</span> <span class="type">string</span> <a href="AntiSpam.html#property.string"><span class="argument">$string</span></a><div class="description">
La chaîne de caractère que devra retaper l'utilisateur.
</div>
<div class="description-bottom"><a href="AntiSpam.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.noise"></a><span class="access">protected</span> <span class="type">int</span> <a href="AntiSpam.html#property.noise"><span class="argument">$noise</span></a> := <span class="default">0</span><div class="description">
Degré de bruit à afficher sur l'image (entre 0 et 10).
</div>
<div class="description-bottom"><a href="AntiSpam.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="AntiSpam.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$string</span> := <span class="default">''</span>)
<div class="description">
Construit une image anti-spam. Vous pouvez définir la chaîne de caractères à afficher sur l'image avec $string.
Si vous ne donnez aucune chaîne de caractères, voyez <a href="AntiSpam.html#method.setRand">AntiSpam::setRand()</a> pour générer une valeur aléatoire.
</div>
<div class="description-bottom"><a href="AntiSpam.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setRand"></a><span class="access">public</span> <span class="type">string</span> <a href="AntiSpam.html#method.setRand">setRand</a>(<span class="type">int</span> <span class="argument">$length</span>)
<div class="description">
Génère une chaîne de caractère aléatoire de taille $length pour l'image anti-spam.
La chaîne de caractère ainsi créée est ensuite retournée.
</div>
<div class="description-bottom"><a href="AntiSpam.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setNoise"></a><span class="access">public</span> <a href="AntiSpam.html#method.setNoise">setNoise</a>(<span class="type">int</span> <span class="argument">$noise</span>)
<div class="description">
Ajoute du bruit sur l'image.
Les valeurs possibles sont de 0 à 10, avec 0 pour ne pas afficher de bruit et 10 pour afficher un bruit maximal.
</div>
<div class="description-bottom"><a href="AntiSpam.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.save"></a><span class="access">public</span> <a href="AntiSpam.html#method.save">save</a>(<span class="type">string</span> <span class="argument">$qName</span>)
<div class="description">
Enregistre la valeur de l'image anti-spam dans la session de l'utilisateur sous le nom $qName.
Cette méthode doit être utilisée en combinaison avec <a href="AntiSpam.html#method.check">AntiSpam::check()</a>.
</div>
<div class="description-bottom"><a href="AntiSpam.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.check"></a><span class="access">public</span> <a href="AntiSpam.html#method.check">check</a>(<span class="type">string</span> <span class="argument">$qName</span>, <span class="type">string</span> <span class="argument">$value</span>, <span class="type">bool</span> <span class="argument">$case</span> := <span class="default">TRUE</span>)
<div class="description">
Vérifie que la valeur $value correspond à la valeur enregistrée sous le nom $qName avec <a href="AntiSpam.html#method.save">AntiSpam::save()</a>.
Si $case est mis à TRUE, alors la vérification NE sera PAS sensible à la casse, elle le sera à FALSE.
Cette méthode doit être utilisée en combinaison avec <a href="AntiSpam.html#method.save">AntiSpam::save()</a>.
</div>
<div class="description-bottom"><a href="AntiSpam.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.draw"></a><span class="access">public</span> <a href="AntiSpam.html#method.draw">draw</a>()
<div class="description">
Affiche l'image anti-spam à l'écran.
<pre>
 
&lt;?php
 
require_once "AntiSpam.class.php";
 
$object = new <a href="AntiSpam.html">AntiSpam</a>();
$object-&gt;<a href="AntiSpam.html#method.setRand">setRand</a>(5);
$object-&gt;<a href="AntiSpam.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="AntiSpam.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Pattern.html
New file
0,0 → 1,40
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Pattern</h2><div class="description">
<p>
La classe <a href="Pattern.html">Pattern</a> simplifie la création de graphiques avec Artichow.
</p>
<p style="color: red; font-weight: bold">
Cette partie de la documentation est encore en cours de réalisation.
Pour obtenir la liste des méthodes de cette classe, voyez le fichier Pattern.class.php.
Pour savoir comment utiliser cette classe, n'hésitez pas à aller jeter un coup d'oeil aux exemples (examples/pattern-*.php)
fournis avec l'archive de Artichow.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><h2>Documentation</h2><ul class="doc"></ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Pie.html
New file
0,0 → 1,233
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Pie</h2><div class="extends"><ul>
<li><a href="Component.html">Component</a></li>
<ul><li>Pie</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="Pie.html">Pie</a> permet de générer des camemberts en deux ou trois dimensions.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Pie.html#constant.DARK">DARK</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Pie.html#constant.COLORED">COLORED</a> := <span class="default">2</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Pie.html#constant.AQUA">AQUA</a> := <span class="default">3</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Pie.html#constant.EARTH">EARTH</a> := <span class="default">4</span>
</li>
</ul><ul class="properties">
<li>
<span class="access">protected</span> <a href="Border.html"><span class="type">Border</span></a> <a href="Pie.html#property.border"><span class="argument">$border</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Pie.html#property.values"><span class="argument">$values</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Pie.html#property.colors"><span class="argument">$colors</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Pie.html#method.__construct">__construct</a>(<span class="type">array</span> <span class="argument">$values</span>, <span class="type">mixed</span> <span class="argument">$colors</span> := <span class="default">Pie::COLORED</span>)
</li>
<li>
<span class="access">public</span> <a href="Pie.html#method.setLegend">setLegend</a>(<span class="type">array</span> <span class="argument">$legend</span>)
</li>
<li>
<span class="access">public</span> <a href="Pie.html#method.setBorder">setBorder</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Pie.html#method.setBorderColor">setBorderColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Pie.html#method.set3D">set3D</a>(<span class="type">int</span> <span class="argument">$size</span>)
</li>
<li>
<span class="access">public</span> <a href="Pie.html#method.setStartAngle">setStartAngle</a>(<span class="type">int</span> <span class="argument">$angle</span>)
</li>
<li>
<span class="access">public</span> <a href="Pie.html#method.setLabelPrecision">setLabelPrecision</a>(<span class="type">int</span> <span class="argument">$precision</span>)
</li>
<li>
<span class="access">public</span> <a href="Pie.html#method.setLabelPosition">setLabelPosition</a>(<span class="type">int</span> <span class="argument">$position</span>)
</li>
<li>
<span class="access">public</span> <a href="Pie.html#method.setLabelNumber">setLabelNumber</a>(<span class="type">int</span> <span class="argument">$number</span>)
</li>
<li>
<span class="access">public</span> <a href="Pie.html#method.setLabelMinimum">setLabelMinimum</a>(<span class="type">int</span> <span class="argument">$minimum</span>)
</li>
<li>
<span class="access">public</span> <a href="Pie.html#method.explode">explode</a>(<span class="type">array</span> <span class="argument">$explode</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.DARK"></a><span class="access">const</span> <span class="type">int</span> <a href="Pie.html#constant.DARK">DARK</a> := <span class="default">1</span><div class="description">
Un thème sombre pour les camemberts.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.COLORED"></a><span class="access">const</span> <span class="type">int</span> <a href="Pie.html#constant.COLORED">COLORED</a> := <span class="default">2</span><div class="description">
Un thème coloré pour les camemberts (thème par défaut).
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.AQUA"></a><span class="access">const</span> <span class="type">int</span> <a href="Pie.html#constant.AQUA">AQUA</a> := <span class="default">3</span><div class="description">
Un thème plutôt bleu pour les camemberts.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.EARTH"></a><span class="access">const</span> <span class="type">int</span> <a href="Pie.html#constant.EARTH">EARTH</a> := <span class="default">4</span><div class="description">
Un thème aux couleurs de la Terre pour les camemberts.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.border"></a><span class="access">protected</span> <a href="Border.html"><span class="type">Border</span></a> <a href="Pie.html#property.border"><span class="argument">$border</span></a><div class="description">
La bordure qui entoure chaque part du camembert.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.values"></a><span class="access">public</span> <span class="type">array</span> <a href="Pie.html#property.values"><span class="argument">$values</span></a><div class="description">
Les valeurs du camembert.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.colors"></a><span class="access">public</span> <span class="type">array</span> <a href="Pie.html#property.colors"><span class="argument">$colors</span></a><div class="description">
Les couleurs des parts du camembert.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Pie.html#method.__construct">__construct</a>(<span class="type">array</span> <span class="argument">$values</span>, <span class="type">mixed</span> <span class="argument">$colors</span> := <span class="default">Pie::COLORED</span>)
<div class="description">
Construit un nouveau camembert avec comme valeurs $values.
Le paramètre $colors peut soit être un tableau de couleurs, soit un thème prédéfini (<a href="Pie.html#constant.DARK">Pie::DARK</a>, <a href="Pie.html#constant.COLORED">Pie::COLORED</a>, <a href="Pie.html#constant.AQUA">Pie::AQUA</a> ou <a href="Pie.html#constant.EARTH">Pie::EARTH</a>).
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLegend"></a><span class="access">public</span> <a href="Pie.html#method.setLegend">setLegend</a>(<span class="type">array</span> <span class="argument">$legend</span>)
<div class="description">
Change les valeurs de la légende associée au camembert.
$legend est un tableau qui contient autant d'entrées que de valeurs présentes sur le camembert.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBorder"></a><span class="access">public</span> <a href="Pie.html#method.setBorder">setBorder</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<ul class="version"><li>
Déprécié depuis Artichow 1.0.9</li></ul>
<div class="description">
Change la couleur de la bordure entourant le camembert et séparant chaque part.
Cette méthode a été remplacée par Pie::setBorderColor() depuis Artichow 1.0.9.
<div class="see">
Voir aussi :
<ul><li><a href="Pie.html#method.setBorderColor">Pie::setBorderColor()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBorderColor"></a><span class="access">public</span> <a href="Pie.html#method.setBorderColor">setBorderColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Change la couleur de la bordure entourant le camembert et séparant chaque part.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.set3D"></a><span class="access">public</span> <a href="Pie.html#method.set3D">set3D</a>(<span class="type">int</span> <span class="argument">$size</span>)
<div class="description">
Associe au camembert à un effet 3D de taille $size (à spécifier en pixels).
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setStartAngle"></a><span class="access">public</span> <a href="Pie.html#method.setStartAngle">setStartAngle</a>(<span class="type">int</span> <span class="argument">$angle</span>)
<div class="description">
Angle initial en degrés pour commencer le dessin du camembert.
La valeur par défaut est de 0°.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLabelPrecision"></a><span class="access">public</span> <a href="Pie.html#method.setLabelPrecision">setLabelPrecision</a>(<span class="type">int</span> <span class="argument">$precision</span>)
<div class="description">
Change la précision des étiquettes associées à chaque part du camembert.
Par défaut à 0, cette précision donne le nombre de chiffres après la virgule à afficher.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLabelPosition"></a><span class="access">public</span> <a href="Pie.html#method.setLabelPosition">setLabelPosition</a>(<span class="type">int</span> <span class="argument">$position</span>)
<div class="description">
Change la distance des étiquettes par rapport au camembert.
La valeur est à donner en pixels et vaut par défaut 15 pixels.
Elle peut également être négative.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLabelNumber"></a><span class="access">public</span> <a href="Pie.html#method.setLabelNumber">setLabelNumber</a>(<span class="type">int</span> <span class="argument">$number</span>)
<div class="description">
Permet de choisir le nombre maximale d'étiquettes à afficher autour du camembert.
Par défaut, toutes les étiquettes sont affichées.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLabelMinimum"></a><span class="access">public</span> <a href="Pie.html#method.setLabelMinimum">setLabelMinimum</a>(<span class="type">int</span> <span class="argument">$minimum</span>)
<div class="description">
Permet de choisir une valeur minimum pour l'affichage des étiquettes.
Tout part dont le pourcentage sera inférieur à $minimum n'aura aucune étiquette associée.
Par défaut, il n'y a aucun minimum.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.explode"></a><span class="access">public</span> <a href="Pie.html#method.explode">explode</a>(<span class="type">array</span> <span class="argument">$explode</span>)
<div class="description">
Cette méthode permet de séparer une ou plusieurs parts du camembert.
Le paramètre $explode est un tableau dont les clés représente les numéros des parts à séparer et les valeurs la distance de séparation.
</div>
<div class="description-bottom"><a href="Pie.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Plot.html
New file
0,0 → 1,316
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Plot</h2><div class="extends"><ul>
<li><a href="Component.html">Component</a></li>
<ul><li>Plot</li></ul>
</ul></div><div class="description">
<p>
Cette classe est la base des <a href="LinePlot.html">courbes</a> et <a href="BarPlot.html">histogrammes</a> sur Artichow.
</p>
</div><div class="inherit">
Les classes suivantes dérivent de Plot :
<ul>
<li><a href="LinePlot.html">LinePlot</a></li>
<li><a href="BarPlot.html">BarPlot</a></li>
<li><a href="ScatterPlot.html">ScatterPlot</a></li>
</ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">string</span> <a href="Plot.html#constant.LEFT">LEFT</a> := <span class="default">left</span>
</li>
<li>
<span class="access">const</span> <span class="type">string</span> <a href="Plot.html#constant.RIGHT">RIGHT</a> := <span class="default">right</span>
</li>
<li>
<span class="access">const</span> <span class="type">string</span> <a href="Plot.html#constant.TOP">TOP</a> := <span class="default">top</span>
</li>
<li>
<span class="access">const</span> <span class="type">string</span> <a href="Plot.html#constant.BOTTOM">BOTTOM</a> := <span class="default">bottom</span>
</li>
<li>
<span class="access">const</span> <span class="type">string</span> <a href="Plot.html#constant.BOTH">BOTH</a> := <span class="default">both</span>
</li>
</ul><ul class="properties">
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Plot.html#property.datay"><span class="argument">$datay</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Plot.html#property.datax"><span class="argument">$datax</span></a>
</li>
<li>
<span class="access">public</span> <a href="Grid.html"><span class="type">Grid</span></a> <a href="Plot.html#property.grid"><span class="argument">$grid</span></a>
</li>
<li>
<span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="Plot.html#property.xAxis"><span class="argument">$xAxis</span></a>
</li>
<li>
<span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="Plot.html#property.yAxis"><span class="argument">$yAxis</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Plot.html#property.xAxisZero"><span class="argument">$xAxisZero</span></a> := <span class="default">TRUE</span>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Plot.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="Plot.html#method.reduce">reduce</a>(<a href="number.html"><span class="type">number</span></a> <span class="argument">$number</span>)
</li>
<li>
<span class="access">public</span> <a href="Plot.html#method.setXAxis">setXAxis</a>(<span class="type">string</span> <span class="argument">$axis</span>)
</li>
<li>
<span class="access">public</span> <a href="Plot.html#method.setYAxis">setYAxis</a>(<span class="type">string</span> <span class="argument">$axis</span>)
</li>
<li>
<span class="access">public</span> <a href="Plot.html#method.setXAxisZero">setXAxisZero</a>(<span class="type">bool</span> <span class="argument">$zero</span>)
</li>
<li>
<span class="access">public</span> <a href="Plot.html#method.setYAxisZero">setYAxisZero</a>(<span class="type">bool</span> <span class="argument">$zero</span>)
</li>
<li>
<span class="access">public</span> <a href="Plot.html#method.setYMin">setYMin</a>(<span class="type">float</span> <span class="argument">$value</span>)
</li>
<li>
<span class="access">public</span> <a href="Plot.html#method.setYMax">setYMax</a>(<span class="type">float</span> <span class="argument">$value</span>)
</li>
<li>
<span class="access">public</span> <a href="Plot.html#method.setXMin">setXMin</a>(<span class="type">float</span> <span class="argument">$value</span>)
</li>
<li>
<span class="access">public</span> <a href="Plot.html#method.setXMax">setXMax</a>(<span class="type">float</span> <span class="argument">$value</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.LEFT"></a><span class="access">const</span> <span class="type">string</span> <a href="Plot.html#constant.LEFT">LEFT</a> := <span class="default">left</span><div class="description">
Dessine l'axe des abscisses sur la gauche du graph.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.RIGHT"></a><span class="access">const</span> <span class="type">string</span> <a href="Plot.html#constant.RIGHT">RIGHT</a> := <span class="default">right</span><div class="description">
Dessine l'axe des abscisses sur la droite du graph.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.TOP"></a><span class="access">const</span> <span class="type">string</span> <a href="Plot.html#constant.TOP">TOP</a> := <span class="default">top</span><div class="description">
Dessine l'axe des ordonnées sur le haut du graph.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.BOTTOM"></a><span class="access">const</span> <span class="type">string</span> <a href="Plot.html#constant.BOTTOM">BOTTOM</a> := <span class="default">bottom</span><div class="description">
Dessine l'axe des ordonnées sur le bas du graph.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.BOTH"></a><span class="access">const</span> <span class="type">string</span> <a href="Plot.html#constant.BOTH">BOTH</a> := <span class="default">both</span><div class="description">
Dessine l'axe des abscisses (ou des ordonnées) sur la gauche et la droite (ou le haut et la bas) du graph.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.datay"></a><span class="access">public</span> <span class="type">array</span> <a href="Plot.html#property.datay"><span class="argument">$datay</span></a><div class="description">
Les valeurs de l'axe des Y.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.datax"></a><span class="access">public</span> <span class="type">array</span> <a href="Plot.html#property.datax"><span class="argument">$datax</span></a><div class="description">
Les valeurs de l'axe des X.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.grid"></a><span class="access">public</span> <a href="Grid.html"><span class="type">Grid</span></a> <a href="Plot.html#property.grid"><span class="argument">$grid</span></a><div class="description">
Représente la grille de fond du composant.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.xAxis"></a><span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="Plot.html#property.xAxis"><span class="argument">$xAxis</span></a><div class="description">
L'axe des abscisses
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.yAxis"></a><span class="access">public</span> <a href="Axis.html"><span class="type">Axis</span></a> <a href="Plot.html#property.yAxis"><span class="argument">$yAxis</span></a><div class="description">
L'axe des ordonnées
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.xAxisZero"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Plot.html#property.xAxisZero"><span class="argument">$xAxisZero</span></a> := <span class="default">TRUE</span><div class="description">
Est-ce le ou les axes des abscisses doivent être centrés sur zéro ?
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Plot.html#method.__construct">__construct</a>()
<div class="description">
Construit le composant.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.reduce"></a><span class="access">public</span> <a href="Plot.html#method.reduce">reduce</a>(<a href="number.html"><span class="type">number</span></a> <span class="argument">$number</span>)
<div class="description">
Réduit le nombre de valeurs à afficher sur le composant à $number.<br>
Cette fonctionnalité est utile dans le cas où vous souhaitez afficher plus de 400 ou 500 valeurs sur un graphique.
En effet, au delà d'un certain nombre de valeurs, toutes ne seront pas affichées et le temps de création du graphique sera très élevé.
La solution est de réduire le nombre de valeurs sur votre graphique, ce que permet cette fonction.
Le processus de réduction se fait à travers un système de moyennes, afin de garder une courbe identique à celle que vous auriez eu en affichant toutes les valeurs.
Le nombre $number que vous spécifiez en paramètre est un nombre maximal. Pas plus de $number valeurs seront affichées sur le graphique. En revanche, dans certains cas, il est possible qu'un nombre inférieur de valeurs soient affichées.
Voici un exemple d'utilisation de cette fonctionnalité :
<pre>
 
&lt;?php
 
require_once "LinePlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
$datay = array();
$datax = array();
 
// On créé un tableau avec 3000 valeurs
for($i = 1; $i &lt;= 3000; $i++) {
$datay[] = log($i);
$datax[] = $i;
}
 
$plot = new <a href="LinePlot.html">LinePlot</a>($datay);
$plot-&gt;xAxis-&gt;<a href="Axis.html#method.setLabelText">setLabelText</a>($datax);
$plot-&gt;xAxis-&gt;label-&gt;<a href="Label.html#method.setAngle">setAngle</a>(90);
 
// On réduit le nombre de valeurs à afficher sur le graphique à 30,
// soit 100 fois moins
$plot-&gt;<a href="Plot.html#method.reduce">reduce</a>(30);
 
// On affiche le graphique
// Les valeurs de l'axe des X ont été automatiquement mises à jour
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
// Finalement, la courbe représentative de log(x) apparaît très correctement
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setXAxis"></a><span class="access">public</span> <a href="Plot.html#method.setXAxis">setXAxis</a>(<span class="type">string</span> <span class="argument">$axis</span>)
<div class="description">
Change l'axe de abscisses qui sera affiché sur l'image.
Cela peut être <a href="Plot.html#constant.TOP">Plot::TOP</a>, <a href="Plot.html#constant.BOTTOM">Plot::BOTTOM</a> ou <a href="Plot.html#constant.BOTH">Plot::BOTH</a>.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setYAxis"></a><span class="access">public</span> <a href="Plot.html#method.setYAxis">setYAxis</a>(<span class="type">string</span> <span class="argument">$axis</span>)
<div class="description">
Change l'axe de ordonnées qui sera affiché sur l'image.
Cela peut être <a href="Plot.html#constant.LEFT">Plot::LEFT</a>, <a href="Plot.html#constant.RIGHT">Plot::RIGHT</a> ou <a href="Plot.html#constant.BOTH">Plot::BOTH</a>.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setXAxisZero"></a><span class="access">public</span> <a href="Plot.html#method.setXAxisZero">setXAxisZero</a>(<span class="type">bool</span> <span class="argument">$zero</span>)
<div class="description">
Précise si le ou les axes des abscisses doivent être centrés sur le zéro de l'axe des ordonnées.
Comme il peut y avoir plus axes des ordonnées, l'axe de gauche est choisi en premier pour sélectionner la valeur du zéro. S'il n'existe pas, alors on utilise l'axe de droite.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setYAxisZero"></a><span class="access">public</span> <a href="Plot.html#method.setYAxisZero">setYAxisZero</a>(<span class="type">bool</span> <span class="argument">$zero</span>)
<div class="description">
Précise si le ou les axes des ordonnées doivent être centrés sur le zéro de l'axe des abscisses.
Comme il peut y avoir plus axes des abscisses, l'axe du bas est choisi en premier pour sélectionner la valeur du zéro. S'il n'existe pas, alors on utilise l'axe du haut.
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setYMin"></a><span class="access">public</span> <a href="Plot.html#method.setYMin">setYMin</a>(<span class="type">float</span> <span class="argument">$value</span>)
<div class="description">
Force la valeur minimale de l'axe des ordonnées à $value.
L'appel à cette méthode désactive la gestion automatique de l'axe des ordonnées.
<div class="see">
Voir aussi :
<ul>
<li><a href="Plot.html#method.setYMax">Plot::setYMax()</a></li>
<li><a href="Axis.html#method.auto">Axis::auto()</a></li>
</ul>
</div>
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setYMax"></a><span class="access">public</span> <a href="Plot.html#method.setYMax">setYMax</a>(<span class="type">float</span> <span class="argument">$value</span>)
<div class="description">
Force la valeur maximale de l'axe des ordonnées à $value.
L'appel à cette méthode désactive la gestion automatique de l'axe des ordonnées.
<div class="see">
Voir aussi :
<ul>
<li><a href="Plot.html#method.setYMin">Plot::setYMin()</a></li>
<li><a href="Axis.html#method.auto">Axis::auto()</a></li>
</ul>
</div>
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setXMin"></a><span class="access">public</span> <a href="Plot.html#method.setXMin">setXMin</a>(<span class="type">float</span> <span class="argument">$value</span>)
<div class="description">
Force la valeur minimale de l'axe des abscisses à $value.
<div class="see">
Voir aussi :
<ul><li><a href="Plot.html#method.setXMax">Plot::setXMax()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setXMax"></a><span class="access">public</span> <a href="Plot.html#method.setXMax">setXMax</a>(<span class="type">float</span> <span class="argument">$value</span>)
<div class="description">
Force la valeur maximale de l'axe des abscisses à $value.
<div class="see">
Voir aussi :
<ul><li><a href="Plot.html#method.setXMin">Plot::setXMin()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Plot.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/ComponentGroup.html
New file
0,0 → 1,72
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2>
<small>abstract</small> Class ComponentGroup</h2><div class="extends"><ul>
<li><a href="Component.html">Component</a></li>
<ul><li>ComponentGroup</li></ul>
</ul></div><div class="description">
<p>
Un groupe de composant permet de gérer plusieurs <a href="Component.html">composants</a>.
Cette classe est abstraite et doit être redéfinit pour être utilisée avec les composants que vous aurez choisis.
</p>
</div><div class="inherit">
Les classes suivantes dérivent de ComponentGroup :
<ul><li><a href="PlotGroup.html">PlotGroup</a></li></ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties"><li>
<span class="access">protected</span> <span class="type">array</span> <a href="ComponentGroup.html#property.components"><span class="argument">$components</span></a>
</li></ul><ul class="methods">
<li>
<span class="access">public</span> <a href="ComponentGroup.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="ComponentGroup.html#method.add">add</a>(<a href="Component.html"><span class="type">Component</span></a> <span class="argument">$component</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.components"></a><span class="access">protected</span> <span class="type">array</span> <a href="ComponentGroup.html#property.components"><span class="argument">$components</span></a><div class="description">
Les <a href="Component.html">composants</a> gérés par ce groupe de composants.
</div>
<div class="description-bottom"><a href="ComponentGroup.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="ComponentGroup.html#method.__construct">__construct</a>()
<div class="description">
Construit le groupe de composants.
</div>
<div class="description-bottom"><a href="ComponentGroup.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.add"></a><span class="access">public</span> <a href="ComponentGroup.html#method.add">add</a>(<a href="Component.html"><span class="type">Component</span></a> <span class="argument">$component</span>)
<div class="description">
Ajoute le composant $component au groupe.
</div>
<div class="description-bottom"><a href="ComponentGroup.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/FileFontDriver.html
New file
0,0 → 1,40
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class FileFontDriver</h2><div class="extends"><ul>
<li><a href="FontDriver.html">FontDriver</a></li>
<ul><li>FileFontDriver</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="FileFontDriver.html">FileFontDriver</a> s'occupe des calculs et de l'affichage liés aux polices de type <a href="FileFont.html">FileFont</a>.
</p>
<p>
A aucun moment vous ne devriez avoir à instancier un objet de ce type. La documentation est là à titre informatif pour les développeurs en herbe.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><h2>Documentation</h2><ul class="doc"></ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/FontDriver.html
New file
0,0 → 1,107
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class FontDriver</h2><div class="description">
<p>
La classe abstraite <a href="FontDriver.html">FontDriver</a> définit toutes les méthodes devant être implémentées pour gérer l'affichage et les calculs à effectuer sur les polices. On dérivera cette classe une fois pour chaque classe enfant de <a href="Font.html">Font</a>, en l'occurence <a href="PHPFontDriver.html">PHPFontDriver</a> pour <a href="PHPFont.html">PHPFont</a> et <a href="FileFontDriver.html">FileFontDriver</a> pour <a href="FileFont.html">FileFont</a>.
</p>
<p>
A aucun moment vous ne devriez avoir à instancier un objet de ce type. La documentation est là à titre informatif pour les développeurs en herbe.
</p>
</div><div class="inherit">
Les classes suivantes dérivent de FontDriver :
<ul>
<li><a href="PHPFontDriver.html">PHPFontDriver</a></li>
<li><a href="FileFontDriver.html">FileFontDriver</a></li>
</ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="methods">
<li>
<span class="access">public</span> <a href="FontDriver.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="FontDriver.html#method.string">string</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>, <span class="type">int</span> <span class="argument">$width</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="FontDriver.html#method.getTextWidth">getTextWidth</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
</li>
<li>
<span class="access">public</span> <a href="FontDriver.html#method.getTextHeight">getTextHeight</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="FontDriver.html#method.__construct">__construct</a>()
<div class="description">
Simple constructeur. Ne fait rien pour l'instant.
</div>
<div class="description-bottom"><a href="FontDriver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.string"></a><span class="access">public</span> <a href="FontDriver.html#method.string">string</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>, <span class="type">int</span> <span class="argument">$width</span> := <span class="default">NULL</span>)
<div class="description">
Dessine le texte $text.
Le pilote $driver sera utilisé pour le dessin tandis que le texte sera positionné au point $point.
Le paramètre $width permet de spécifier la largeur maximale en pixels de la boîte de texte.
</div>
<div class="description-bottom"><a href="FontDriver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getTextWidth"></a><span class="access">public</span> <a href="FontDriver.html#method.getTextWidth">getTextWidth</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
<ul class="version"><li>
Supprimé à partir d'Artichow 1.1</li></ul>
<div class="description">
Retourne la largeur en pixels occupée par l'objet <a href="Text.html">Text</a> $text.
<div class="see">
Voir aussi :
<ul>
<li><a href="Driver.html#method.getTextHeight">Driver::getTextHeight()</a></li>
<li><a href="FontDriver.html#method.getTextHeight">FontDriver::getTextHeight()</a></li>
<li><a href="FontDriver.html#method.getTextWidth">FontDriver::getTextWidth()</a></li>
</ul>
</div>
</div>
<div class="description-bottom"><a href="FontDriver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getTextHeight"></a><span class="access">public</span> <a href="FontDriver.html#method.getTextHeight">getTextHeight</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
<ul class="version"><li>
Supprimé à partir d'Artichow 1.1</li></ul>
<div class="description">
Retourne la hauteur en pixels occupée par l'objet <a href="Text.html">Text</a> $text.
<div class="see">
Voir aussi :
<ul>
<li><a href="Driver.html#method.getTextWidth">Driver::getTextWidth()</a></li>
<li><a href="FontDriver.html#method.getTextHeight">FontDriver::getTextHeight()</a></li>
<li><a href="FontDriver.html#method.getTextWidth">FontDriver::getTextWidth()</a></li>
</ul>
</div>
</div>
<div class="description-bottom"><a href="FontDriver.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Image.html
New file
0,0 → 1,354
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2>
<small>abstract</small> Class Image</h2><div class="description">
<p>
La classe <a href="Image.html">Image</a> est une classe abstraite à la base de toutes les images sur Artichow. Une image peut être copiée sur d'autres images et chaque image peut être générée soit au format PNG, soit au format JPEG.
</p>
</div><div class="inherit">
Les classes suivantes dérivent de Image :
<ul>
<li><a href="Graph.html">Graph</a></li>
<li><a href="FileImage.html">FileImage</a></li>
</ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Image.html#constant.JPEG">JPEG</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Image.html#constant.PNG">PNG</a> := <span class="default">2</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Image.html#constant.GIF">GIF</a> := <span class="default">3</span>
</li>
</ul><ul class="properties">
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Image.html#property.width"><span class="argument">$width</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Image.html#property.height"><span class="argument">$height</span></a>
</li>
<li>
<span class="access">public</span> <a href="Shadow.html"><span class="type">Shadow</span></a> <a href="Image.html#property.shadow"><span class="argument">$shadow</span></a>
</li>
<li>
<span class="access">public</span> <a href="Border.html"><span class="type">Border</span></a> <a href="Image.html#property.border"><span class="argument">$border</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">int</span> <a href="Image.html#property.format"><span class="argument">$format</span></a> := <span class="default">Image::PNG</span>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Image.html#property.antiAliasing"><span class="argument">$antiAliasing</span></a> := <span class="default">FALSE</span>
</li>
<li>
<span class="access">protected</span> <span class="type">resource</span> <a href="Image.html#property.resource"><span class="argument">$resource</span></a>
</li>
<li>
<span class="access">protected</span> <a href="Driver.html"><span class="type">Driver</span></a> <a href="Image.html#property.driver"><span class="argument">$driver</span></a>
</li>
<li>
<span class="access">protected</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Image.html#property.background"><span class="argument">$background</span></a> := <span class="default">new Color(255, 255, 255)</span>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Image.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="Driver.html"><span class="type">Driver</span></a> <a href="Image.html#method.getDriver">getDriver</a>(<span class="type">int</span> <span class="argument">$w</span> := <span class="default">1</span>, <span class="type">int</span> <span class="argument">$h</span> := <span class="default">1</span>, <span class="type">int</span> <span class="argument">$x</span> := <span class="default">0.5</span>, <span class="type">int</span> <span class="argument">$y</span> := <span class="default">0.5</span>)
</li>
<li>
<span class="access">public</span> <a href="Image.html#method.setSize">setSize</a>(<span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
</li>
<li>
<span class="access">public</span> <a href="Image.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Image.html#method.setBackgroundGradient">setBackgroundGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
</li>
<li>
<span class="access">public</span> <a href="Image.html#method.setAntiAliasing">setAntiAliasing</a>(<span class="type">bool</span> <span class="argument">$bool</span>)
</li>
<li>
<span class="access">public</span> <a href="Image.html#method.setFormat">setFormat</a>(<span class="type">int</span> <span class="argument">$format</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Image.html#method.getFormat">getFormat</a>()
</li>
<li>
<span class="access">public</span> <span class="type">string</span> <a href="Image.html#method.getFormatString">getFormatString</a>()
</li>
<li>
<span class="access">public</span> <a href="Image.html#method.create">create</a>()
</li>
<li>
<span class="access">public</span> <a href="Image.html#method.drawComponent">drawComponent</a>(<a href="Component.html"><span class="type">Component</span></a> <span class="argument">$component</span>)
</li>
<li>
<span class="access">public</span> <a href="Image.html#method.send">send</a>()
</li>
<li>
<span class="access">public</span> <span class="type">resource</span> <a href="Image.html#method.get">get</a>()
</li>
<li>
<span class="access">public</span> <a href="Image.html#method.sendHeaders">sendHeaders</a>()
</li>
<li>
<span class="access">public static</span> <a href="Image.html#method.drawError">drawError</a>(<span class="type">string</span> <span class="argument">
$message</span>)
</li>
<li>
<span class="access">public static</span> <a href="Image.html#method.drawErrorFile">drawErrorFile</a>(<span class="type">string</span> <span class="argument">
$error</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.JPEG"></a><span class="access">const</span> <span class="type">int</span> <a href="Image.html#constant.JPEG">JPEG</a> := <span class="default">1</span><div class="description">
Indique que l'image est au format JPEG.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.PNG"></a><span class="access">const</span> <span class="type">int</span> <a href="Image.html#constant.PNG">PNG</a> := <span class="default">2</span><div class="description">
Indique que l'image est au format PNG.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.GIF"></a><span class="access">const</span> <span class="type">int</span> <a href="Image.html#constant.GIF">GIF</a> := <span class="default">3</span><div class="description">
Indique que l'image est au format GIF.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.width"></a><span class="access">public</span> <span class="type">int</span> <a href="Image.html#property.width"><span class="argument">$width</span></a><div class="description">
La largeur de l'image en pixels.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.height"></a><span class="access">public</span> <span class="type">int</span> <a href="Image.html#property.height"><span class="argument">$height</span></a><div class="description">
La hauteur de l'image en pixels.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.shadow"></a><span class="access">public</span> <a href="Shadow.html"><span class="type">Shadow</span></a> <a href="Image.html#property.shadow"><span class="argument">$shadow</span></a><div class="description">
L'ombre associée à l'image.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.border"></a><span class="access">public</span> <a href="Border.html"><span class="type">Border</span></a> <a href="Image.html#property.border"><span class="argument">$border</span></a><div class="description">
La bordure associée à l'image.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.format"></a><span class="access">protected</span> <span class="type">int</span> <a href="Image.html#property.format"><span class="argument">$format</span></a> := <span class="default">Image::PNG</span><div class="description">
Le format de l'image. Cela peut être <a href="Image.html#constant.PNG">Image::PNG</a> ou <a href="Image.html#constant.JPEG">Image::JPEG</a>.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.antiAliasing"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Image.html#property.antiAliasing"><span class="argument">$antiAliasing</span></a> := <span class="default">FALSE</span><div class="description">
Doit-on utiliser l'anti aliasing sur cette image ?
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.resource"></a><span class="access">protected</span> <span class="type">resource</span> <a href="Image.html#property.resource"><span class="argument">$resource</span></a><div class="description">
La ressource GD créée par PHP pour gérer l'image.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.driver"></a><span class="access">protected</span> <a href="Driver.html"><span class="type">Driver</span></a> <a href="Image.html#property.driver"><span class="argument">$driver</span></a><div class="description">
Représente un objet de la classe <a href="Driver.html">Driver</a> qui sera utilisé pour dessiner toutes sortes de données sur cette image.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.background"></a><span class="access">protected</span> <a href="Color.html"><span class="type">Color</span></a> <a href="Image.html#property.background"><span class="argument">$background</span></a> := <span class="default">new Color(255, 255, 255)</span><div class="description">
La couleur de fond de l'image. Par défaut, le fond d'une image est blanc.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Image.html#method.__construct">__construct</a>()
<div class="description">
Construit l'image.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getDriver"></a><span class="access">public</span> <a href="Driver.html"><span class="type">Driver</span></a> <a href="Image.html#method.getDriver">getDriver</a>(<span class="type">int</span> <span class="argument">$w</span> := <span class="default">1</span>, <span class="type">int</span> <span class="argument">$h</span> := <span class="default">1</span>, <span class="type">int</span> <span class="argument">$x</span> := <span class="default">0.5</span>, <span class="type">int</span> <span class="argument">$y</span> := <span class="default">0.5</span>)
<div class="description">
Retourne un objet de type <a href="Driver.html">Driver</a> qui permet de dessiner sur l'image.
Le <a href="Driver.html">Driver</a> aura une largeur $w et une hauteur $h, et son centre sera positionné au point ($x, $y).
La largeur doit être comprise entre 0 et 1 et représente une fraction de la taille réelle de l'image.
La position doit être elle aussi comprise entre 0 et 1.
Les paramètres par défaut centrent le pilote au milieu de l'image et lui donnent la taille de l'image.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSize"></a><span class="access">public</span> <a href="Image.html#method.setSize">setSize</a>(<span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
<div class="description">
Permet de déterminer la taille de l'image à une largeur $width et une hauteur $height.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundColor"></a><span class="access">public</span> <a href="Image.html#method.setBackgroundColor">setBackgroundColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de fond de l'image.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setBackgroundGradient"></a><span class="access">public</span> <a href="Image.html#method.setBackgroundGradient">setBackgroundGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
<div class="description">
Change le dégradé de fond de l'image.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAntiAliasing"></a><span class="access">public</span> <a href="Image.html#method.setAntiAliasing">setAntiAliasing</a>(<span class="type">bool</span> <span class="argument">$bool</span>)
<div class="description">
Active ou désactive l'anti-aliasing sur l'image.
L'anti-aliasing permet d'avoir des graphiques plus propres mais demande plus de ressources.
L'anti-aliasing n'est pas activé par défaut.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.setAntiAliasing">Driver::setAntiAliasing()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setFormat"></a><span class="access">public</span> <a href="Image.html#method.setFormat">setFormat</a>(<span class="type">int</span> <span class="argument">$format</span>)
<div class="description">
Change le format de l'image. La nouvelle valeur peut être <a href="Image.html#constant.PNG">Image::PNG</a>, <a href="Image.html#constant.JPEG">Image::JPEG</a> ou <a href="Image.html#constant.GIF">Image::GIF</a>.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getFormat"></a><span class="access">public</span> <span class="type">int</span> <a href="Image.html#method.getFormat">getFormat</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.1.0</li></ul>
<div class="description">
Renvoie le format de l'image comme un entier.
Les valeurs possibles sont <a href="Image.html#constant.PNG">Image::PNG</a>, <a href="Image.html#constant.JPEG">Image::JPEG</a> ou <a href="Image.html#constant.GIF">Image::GIF</a>.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getFormatString"></a><span class="access">public</span> <span class="type">string</span> <a href="Image.html#method.getFormatString">getFormatString</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.1.0</li></ul>
<div class="description">
Renvoie le format de l'image comme une chaîne de caractères.
Les valeurs possibles sont "jpeg", "png", ou "gif".
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.create"></a><span class="access">public</span> <a href="Image.html#method.create">create</a>()
<div class="description">
Créé l'image en vue d'y ajouter des composants.
Il n'est possible de créer une image qu'après lui avoir affecté une taille avec <a href="Image.html#method.setSize">setSize()</a>.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.drawComponent"></a><span class="access">public</span> <a href="Image.html#method.drawComponent">drawComponent</a>(<a href="Component.html"><span class="type">Component</span></a> <span class="argument">$component</span>)
<div class="description">
Dessine le composant $component sur l'image.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.send"></a><span class="access">public</span> <a href="Image.html#method.send">send</a>()
<div class="description">
Construit l'image et l'envoie sur la sortie standard accompagnée des en-têtes HTTP correspondants.
Cette fonction ne prend plus d'arguments depuis Artichow 1.1.0. Pour récupérer les données brutes de l'image, utilisez la méthode <a href="Image.html#method.get">get()</a>. Pour sauvegarder l'image dans un fichier sur le disque, voyez la méthode <a href="Graph.html#method.draw">Graph::draw()</a>.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.get"></a><span class="access">public</span> <span class="type">resource</span> <a href="Image.html#method.get">get</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.1.0</li></ul>
<div class="description">
Construit l'image et la renvoie sous forme de données binaires. Vous pouvez donc la stocker dans une variable si vous voulez faire des manipulations spécifiques.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.sendHeaders"></a><span class="access">public</span> <a href="Image.html#method.sendHeaders">sendHeaders</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Envoie l'en-tête HTTP correspondant au format de l'image.
</div>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.drawError"></a><span class="access">public static</span> <a href="Image.html#method.drawError">drawError</a>(<span class="type">string</span> <span class="argument">
$message</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.0.8</li></ul>
<div class="description">
Affiche une erreur de façon lisible sous forme graphique.
</div>
<ul class="arguments"><li class="property">
<span class="type">string</span> <a href="Image.html#property.message"><span class="argument">$message</span></a><div class="description">
Le message d'erreur à afficher.
</div>
</li></ul>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.drawErrorFile"></a><span class="access">public static</span> <a href="Image.html#method.drawErrorFile">drawErrorFile</a>(<span class="type">string</span> <span class="argument">
$error</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.0.8</li></ul>
<div class="description">
Affiche une erreur à partir d'une image présente dans le dossier <em>images/erreurs/</em>.
</div>
<ul class="arguments"><li class="property">
<span class="type">string</span> <a href="Image.html#property.error"><span class="argument">$error</span></a><div class="description">
Le nom de l'erreur à afficher.
L'image correspondant à cette erreur sera récupérée dans le dossier <em>images/erreurs/</em>.
</div>
</li></ul>
<div class="description-bottom"><a href="Image.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/FileImage.html
New file
0,0 → 1,47
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class FileImage</h2><div class="extends"><ul>
<li><a href="Image.html">Image</a></li>
<ul><li>FileImage</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="FileImage.html">FileImage</a> permet de charger une image existante à partir d'un fichier. L'image ainsi créée peut être utilisée avec un <a href="Driver.html">Driver</a> pour être copiée sur une autre image par exemple.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="methods"><li>
<span class="access">public</span> <a href="FileImage.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">
$file</span>)
</li></ul><h2>Documentation</h2><ul class="doc"><li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="FileImage.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">
$file</span>)
<div class="description">
Construit l'image à partir de l'image contenue dans le fichier $file.
</div>
<div class="description-bottom"><a href="FileImage.html#top">Remonter</a></div>
</li></ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/LinePlot.html
New file
0,0 → 1,230
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class LinePlot</h2><div class="extends"><ul>
<li><a href="Component.html">Component</a></li>
<ul>
<li><a href="Plot.html">Plot</a></li>
<ul><li>LinePlot <span class="interface">implements</span> <a href="Legendable.html">Legendable</a>
</li></ul>
</ul>
</ul></div><div class="description">
<p>
Cette classe permet de dessiner des courbes.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">int</span> <a href="LinePlot.html#constant.LINE">LINE</a> := <span class="default">0</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="LinePlot.html#constant.MIDDLE">MIDDLE</a> := <span class="default">1</span>
</li>
</ul><ul class="properties">
<li>
<span class="access">public</span> <a href="Mark.html"><span class="type">Mark</span></a> <a href="LinePlot.html#property.mark"><span class="argument">$mark</span></a>
</li>
<li>
<span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="LinePlot.html#property.label"><span class="argument">$label</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="LinePlot.html#method.__construct">__construct</a>(<span class="type">array</span> <span class="argument">$values</span>, <span class="type">int</span> <span class="argument">$mode</span> := <span class="default">LinePlor::LINE</span>)
</li>
<li>
<span class="access">public</span> <a href="LinePlot.html#method.hideLine">hideLine</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
</li>
<li>
<span class="access">public</span> <a href="LinePlot.html#method.setFilledArea">setFilledArea</a>(<span class="type">int</span> <span class="argument">$start</span>, <span class="type">int</span> <span class="argument">$stop</span>, <span class="type">mixed</span> <span class="argument">$background</span>)
</li>
<li>
<span class="access">public</span> <a href="LinePlot.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="LinePlot.html#method.setStyle">setStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
</li>
<li>
<span class="access">public</span> <a href="LinePlot.html#method.setThickness">setThickness</a>(<span class="type">int</span> <span class="argument">$thickness</span>)
</li>
<li>
<span class="access">public</span> <a href="LinePlot.html#method.setFillColor">setFillColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="LinePlot.html#method.setFillGradient">setFillGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.LINE"></a><span class="access">const</span> <span class="type">int</span> <a href="LinePlot.html#constant.LINE">LINE</a> := <span class="default">0</span><div class="description">
Dessine une courbe.
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.MIDDLE"></a><span class="access">const</span> <span class="type">int</span> <a href="LinePlot.html#constant.MIDDLE">MIDDLE</a> := <span class="default">1</span><div class="description">
Dessine une courbe dont les pics sont centrés sur l'axe des X (idéal pour cumuler courbe et histogramme).
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.mark"></a><span class="access">public</span> <a href="Mark.html"><span class="type">Mark</span></a> <a href="LinePlot.html#property.mark"><span class="argument">$mark</span></a><div class="description">
Représente les marques affichées sur chaque pointe de la courbe.
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.label"></a><span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="LinePlot.html#property.label"><span class="argument">$label</span></a><div class="description">
Représente les étiquettes affichées au-dessus de chaque pointe de la courbe.
Ces étiquettes contiennent la valeur de chaque pointe.
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="LinePlot.html#method.__construct">__construct</a>(<span class="type">array</span> <span class="argument">$values</span>, <span class="type">int</span> <span class="argument">$mode</span> := <span class="default">LinePlor::LINE</span>)
<div class="description">
Créé une nouvelle courbe de type $mode avec les valeurs présentes dans $values.
Le tableau $values doit être une liste de valeurs dans un tableau incrémental, c'est-à-dire dont les clés valent de 0 à n - 1 (où n est la taille du tableau).
<pre>
 
&lt;?php
 
require_once "LinePlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
// Tableau de valeurs
$x = array(1, 4, 3);
 
$plot = new <a href="LinePlot.html">LinePlot</a>($x);
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hideLine"></a><span class="access">public</span> <a href="LinePlot.html#method.hideLine">hideLine</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
<div class="description">
Cache ou ne cache pas la ligne qui relie les valeurs de la courbe.
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setFilledArea"></a><span class="access">public</span> <a href="LinePlot.html#method.setFilledArea">setFilledArea</a>(<span class="type">int</span> <span class="argument">$start</span>, <span class="type">int</span> <span class="argument">$stop</span>, <span class="type">mixed</span> <span class="argument">$background</span>)
<div class="description">
Permet de remplir une aire sous la courbe des points $start à $stop.
L'aire sera remplie avec la couleur ou le dégradé $background.
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColor"></a><span class="access">public</span> <a href="LinePlot.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de la ligne qui relie les valeurs de la courbe.
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setStyle"></a><span class="access">public</span> <a href="LinePlot.html#method.setStyle">setStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
<div class="description">
Change le style de ligne (<a href="Line.html#constant.SOLID">Line::SOLID</a>, <a href="Line.html#constant.DOTTED">Line::DOTTED</a> ou <a href="Line.html#constant.DASHED">Line::DASHED</a>).
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setThickness"></a><span class="access">public</span> <a href="LinePlot.html#method.setThickness">setThickness</a>(<span class="type">int</span> <span class="argument">$thickness</span>)
<div class="description">
Change l'épaisseur de la ligne.
L'épaisseur de la ligne doit être toujours positive.
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setFillColor"></a><span class="access">public</span> <a href="LinePlot.html#method.setFillColor">setFillColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de fond de la ligne qui relie les valeurs de la courbe.
La couleur de fond remplit le polygone définit par tous les points de la ligne additionés des points extrêmes de l'axe des abscisses.
<pre>
 
&lt;?php
 
require_once "LinePlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
$x = array(1, 10, 3, -4, 1);
 
$plot = new <a href="LinePlot.html">LinePlot</a>($x);
$plot-&gt;<a href="LinePlot.html#method.setFillColor">setFillColor</a>(new <a href="Color.html">Color</a>(255, 20, 20, 30));
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setFillGradient"></a><span class="access">public</span> <a href="LinePlot.html#method.setFillGradient">setFillGradient</a>(<a href="Gradient.html"><span class="type">Gradient</span></a> <span class="argument">$gradient</span>)
<div class="description">
Change le dégradé de fond de la ligne qui relie les valeurs de la courbe.
Le dégradé de fond remplit le polygone définit par tous les points de la ligne additionés des points extrêmes de l'axe des abscisses.
<pre>
 
&lt;?php
 
require_once "LinePlot.class.php";
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
$x = array(1, 10, 3, -4, 1);
 
$plot = new <a href="LinePlot.html">LinePlot</a>($x);
$plot-&gt;<a href="LinePlot.html#method.setFillGradient">setFillGradient</a>(
new <a href="LinearGradient.html">LinearGradient</a>(
new <a href="Color.html">Color</a>(255, 20, 20, 30),
new <a href="Color.html">Color</a>(20, 255, 20, 30),
90
)
);
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
</div>
<div class="description-bottom"><a href="LinePlot.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Polygon.html
New file
0,0 → 1,147
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Polygon</h2><div class="extends"><ul>
<li><a href="Shape.html">Shape</a></li>
<ul><li>Polygon</li></ul>
</ul></div><div class="description">
<p>
Un polygone est une succcession de points.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties"><li>
<span class="access">protected</span> <span class="type">array</span> <a href="Polygon.html#property.points"><span class="argument">$points</span></a>
</li></ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Polygon.html#method.set">set</a>(<span class="type">int</span> <span class="argument">$pos</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
</li>
<li>
<span class="access">public</span> <a href="Point.html"><span class="type">Point</span></a> <a href="Polygon.html#method.get">get</a>(<span class="type">int</span> <span class="argument">$pos</span>)
</li>
<li>
<span class="access">public</span> <a href="Polygon.html#method.append">append</a>(<a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Polygon.html#method.count">count</a>()
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Polygon.html#method.all">all</a>()
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Polygon.html#method.getLines">getLines</a>()
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Polygon.html#method.getBoxPoints">getBoxPoints</a>()
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Polygon.html#method.getBoxYRange">getBoxYRange</a>()
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Polygon.html#method.getBoxXRange">getBoxXRange</a>()
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.points"></a><span class="access">protected</span> <span class="type">array</span> <a href="Polygon.html#property.points"><span class="argument">$points</span></a><div class="description">
Stocke tous les points du polygone.
</div>
<div class="description-bottom"><a href="Polygon.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.set"></a><span class="access">public</span> <a href="Polygon.html#method.set">set</a>(<span class="type">int</span> <span class="argument">$pos</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
<div class="description">
Ajoute ou remplace un point $point dans le polygon à la position $pos.
Cette méthode accepte la valeur NULL pour spécifier que ce point doit être ignoré.
</div>
<div class="description-bottom"><a href="Polygon.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.get"></a><span class="access">public</span> <a href="Point.html"><span class="type">Point</span></a> <a href="Polygon.html#method.get">get</a>(<span class="type">int</span> <span class="argument">$pos</span>)
<div class="description">
Retourne le point du polygone à la position $pos.
</div>
<div class="description-bottom"><a href="Polygon.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.append"></a><span class="access">public</span> <a href="Polygon.html#method.append">append</a>(<a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
<div class="description">
Ajoute un point $point à la fin du polygone.
Cette méthode accepte la valeur NULL pour spécifier que ce point doit être ignoré.
</div>
<div class="description-bottom"><a href="Polygon.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.count"></a><span class="access">public</span> <span class="type">int</span> <a href="Polygon.html#method.count">count</a>()
<div class="description">
Retourne le nombre de points contenus dans le polygone.
</div>
<div class="description-bottom"><a href="Polygon.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.all"></a><span class="access">public</span> <span class="type">array</span> <a href="Polygon.html#method.all">all</a>()
<div class="description">
Permet de récupérer tous les points du polygone.
</div>
<div class="description-bottom"><a href="Polygon.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getLines"></a><span class="access">public</span> <span class="type">array</span> <a href="Polygon.html#method.getLines">getLines</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie un tableau contenant toutes les lignes formant le polygone.
</div>
<div class="description-bottom"><a href="Polygon.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getBoxPoints"></a><span class="access">public</span> <span class="type">array</span> <a href="Polygon.html#method.getBoxPoints">getBoxPoints</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie un tableau contenant les points supérieur droit et inférieur gauche du rectangle encadrant le polygone.
</div>
<div class="description-bottom"><a href="Polygon.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getBoxYRange"></a><span class="access">public</span> <span class="type">array</span> <a href="Polygon.html#method.getBoxYRange">getBoxYRange</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie un tableau contenant les ordonnées minimales et maximales de n'importe quel point appartenant au polygone (c'est à dire l'étendue du polygone le long de l'axe des ordonnées).
</div>
<div class="description-bottom"><a href="Polygon.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getBoxXRange"></a><span class="access">public</span> <span class="type">array</span> <a href="Polygon.html#method.getBoxXRange">getBoxXRange</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Renvoie un tableau contenant les abscisses minimales et maximales de n'importe quel point appartenant au polygone (c'est à dire l'étendue du polygone le long de l'axe des abscisses).
</div>
<div class="description-bottom"><a href="Polygon.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Positionable.html
New file
0,0 → 1,101
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Positionable</h2><div class="description">
<p>
<a href="Positionable.html">Positionable</a> est une <span style="text-decoration: underline">interface</span> que doivent implémenter les classes peuvent être positionnées par rapport à un <a href="Point.html">Point</a>.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.LEFT">LEFT</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.RIGHT">RIGHT</a> := <span class="default">2</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.CENTER">CENTER</a> := <span class="default">3</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.TOP">TOP</a> := <span class="default">4</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.BOTTOM">BOTTOM</a> := <span class="default">5</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.MIDDLE">MIDDLE</a> := <span class="default">6</span>
</li>
</ul><ul class="methods"><li>
<span class="access">public</span> <a href="Positionable.html#method.setAlign">setAlign</a>(<span class="type">int</span> <span class="argument">$h</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$v</span> := <span class="default">NULL</span>)
</li></ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.LEFT"></a><span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.LEFT">LEFT</a> := <span class="default">1</span><div class="description">
Désigne un alignement à gauche.
</div>
<div class="description-bottom"><a href="Positionable.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.RIGHT"></a><span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.RIGHT">RIGHT</a> := <span class="default">2</span><div class="description">
Désigne un alignement à droite.
</div>
<div class="description-bottom"><a href="Positionable.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.CENTER"></a><span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.CENTER">CENTER</a> := <span class="default">3</span><div class="description">
Désigne un alignement au centre.
</div>
<div class="description-bottom"><a href="Positionable.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.TOP"></a><span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.TOP">TOP</a> := <span class="default">4</span><div class="description">
Désigne un alignement en haut.
</div>
<div class="description-bottom"><a href="Positionable.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.BOTTOM"></a><span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.BOTTOM">BOTTOM</a> := <span class="default">5</span><div class="description">
Désigne un alignement en bas.
</div>
<div class="description-bottom"><a href="Positionable.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.MIDDLE"></a><span class="access">const</span> <span class="type">int</span> <a href="Positionable.html#constant.MIDDLE">MIDDLE</a> := <span class="default">6</span><div class="description">
Désigne un alignement au centre.
</div>
<div class="description-bottom"><a href="Positionable.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAlign"></a><span class="access">public</span> <a href="Positionable.html#method.setAlign">setAlign</a>(<span class="type">int</span> <span class="argument">$h</span> := <span class="default">NULL</span>, <span class="type">int</span> <span class="argument">$v</span> := <span class="default">NULL</span>)
<div class="description">
Change l'alignement par rapport au point où l'objet sera affiché.
$h correspond à l'alignement horizontal (<a href="Positionable.html#constant.LEFT">Positionable::LEFT</a>, <a href="Positionable.html#constant.RIGHT">Positionable::RIGHT</a> ou <a href="Positionable.html#constant.CENTER">Positionable::CENTER</a>) et $v à l'alignement vertical (<a href="Positionable.html#constant.TOP">Positionable::TOP</a>, <a href="Positionable.html#constant.BOTTOM">Positionable::BOTTOM</a> ou <a href="Positionable.html#constant.MIDDLE">Positionable::MIDDLE</a>).
Si vous ne souhaitez pas modifier une des deux valeurs, vous pouvez passer NULL.
</div>
<div class="description-bottom"><a href="Positionable.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/LinearGradient.html
New file
0,0 → 1,58
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class LinearGradient</h2><div class="extends"><ul>
<li><a href="Gradient.html">Gradient</a></li>
<ul><li>LinearGradient</li></ul>
</ul></div><div class="description">
<p>
Cette classe permet de décrire un dégradé linéaire.
</p>
</div><div class="inherit">
Les classes suivantes dérivent de LinearGradient :
<ul><li><a href="BilinearGradient.html">BilinearGradient</a></li></ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties"><li>
<span class="access">public</span> <span class="type">int</span> <a href="LinearGradient.html#property.angle"><span class="argument">$angle</span></a>
</li></ul><ul class="methods"><li>
<span class="access">public</span> <a href="LinearGradient.html#method.__construct">__construct</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$from</span>, <a href="Color.html"><span class="type">Color</span></a> <span class="argument">$to</span>, <span class="type">int</span> <span class="argument">$angle</span>)
</li></ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.angle"></a><span class="access">public</span> <span class="type">int</span> <a href="LinearGradient.html#property.angle"><span class="argument">$angle</span></a><div class="description">
Décrit l'angle du dégradé. Les valeurs possibles sont 0 et 90°.
</div>
<div class="description-bottom"><a href="LinearGradient.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="LinearGradient.html#method.__construct">__construct</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$from</span>, <a href="Color.html"><span class="type">Color</span></a> <span class="argument">$to</span>, <span class="type">int</span> <span class="argument">$angle</span>)
<div class="description">
Construit une nouveu dégradé. Cette méthode doit être appelée par toutes les classes qui dérivent de celle-ci. Le paramètre $from décrit la couleur de départ du dégradé et le paramètre $to celle de fin. Le troisième paramètre $angle décrit l'angle du dégradé. Ce peut être un dégradé horizontal (angle de 0°) ou un dégradé vertical (angle de 90°).
</div>
<div class="description-bottom"><a href="LinearGradient.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/PHPFontDriver.html
New file
0,0 → 1,40
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class PHPFontDriver</h2><div class="extends"><ul>
<li><a href="FontDriver.html">FontDriver</a></li>
<ul><li>PHPFontDriver</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="PHPFontDriver.html">PHPFontDriver</a> s'occupe des calculs et de l'affichage liés aux polices de type <a href="PHPFont.html">PHPFont</a>.
</p>
<p>
A aucun moment vous ne devriez avoir à instancier un objet de ce type. La documentation est là à titre informatif pour les développeurs en herbe.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><h2>Documentation</h2><ul class="doc"></ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Driver.html
New file
0,0 → 1,494
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Driver</h2><div class="description">
<p>
La classe abstraite <a href="Driver.html">Driver</a> rassemble toutes les méthodes permettant de dessiner sur une <a href="Image.html">Image</a>. Cette classe ne contient aucune implémentation. Celle-ci doit être effectué à l'intérieur de chaque pilote dérivant de <a href="Driver.html">Driver</a>.
</p>
<p>
Sur une image, l'axe des abscisses rejoint l'axe des ordonnées sur le coin haut-gauche. Le coin haut-gauche de l'image a donc pour coordonnées (0, 0) et le coin bas-droite (largeur, hauteur). Par exemple, sur une image de largeur 100 et de hauteur 50, un point à 50 sur l'axe des abscisses et 25 sur l'axe des ordonnées sera au centre de l'image.
</p>
</div><div class="inherit">
Les classes suivantes dérivent de Driver :
<ul><li><a href="GDDriver.html">GDDriver</a></li></ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Driver.html#property.imageWidth"><span class="argument">$imageWidth</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Driver.html#property.imageHeight"><span class="argument">$imageHeight</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Driver.html#property.antiAliasing"><span class="argument">$antiAliasing</span></a> := <span class="default">FALSE</span>
</li>
<li>
<span class="access">protected</span> <span class="type">string</span> <a href="Driver.html#property.driverString"><span class="argument">$driverString</span></a>
</li>
<li>
<span class="access">protected</span> <a href="PHPFontDriver.html"><span class="type">PHPFontDriver</span></a> <a href="Driver.html#property.phpFontDriver"><span class="argument">$phpFontDriver</span></a>
</li>
<li>
<span class="access">protected</span> <a href="FileFontDriver.html"><span class="type">FileFontDriver</span></a> <a href="Driver.html#property.fileFontDriver"><span class="argument">$fileFontDriver</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Driver.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.init">init</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.initFromFile">initFromFile</a>(<a href="FileImage.html"><span class="type">FileImage</span></a> <span class="argument">$fileImage</span>, <span class="type">string</span> <span class="argument">$file</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setImageSize">setImageSize</a>(<span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setPosition">setPosition</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.movePosition">movePosition</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setAbsPosition">setAbsPosition</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setSize">setSize</a>(<span class="type">float</span> <span class="argument">$w</span>, <span class="type">float</span> <span class="argument">$h</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setAbsSize">setAbsSize</a>(<span class="type">int</span> <span class="argument">$w</span>, <span class="type">int</span> <span class="argument">$h</span>)
</li>
<li>
<span class="access">public</span> <span class="type">array</span> <a href="Driver.html#method.getSize">getSize</a>()
</li>
<li>
<span class="access">public</span> <span class="type">mixed</span> <a href="Driver.html#method.getColor">getColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.send">send</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.get">get</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.setAntiAliasing">setAntiAliasing</a>(<span class="type">bool</span> <span class="argument">$bool</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.copyImage">copyImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.copyResizeImage">copyResizeImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$d1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$d2</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$s1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$s2</span>, <span class="type">bool</span> <span class="argument">$resampled</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.string">string</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>, <span class="type">int</span> <span class="argument">$width</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.point">point</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.line">line</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Line.html"><span class="type">Line</span></a> <span class="argument">$line</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.arc">arc</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>, <span class="type">float</span> <span class="argument">$from</span>, <span class="type">float</span> <span class="argument">$to</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.filledArc">filledArc</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>, <span class="type">float</span> <span class="argument">$from</span>, <span class="type">float</span> <span class="argument">$to</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.ellipse">ellipse</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.filledEllipse">filledEllipse</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.rectangle">rectangle</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Line.html"><span class="type">Line</span></a> <span class="argument">$line</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.filledRectangle">filledRectangle</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Line.html"><span class="type">Line</span></a> <span class="argument">$line</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.polygon">polygon</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
</li>
<li>
<span class="access">public</span> <a href="Driver.html#method.filledPolygon">filledPolygon</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Driver.html#method.getTextWidth">getTextWidth</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Driver.html#method.getTextHeight">getTextHeight</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Driver.html#method.isCompatibleWithFont">isCompatibleWithFont</a>(<a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.imageWidth"></a><span class="access">public</span> <span class="type">int</span> <a href="Driver.html#property.imageWidth"><span class="argument">$imageWidth</span></a><div class="description">
La largeur de l'image gérée par le pilote.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.imageHeight"></a><span class="access">public</span> <span class="type">int</span> <a href="Driver.html#property.imageHeight"><span class="argument">$imageHeight</span></a><div class="description">
La hauteur de l'image gérée par le pilote.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.antiAliasing"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Driver.html#property.antiAliasing"><span class="argument">$antiAliasing</span></a> := <span class="default">FALSE</span><div class="description">
Doit-on utiliser l'anti-aliasing sur ce dessin ?
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.driverString"></a><span class="access">protected</span> <span class="type">string</span> <a href="Driver.html#property.driverString"><span class="argument">$driverString</span></a><div class="description">
Représente le type du pilote sous forme de chaîne.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.phpFontDriver"></a><span class="access">protected</span> <a href="PHPFontDriver.html"><span class="type">PHPFontDriver</span></a> <a href="Driver.html#property.phpFontDriver"><span class="argument">$phpFontDriver</span></a><div class="description">
Un objet <a href="PHPFontDriver.html">PHPFontDriver</a> gérant l'affichage et les calculs sur les polices de type <a href="PHPFont.html">PHPFont</a>.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.fileFontDriver"></a><span class="access">protected</span> <a href="FileFontDriver.html"><span class="type">FileFontDriver</span></a> <a href="Driver.html#property.fileFontDriver"><span class="argument">$fileFontDriver</span></a><div class="description">
Un objet <a href="FileFontDriver.html">FileFontDriver</a> gérant l'affichage et les calculs sur les polices de type <a href="FileFont.html">FileFont</a>.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Driver.html#method.__construct">__construct</a>()
<div class="description">
Construit le pilote.
Instancie les <a href="FontDriver.html">FontDriver</a> et initialise la propriété <a href="Driver.html#property.driverString">driverString</a>.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.init"></a><span class="access">public</span> <a href="Driver.html#method.init">init</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Initialise le pilote pour l'<a href="Image.html">Image</a> $image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.initFromFile"></a><span class="access">public</span> <a href="Driver.html#method.initFromFile">initFromFile</a>(<a href="FileImage.html"><span class="type">FileImage</span></a> <span class="argument">$fileImage</span>, <span class="type">string</span> <span class="argument">$file</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Initialise le pilote à partir d'une <a href="FileImage.html">FileImage</a> $fileImage.
Le chemin d'accès au fichier proprement dit est contenu dans $file.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setImageSize"></a><span class="access">public</span> <a href="Driver.html#method.setImageSize">setImageSize</a>(<span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
<div class="description">
Change la taille de l'image gérée par le pilote pour la largeur $width et la hauteur $height.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setPosition"></a><span class="access">public</span> <a href="Driver.html#method.setPosition">setPosition</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
<div class="description">
Informe le pilote de la position de la sous-image sur l'image.
Les positions X et Y sont données via les paramètres $x et $y, qui représentent une fraction de la taille de l'image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.movePosition"></a><span class="access">public</span> <a href="Driver.html#method.movePosition">movePosition</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
<div class="description">
Demande au pilote de déplacer la position de la sous-image sur l'image.
$x et $y représentent respectivement les déplacements latéral et vertical de la position en pixels.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAbsPosition"></a><span class="access">public</span> <a href="Driver.html#method.setAbsPosition">setAbsPosition</a>(<span class="type">int</span> <span class="argument">$x</span>, <span class="type">int</span> <span class="argument">$y</span>)
<div class="description">
Informe le pilote de la position de la sous-image sur l'image.
Les positions X et Y sont données via les paramètres $x et $y, dont l'unité est le pixel.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSize"></a><span class="access">public</span> <a href="Driver.html#method.setSize">setSize</a>(<span class="type">float</span> <span class="argument">$w</span>, <span class="type">float</span> <span class="argument">$h</span>)
<div class="description">
Informe le pilote de la taille de la sous-image sur l'image.
Les largeur et hauteur de la sous-image sont données via les paramètres $w et $h, qui représentent une fraction de la taille de l'image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAbsSize"></a><span class="access">public</span> <a href="Driver.html#method.setAbsSize">setAbsSize</a>(<span class="type">int</span> <span class="argument">$w</span>, <span class="type">int</span> <span class="argument">$h</span>)
<div class="description">
Informe le pilote de la taille de la sous-image sur l'image.
Les largeur et hauteur de la sous-image sont données via les paramètres $w et $h, dont l'unité est le pixel.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getSize"></a><span class="access">public</span> <span class="type">array</span> <a href="Driver.html#method.getSize">getSize</a>()
<div class="description">
Retourne la taille de la sous-image en pixels.
Les valeurs sont retournées sous la forme d'un tableau, de la forme array(largeur, hauteur).
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getColor"></a><span class="access">public</span> <span class="type">mixed</span> <a href="Driver.html#method.getColor">getColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Convertit un objet <a href="Color.html">Color</a> pour qu'il soit exploitable directement par les fonctions de dessins employées par le pilote.
Le type de donnée renvoyée dépend du pilote.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.send"></a><span class="access">public</span> <a href="Driver.html#method.send">send</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
<div class="description">
Construit l'image passée en paramètre et l'envoie sur la sortie standard accompagnée des en-têtes HTTP correspondants.
A aucun moment vous ne devriez avoir besoin d'appeler vous-même cette méthode. Pour générez les images, utilisez <a href="Graph.html#method.draw">Graph::draw()</a>.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.get"></a><span class="access">public</span> <a href="Driver.html#method.get">get</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Construit l'image passée en paramètre et la renvoie sous forme de données binaires. Vous pouvez donc la stocker dans une variable si vous voulez faire des manipulations spécifiques.
A aucun moment vous ne devriez avoir besoin d'appeler vous-même cette méthode. Pour générez les images, utilisez <a href="Graph.html#method.draw">Graph::draw()</a>.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setAntiAliasing"></a><span class="access">public</span> <a href="Driver.html#method.setAntiAliasing">setAntiAliasing</a>(<span class="type">bool</span> <span class="argument">$bool</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.0.9</li></ul>
<div class="description">
Active ou désactive l'anti-aliasing lors du dessin.
L'anti-aliasing permet d'avoir des graphiques plus propres mais demande plus de ressources.
L'anti-aliasing n'est pas activé par défaut.
<div class="see">
Voir aussi :
<ul><li><a href="Image.html#method.setAntiAliasing">Image::setAntiAliasing()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.copyImage"></a><span class="access">public</span> <a href="Driver.html#method.copyImage">copyImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$p2</span>)
<div class="description">
Copie l'image $image vers la sous-image courante.
L'image sera copiée sur la sous-image du point $p1 (coin haut-gauche) ou point $p2 (coin bas-droit).
Les coordonnées de $p1 et $p2 doivent être relatives à celles de la sous-image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.copyResizeImage"></a><span class="access">public</span> <a href="Driver.html#method.copyResizeImage">copyResizeImage</a>(<a href="Image.html"><span class="type">Image</span></a> <span class="argument">$image</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$d1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$d2</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$s1</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$s2</span>, <span class="type">bool</span> <span class="argument">$resampled</span>)
<div class="description">
Copie l'image $image vers l'image courante.
L'image $image sera copiée des points $s1 (coin haut-gauche) et $s2 (coin bas-droit) vers les points $d1 (coin haut-gauche) et $d2 (coin bas-droit) de l'image courante.
Si $resampled est placé à TRUE, l'image sera rééchantillonée.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.string"></a><span class="access">public</span> <a href="Driver.html#method.string">string</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>, <span class="type">int</span> <span class="argument">$width</span> := <span class="default">NULL</span>)
<div class="description">
Dessine la chaîne de caractères $text à partir du point $point.
Les coordonnées de $point doivent être relatives à celles de la sous-image.
Le paramètre $width permet de spécifier la largeur maximale en pixels de la boîte de texte.
<div class="see">
Voir aussi :
<ul>
<li><a href="Driver.html#method.getTextHeight">Driver::getTextHeight()</a></li>
<li><a href="Driver.html#method.getTextWidth">Driver::getTextWidth()</a></li>
</ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.point"></a><span class="access">public</span> <a href="Driver.html#method.point">point</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>)
<div class="description">
Dessine un pixel de couleur $color au point $point.
Les coordonnées de $point doivent être relatives à celles de la sous-image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.line"></a><span class="access">public</span> <a href="Driver.html#method.line">line</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Line.html"><span class="type">Line</span></a> <span class="argument">$line</span>)
<div class="description">
Dessine la ligne $line de couleur $color.
Les coordonnées de la ligne doivent être relatives à celles de la sous-image.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.arc"></a><span class="access">public</span> <a href="Driver.html#method.arc">arc</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>, <span class="type">float</span> <span class="argument">$from</span>, <span class="type">float</span> <span class="argument">$to</span>)
<div class="description">
Dessine un arc d'ellipse de couleur $color dont les deux extrémités sont reliées au centre de l'ellipse.
L'ellipse a pour centre $center et est de largeur et hauteur respectives $width et $height.
L'angle de départ pour l'arc est $from et l'angle d'arrivée $to.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.filledArc">Driver::filledArc()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.filledArc"></a><span class="access">public</span> <a href="Driver.html#method.filledArc">filledArc</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>, <span class="type">float</span> <span class="argument">$from</span>, <span class="type">float</span> <span class="argument">$to</span>)
<div class="description">
Dessine un arc d'ellipse dont les deux extrémités sont reliées au centre de l'ellipse et le remplit avec la couleur ou le dégradé $background.
L'ellipse a pour centre $center et est de largeur et hauteur respectives $width et $height.
L'angle de départ pour l'arc est $from et l'angle d'arrivée $to.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.arc">Driver::arc()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.ellipse"></a><span class="access">public</span> <a href="Driver.html#method.ellipse">ellipse</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
<div class="description">
Dessine une ellipse de couleur $color, ayant pour centre $center et de largeur et hauteur respectives $width et $height.
Les coordonnées de l'ellipse doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.filledEllipse">Driver::filledEllipse()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.filledEllipse"></a><span class="access">public</span> <a href="Driver.html#method.filledEllipse">filledEllipse</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$center</span>, <span class="type">int</span> <span class="argument">$width</span>, <span class="type">int</span> <span class="argument">$height</span>)
<div class="description">
Dessine et remplit une ellipse avec la couleur ou le dégradé $background. Cette ellipse a pour centre $center et est de largeur et hauteur respectives $width et $height.
Les coordonnées de l'ellipse doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.ellipse">Driver::ellipse()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.rectangle"></a><span class="access">public</span> <a href="Driver.html#method.rectangle">rectangle</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Line.html"><span class="type">Line</span></a> <span class="argument">$line</span>)
<div class="description">
Dessine un rectangle de couleur $color dont la ligne $line représente la diagonale.
Les coordonnées du rectangle doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.filledRectangle">Driver::filledRectangle()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.filledRectangle"></a><span class="access">public</span> <a href="Driver.html#method.filledRectangle">filledRectangle</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Line.html"><span class="type">Line</span></a> <span class="argument">$line</span>)
<div class="description">
Dessine et remplit un rectangle avec la couleur ou le dégradé $background dont la ligne $line représente la diagonale.
Les coordonnées du rectangle doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.rectangle">Driver::rectangle()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.polygon"></a><span class="access">public</span> <a href="Driver.html#method.polygon">polygon</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>, <a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
<div class="description">
Dessine le polygone $polygon de couleur $color.
Les coordonnées de chaque point du polygone doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.filledPolygon">Driver::filledPolygon()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.filledPolygon"></a><span class="access">public</span> <a href="Driver.html#method.filledPolygon">filledPolygon</a>(<span class="type">mixed</span> <span class="argument">$background</span>, <a href="Polygon.html"><span class="type">Polygon</span></a> <span class="argument">$polygon</span>)
<div class="description">
Dessine et remplit le polygone $polygon avec la couleur ou le dégradé $background.
Les coordonnées de chaque point du polygone doivent être relatives à celles de la sous-image.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.polygon">Driver::polygon()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getTextWidth"></a><span class="access">public</span> <span class="type">float</span> <a href="Driver.html#method.getTextWidth">getTextWidth</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Renvoie la largeur prise sur l'image par le <a href="Text.html">Text</a> $text.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.getTextHeight">Driver::getTextHeight()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getTextHeight"></a><span class="access">public</span> <span class="type">float</span> <a href="Driver.html#method.getTextHeight">getTextHeight</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Renvoie la hauteur prise sur l'image par le <a href="Text.html">Text</a> $text.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.getTextWidth">Driver::getTextWidth()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.isCompatibleWithFont"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Driver.html#method.isCompatibleWithFont">isCompatibleWithFont</a>(<a href="Font.html"><span class="type">Font</span></a> <span class="argument">$font</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Renvoie TRUE si le pilote actuel est compatible avec la police $font, FALSE sinon.
Chaque pilote doit définir les polices avec lesquelles il est compatible.
</div>
<div class="description-bottom"><a href="Driver.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/PlotGroup.html
New file
0,0 → 1,156
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class PlotGroup</h2><div class="extends"><ul>
<li><a href="Component.html">Component</a></li>
<ul>
<li><a href="ComponentGroup.html">ComponentGroup</a></li>
<ul><li>PlotGroup</li></ul>
</ul>
</ul></div><div class="description">
<p>
Cette classe permet de gérer plusieurs objets <a href="Plot.html">Plot</a> sur le même graphique.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <a href="Grid.html"><span class="type">Grid</span></a> <a href="PlotGroup.html#property.grid"><span class="argument">$grid</span></a>
</li>
<li>
<span class="access">public</span> <a href="PlotAxis.html"><span class="type">PlotAxis</span></a> <a href="PlotGroup.html#property.axis"><span class="argument">$axis</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="PlotGroup.html#property.xAxisZero"><span class="argument">$xAxisZero</span></a> := <span class="default">TRUE</span>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="PlotGroup.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="PlotGroup.html#method.setXAxisZero">setXAxisZero</a>(<span class="type">bool</span> <span class="argument">$zero</span>)
</li>
<li>
<span class="access">public</span> <a href="PlotGroup.html#method.setYAxisZero">setYAxisZero</a>(<span class="type">bool</span> <span class="argument">$zero</span>)
</li>
<li>
<span class="access">public</span> <a href="PlotGroup.html#method.setYMin">setYMin</a>(<span class="type">float</span> <span class="argument">$value</span>)
</li>
<li>
<span class="access">public</span> <a href="PlotGroup.html#method.setYMax">setYMax</a>(<span class="type">float</span> <span class="argument">$value</span>)
</li>
<li>
<span class="access">public</span> <a href="PlotGroup.html#method.setXMin">setXMin</a>(<span class="type">float</span> <span class="argument">$value</span>)
</li>
<li>
<span class="access">public</span> <a href="PlotGroup.html#method.setXMax">setXMax</a>(<span class="type">float</span> <span class="argument">$value</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.grid"></a><span class="access">public</span> <a href="Grid.html"><span class="type">Grid</span></a> <a href="PlotGroup.html#property.grid"><span class="argument">$grid</span></a><div class="description">
Représente la grille de fond du groupe de <a href="Plot.html">Plot</a>.
</div>
<div class="description-bottom"><a href="PlotGroup.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.axis"></a><span class="access">public</span> <a href="PlotAxis.html"><span class="type">PlotAxis</span></a> <a href="PlotGroup.html#property.axis"><span class="argument">$axis</span></a><div class="description">
Représente les axes de gauche, droite, du haut et du bas du groupe de <a href="Plot.html">Plot</a>.
</div>
<div class="description-bottom"><a href="PlotGroup.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.xAxisZero"></a><span class="access">protected</span> <span class="type">bool</span> <a href="PlotGroup.html#property.xAxisZero"><span class="argument">$xAxisZero</span></a> := <span class="default">TRUE</span><div class="description">
Est-ce le ou les axes des abscisses doivent être centrés sur zéro ?
</div>
<div class="description-bottom"><a href="PlotGroup.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="PlotGroup.html#method.__construct">__construct</a>()
<div class="description">
Construit le groupe de <a href="Plot.html">Plot</a>.
</div>
<div class="description-bottom"><a href="PlotGroup.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setXAxisZero"></a><span class="access">public</span> <a href="PlotGroup.html#method.setXAxisZero">setXAxisZero</a>(<span class="type">bool</span> <span class="argument">$zero</span>)
<div class="description">
Précise si le ou les axes des abscisses doivent être centrés sur le zéro de l'axe des ordonnées.
</div>
<div class="description-bottom"><a href="PlotGroup.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setYAxisZero"></a><span class="access">public</span> <a href="PlotGroup.html#method.setYAxisZero">setYAxisZero</a>(<span class="type">bool</span> <span class="argument">$zero</span>)
<div class="description">
Précise si le ou les axes des ordonnées doivent être centrés sur le zéro de l'axe des abscisses.
</div>
<div class="description-bottom"><a href="PlotGroup.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setYMin"></a><span class="access">public</span> <a href="PlotGroup.html#method.setYMin">setYMin</a>(<span class="type">float</span> <span class="argument">$value</span>)
<div class="description">
Force la valeur minimale de l'axe des ordonnées à $value.
<div class="see">
Voir aussi :
<ul><li><a href="PlotGroup.html#method.setYMax">PlotGroup::setYMax()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="PlotGroup.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setYMax"></a><span class="access">public</span> <a href="PlotGroup.html#method.setYMax">setYMax</a>(<span class="type">float</span> <span class="argument">$value</span>)
<div class="description">
Force la valeur maximale de l'axe des ordonnées à $value.
<div class="see">
Voir aussi :
<ul><li><a href="PlotGroup.html#method.setYMin">PlotGroup::setYMin()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="PlotGroup.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setXMin"></a><span class="access">public</span> <a href="PlotGroup.html#method.setXMin">setXMin</a>(<span class="type">float</span> <span class="argument">$value</span>)
<div class="description">
Force la valeur minimale de l'axe des abscisses à $value.
<div class="see">
Voir aussi :
<ul><li><a href="PlotGroup.html#method.setXMax">PlotGroup::setXMax()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="PlotGroup.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setXMax"></a><span class="access">public</span> <a href="PlotGroup.html#method.setXMax">setXMax</a>(<span class="type">float</span> <span class="argument">$value</span>)
<div class="description">
Force la valeur maximale de l'axe des abscisses à $value.
<div class="see">
Voir aussi :
<ul><li><a href="PlotGroup.html#method.setXMin">PlotGroup::setXMin()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="PlotGroup.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Shape.html
New file
0,0 → 1,177
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Shape</h2><div class="description">
<p>La classe <a href="Shape.html">Shape</a> permet de représenter toutes sortes de formes sur Artichow.</p>
</div><div class="inherit">
Les classes suivantes dérivent de Shape :
<ul>
<li><a href="Point.html">Point</a></li>
<li><a href="Line.html">Line</a></li>
<li><a href="Polygon.html">Polygon</a></li>
</ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="constants">
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Shape.html#constant.SOLID">SOLID</a> := <span class="default">1</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Shape.html#constant.DOTTED">DOTTED</a> := <span class="default">2</span>
</li>
<li>
<span class="access">const</span> <span class="type">int</span> <a href="Shape.html#constant.DASHED">DASHED</a> := <span class="default">3</span>
</li>
</ul><ul class="properties">
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Shape.html#property.style"><span class="argument">$style</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Shape.html#property.thickness"><span class="argument">$thickness</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Shape.html#property.hide"><span class="argument">$hide</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Shape.html#method.__construct">__construct</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
</li>
<li>
<span class="access">public</span> <a href="Shape.html#method.setStyle">setStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Shape.html#method.getStyle">getStyle</a>()
</li>
<li>
<span class="access">public</span> <a href="Shape.html#method.setThickness">setThickness</a>(<span class="type">int</span> <span class="argument">$thickness</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Shape.html#method.getThickness">getThickness</a>()
</li>
<li>
<span class="access">public</span> <a href="Shape.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
</li>
<li>
<span class="access">public</span> <a href="Shape.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span>)
</li>
<li>
<span class="access">public</span> <span class="type">bool</span> <a href="Shape.html#method.isHidden">isHidden</a>()
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="constant">
<a id="constant.SOLID"></a><span class="access">const</span> <span class="type">int</span> <a href="Shape.html#constant.SOLID">SOLID</a> := <span class="default">1</span><div class="description">
Désigne une ligne continue.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.DOTTED"></a><span class="access">const</span> <span class="type">int</span> <a href="Shape.html#constant.DOTTED">DOTTED</a> := <span class="default">2</span><div class="description">
Désigne une ligne pointillée.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="constant">
<a id="constant.DASHED"></a><span class="access">const</span> <span class="type">int</span> <a href="Shape.html#constant.DASHED">DASHED</a> := <span class="default">3</span><div class="description">
Désigne une ligne avec de larges pointillés.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.style"></a><span class="access">public</span> <span class="type">int</span> <a href="Shape.html#property.style"><span class="argument">$style</span></a><div class="description">
Décrit le style du pourtour de la forme. Peut être <a href="Shape.html#constant.DOTTED">Shape::DOTTED</a>, <a href="Shape.html#constant.SOLID">Shape::SOLID</a> ou <a href="Shape.html#constant.DASHED">Shape::DASHED</a>.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.thickness"></a><span class="access">public</span> <span class="type">int</span> <a href="Shape.html#property.thickness"><span class="argument">$thickness</span></a><div class="description">
L'épaisseur du pourtour de la forme.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.hide"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Shape.html#property.hide"><span class="argument">$hide</span></a><div class="description">
Déterminer si la forme doit être cachée ou non.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Shape.html#method.__construct">__construct</a>(<span class="type">float</span> <span class="argument">$x</span>, <span class="type">float</span> <span class="argument">$y</span>)
<div class="description">
Déclare un nouveau point avec des coordonnées x et y.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setStyle"></a><span class="access">public</span> <a href="Shape.html#method.setStyle">setStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
<div class="description">
Change le style du pourtour de la forme. Peut être <a href="Shape.html#constant.SOLID">Shape::SOLID</a> pour un pourtour continu, <a href="Shape.html#constant.DOTTED">Shape::DOTTED</a> pour un pourtour pointillé ou encore <a href="Shape.html#constant.DASHED">Shape::DASHED</a>.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getStyle"></a><span class="access">public</span> <span class="type">int</span> <a href="Shape.html#method.getStyle">getStyle</a>()
<div class="description">
Retourne le style actuel de la forme.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setThickness"></a><span class="access">public</span> <a href="Shape.html#method.setThickness">setThickness</a>(<span class="type">int</span> <span class="argument">$thickness</span>)
<div class="description">
Change l'épaisseur du pourtour de la forme. Cette épaisseur doit être donnée en pixels.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getThickness"></a><span class="access">public</span> <span class="type">int</span> <a href="Shape.html#method.getThickness">getThickness</a>()
<div class="description">
Retourne l'épaisseur du pourtour de la forme.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hide"></a><span class="access">public</span> <a href="Shape.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span>)
<div class="description">
Détermine si la forme doit être cachée ou non.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.show"></a><span class="access">public</span> <a href="Shape.html#method.show">show</a>(<span class="type">bool</span> <span class="argument">$show</span>)
<div class="description">
Détermine si la forme doit être affichée ou non.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.isHidden"></a><span class="access">public</span> <span class="type">bool</span> <a href="Shape.html#method.isHidden">isHidden</a>()
<div class="description">
Retourne TRUE si la forme est cachée, FALSE si elle est visible.
</div>
<div class="description-bottom"><a href="Shape.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Axis.html
New file
0,0 → 1,385
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Axis</h2><div class="description">
<p>
La classe <a href="Axis.html">Axis</a> permet de manipuler des axes.
Un axe permet à un utilisateur de répérer les points et leurs valeurs sur un graphique.
</p>
<p>
De nombreuses méthodes de la classe <a href="Axis.html">Axis</a> ne sont pas documentées,
car elles ne sont utilisées qu'en interne par Artichow.
Néanmoins, si vous développez Artichow, vous aurez besoin de ces méthodes.
N'hésitez donc pas à parcourir le code source de cette classe.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="Axis.html#property.title"><span class="argument">$title</span></a>
</li>
<li>
<span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="Axis.html#property.label"><span class="argument">$label</span></a>
</li>
<li>
<span class="access">public</span> <a href="Line.html"><span class="type">Line</span></a> <a href="Axis.html#property.line"><span class="argument">$line</span></a>
</li>
<li>
<span class="access">protected</span> <span class="type">bool</span> <a href="Axis.html#property.auto"><span class="argument">$auto</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="Axis.html#method.__construct">__construct</a>(<span class="type">float</span> <span class="argument">$min</span>, <span class="type">float</span> <span class="argument">$max</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.auto">auto</a>(<span class="type">bool</span> <span class="argument">$auto</span>)
</li>
<li>
<span class="access">public</span> <a href="true.html"><span class="type">true</span></a> <a href="Axis.html#method.isAuto">isAuto</a>()
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.addTick">addTick</a>(<span class="type">string</span> <span class="argument">$name</span>, <a href="Tick.html"><span class="type">Tick</span></a> <span class="argument">$tick</span>)
</li>
<li>
<span class="access">public</span> <a href="Tick.html"><span class="type">Tick</span></a> <a href="Axis.html#method.tick">tick</a>(<span class="type">string</span> <span class="argument">$name</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.deleteTick">deleteTick</a>(<span class="type">string</span> <span class="argument">$name</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.hideTicks">hideTicks</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setTickStyle">setTickStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.reverseTickStyle">reverseTickStyle</a>()
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setTickInterval">setTickInterval</a>(<span class="type">int</span> <span class="argument">$interval</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setNumberByTick">setNumberByTick</a>(<span class="type">string</span> <span class="argument">$to</span>, <span class="type">string</span> <span class="argument">$from</span>, <span class="type">float</span> <span class="argument">$number</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setLabelInterval">setLabelInterval</a>(<span class="type">int</span> <span class="argument">$interval</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setLabelNumber">setLabelNumber</a>(<span class="type">int</span> <span class="argument">$number</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="Axis.html#method.getLabelNumber">getLabelNumber</a>()
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setLabelPrecision">setLabelPrecision</a>(<span class="type">int</span> <span class="argument">$precision</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setLabelText">setLabelText</a>(<span class="type">array</span> <span class="argument">$texts</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setTitleAlignment">setTitleAlignment</a>(<span class="type">int</span> <span class="argument">$alignment</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setTitlePosition">setTitlePosition</a>(<span class="type">float</span> <span class="argument">$postion</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
<li>
<span class="access">public</span> <a href="Axis.html#method.setPadding">setPadding</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>)
</li>
<li>
<span class="access">public</span> <a href="Side.html"><span class="type">Side</span></a> <a href="Axis.html#method.getPadding">getPadding</a>()
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.title"></a><span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="Axis.html#property.title"><span class="argument">$title</span></a><div class="description">
Représente le titre de l'axe.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.label"></a><span class="access">public</span> <a href="Label.html"><span class="type">Label</span></a> <a href="Axis.html#property.label"><span class="argument">$label</span></a><div class="description">
Représente les étiquettes qui portent les valeurs affichées sur l'axe.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.line"></a><span class="access">public</span> <a href="Line.html"><span class="type">Line</span></a> <a href="Axis.html#property.line"><span class="argument">$line</span></a><div class="description">
Représente la ligne de l'axe.
Vous pouvez modifier le style et l'épaisseur de cette ligne, pas ses coordonnées.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.auto"></a><span class="access">protected</span> <span class="type">bool</span> <a href="Axis.html#property.auto"><span class="argument">$auto</span></a><div class="description">
Précise si la gestion de l'axe doit être automatique ou non.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Axis.html#method.__construct">__construct</a>(<span class="type">float</span> <span class="argument">$min</span>, <span class="type">float</span> <span class="argument">$max</span>)
<div class="description">
Déclare un nouvel axe.
Les variables $min et $max représentent respectivement la valeurs minimales et maximales associées à l'axe.
Par exemple, choisir $min = -12 et $max = 42 signifie tout simplement que l'axe ira de -12 à 42.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.auto"></a><span class="access">public</span> <a href="Axis.html#method.auto">auto</a>(<span class="type">bool</span> <span class="argument">$auto</span>)
<div class="description">
Active/désactive la gestion automatique de l'axe.
La gestion automatique est automatiquement désactivée en cas d'appel aux méthodes suivantes : <a href="Axis.html#method.setLabelNumber">Axis::setLabelNumber()</a>, <a href="Axis.html#method.setLabelInterval">Axis::setLabelInterval()</a>, <a href="Axis.html#method.setLabelPrecision">Axis::setLabelPrecision()</a> et <a href="Axis.html#method.setLabelText">Axis::setLabelText()</a>.
Lorsqu'un axe est sous gestion automatique, l'échelle est le nombre de valeurs à afficher sur l'axe sont automatiquement calculés.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.isAuto"></a><span class="access">public</span> <a href="true.html"><span class="type">true</span></a> <a href="Axis.html#method.isAuto">isAuto</a>()
<div class="description">
Retourne TRUE si l'axe est gérée automatiquement, FALSE sinon.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hide"></a><span class="access">public</span> <a href="Axis.html#method.hide">hide</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
<div class="description">
Cache ou non l'axe. Le paramètre $hide est par défaut à TRUE (ce qui signifie que l'axe ne sera pas dessiné).
S'il est mis à FALSE, l'axe sera dessiné.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.addTick"></a><span class="access">public</span> <a href="Axis.html#method.addTick">addTick</a>(<span class="type">string</span> <span class="argument">$name</span>, <a href="Tick.html"><span class="type">Tick</span></a> <span class="argument">$tick</span>)
<div class="description">
Associe un objet <a href="Tick.html">Tick</a> $tick à l'axe.
Cet objet sera reconnu par le nom $name au sein de la classe <a href="Axis.html">Axis</a>.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.tick"></a><span class="access">public</span> <a href="Tick.html"><span class="type">Tick</span></a> <a href="Axis.html#method.tick">tick</a>(<span class="type">string</span> <span class="argument">$name</span>)
<div class="description">
Récupère un objet <a href="Tick.html">Tick</a> en fonction de son nom.
Cet objet doit avoir été précédemment ajouté avec la méthode <a href="Axis.html#method.addTick">Axis::addTick()</a>.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.deleteTick"></a><span class="access">public</span> <a href="Axis.html#method.deleteTick">deleteTick</a>(<span class="type">string</span> <span class="argument">$name</span>)
<div class="description">
Supprime l'objet <a href="Tick.html">Tick</a> de nom $name associé à l'axe.
Pour pouvoir être supprimé, cet objet doit avoir été précédemment ajouté avec la méthode <a href="Axis.html#method.addTick">Axis::addTick()</a>.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.hideTicks"></a><span class="access">public</span> <a href="Axis.html#method.hideTicks">hideTicks</a>(<span class="type">bool</span> <span class="argument">$hide</span> := <span class="default">TRUE</span>)
<div class="description">
Cache ou non tous les ticks qui ont été associés à cet axe.
<div class="see">
Voir aussi :
<ul><li><a href="Axis.html#method.addTick">Axis::addTick()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setTickStyle"></a><span class="access">public</span> <a href="Axis.html#method.setTickStyle">setTickStyle</a>(<span class="type">int</span> <span class="argument">$style</span>)
<div class="description">
Change le style de tous les ticks associés à l'axe pour $style.
<div class="see">
Voir aussi :
<ul><li><a href="Tick.html#method.setStyle">Tick::setStyle()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.reverseTickStyle"></a><span class="access">public</span> <a href="Axis.html#method.reverseTickStyle">reverseTickStyle</a>()
<div class="description">
Inverse le style de tous les ticks associés à l'axe pour $style.
Si les ticks étaient tournés vers l'extérieur, ils seront désormais tournés vers l'intérieur.
Et vice-versa.
<div class="see">
Voir aussi :
<ul><li><a href="Tick.html#method.setStyle">Tick::setStyle()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setTickInterval"></a><span class="access">public</span> <a href="Axis.html#method.setTickInterval">setTickInterval</a>(<span class="type">int</span> <span class="argument">$interval</span>)
<div class="description">
Change l'intervalle d'affichage de tous les ticks associés à l'axe pour $interval.
Cette méthode permet d'espacer l'affichage des ticks par rapport aux valeurs de l'axe.
<div class="see">
Voir aussi :
<ul><li><a href="Tick.html#method.setStyle">Tick::setStyle()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setNumberByTick"></a><span class="access">public</span> <a href="Axis.html#method.setNumberByTick">setNumberByTick</a>(<span class="type">string</span> <span class="argument">$to</span>, <span class="type">string</span> <span class="argument">$from</span>, <span class="type">float</span> <span class="argument">$number</span>)
<div class="description">
Cette méthode permet de modifier la fréquence d'affichage d'un objet <a href="Tick.html">Tick</a> par rapport à un autre.
$to représente l'objet dont la fréquence d'affichage doit être modifiée et $from l'objet auquel on se réfère.
A chaque fois qu'un tick $from sera affiché, on affichera $number ticks $to.
Si $number vaut 2, cela signifie que deux ticks $to seront affichés pour un tick $from.
Cette méthode prend tout son sens donc le cadre des <a href="Plot.html">Plot</a> par exemple :
<pre>
 
&lt;?php
 
require_once 'LinePlot.class.php';
 
$graph = new <a href="Graph.html">Graph</a>(400, 400);
 
$plot = new <a href="LinePlot.html">LinePlot</a>(array(1, 2, 3));
 
// Pour chaque tick major affiché,
// on affichera 10 ticks minor
$plot-&gt;xAxis-&gt;setNumberByTick('minor', 'major', 10);
 
$graph-&gt;<a href="Graph.html#method.add">add</a>($plot);
$graph-&gt;<a href="Graph.html#method.draw">draw</a>();
 
?&gt;
 
</pre>
Cela donne 10 ticks mineurs par tick majeur :
<div class="image">
<img src="doc/image/ticks.png" alt="10 ticks mineurs par tick majeur">
</div>
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLabelInterval"></a><span class="access">public</span> <a href="Axis.html#method.setLabelInterval">setLabelInterval</a>(<span class="type">int</span> <span class="argument">$interval</span>)
<div class="description">
Change l'intervalle d'affichage des étiquettes sur l'axe pour $interval.
Par défaut, cet intervalle est égal à 1.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLabelNumber"></a><span class="access">public</span> <a href="Axis.html#method.setLabelNumber">setLabelNumber</a>(<span class="type">int</span> <span class="argument">$number</span>)
<div class="description">
Change le nombre d'étiquettes à afficher sur l'axe pour $number.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getLabelNumber"></a><span class="access">public</span> <span class="type">int</span> <a href="Axis.html#method.getLabelNumber">getLabelNumber</a>()
<div class="description">
Retourne le nombre d'étiquettes qui seront affichées sur l'axe.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLabelPrecision"></a><span class="access">public</span> <a href="Axis.html#method.setLabelPrecision">setLabelPrecision</a>(<span class="type">int</span> <span class="argument">$precision</span>)
<div class="description">
Change la précision des valeurs affichées sur chaque étiquette de l'axe.
$number représente le nombre de chiffres après la virgule qui doivent être affiché.
Par défaut, $precision vaut 0.
<div class="see">
Voir aussi :
<ul>
<li><a href="Axis.html#method.setLabelText">Axis::setLabelText()</a></li>
<li><a href="Label.html#method.setCallbackFunction">Label::setCallbackFunction()</a></li>
</ul>
</div>
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setLabelText"></a><span class="access">public</span> <a href="Axis.html#method.setLabelText">setLabelText</a>(<span class="type">array</span> <span class="argument">$texts</span>)
<div class="description">
Cette méthode permet d'afficher des valeurs arbitraires plutôt que des valeurs numériques sur les étiquettes de l'axe.
$texts est un tableau comportant autant d'entrées que d'étiquettes et qui contient les nouvelles valeurs à afficher.
<div class="see">
Voir aussi :
<ul>
<li><a href="Axis.html#method.setLabelPrecision">Axis::setLabelPrecision()</a></li>
<li><a href="Label.html#method.setCallbackFunction">Label::setCallbackFunction()</a></li>
</ul>
</div>
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setTitleAlignment"></a><span class="access">public</span> <a href="Axis.html#method.setTitleAlignment">setTitleAlignment</a>(<span class="type">int</span> <span class="argument">$alignment</span>)
<div class="description">
Change l'alignement du titre de l'axe sur l'axe.
Les valeurs possibles sont <a href="Label.html#constant.LEFT">Label::LEFT</a>, <a href="Label.html#constant.RIGHT">Label::RIGHT</a>, <a href="Label.html#constant.TOP">Label::TOP</a> et <a href="Label.html#constant.BOTTOM">Label::BOTTOM</a>.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setTitlePosition"></a><span class="access">public</span> <a href="Axis.html#method.setTitlePosition">setTitlePosition</a>(<span class="type">float</span> <span class="argument">$postion</span>)
<div class="description">
Change la position du titre sur l'axe.
$position est une fraction de la taille de l'axe.
Par exemple, si $position est placé à 0.5, le titre sera affiché au milieu de l'axe.
Si $position vaut 0.25, alors le titre sera affiché sur le premier quart de l'axe.
Pour aligner le titre par rapport à cette position, utilisez la méthode <a href="Axis.html#method.setTitleAlignment">Axis::setTitleAlignment()</a>.
<div class="see">
Voir aussi :
<ul><li><a href="Axis.html#method.setTitleAlignment">Axis::setTitleAlignment()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setColor"></a><span class="access">public</span> <a href="Axis.html#method.setColor">setColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Change la couleur de l'axe et de son titre pour $color.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setPadding"></a><span class="access">public</span> <a href="Axis.html#method.setPadding">setPadding</a>(<span class="type">int</span> <span class="argument">$left</span>, <span class="type">int</span> <span class="argument">$right</span>)
<div class="description">
Change l'espace interne à gauche et à droite de l'axe.
Gauche et droite n'ont de sens que pour les axes verticaux.
Pour les axes plus horizontaux, préférez haut à gauche et bas à droite.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getPadding"></a><span class="access">public</span> <a href="Side.html"><span class="type">Side</span></a> <a href="Axis.html#method.getPadding">getPadding</a>()
<div class="description">
Retourne l'espace interne associé à l'axe.
</div>
<div class="description-bottom"><a href="Axis.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/GDDriver.html
New file
0,0 → 1,72
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class GDDriver</h2><div class="extends"><ul>
<li><a href="Driver.html">Driver</a></li>
<ul><li>GDDriver</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="GDDriver.html">GDDriver</a> est une implémentation de <a href="Driver.html">Driver</a> qui repose sur la bibliothèque GD. C'est le pilote par défaut utilisé par Artichow, PHP doit donc être compilé avec le support de GD pour que tout fonctionne.
</p>
<p>
Seules seront mentionnées ici les méthodes dont l'implémentation pourrait avoir un comportement spécifique. Pour le reste, veuillez vous référer à la doc de la classe parente <a href="Driver.html">Driver</a>.
</p>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties"><li>
<span class="access">public</span> <span class="type">resource</span> <a href="GDDriver.html#property.resource"><span class="argument">$resource</span></a>
</li></ul><ul class="methods">
<li>
<span class="access">public</span> <a href="GDDriver.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="GDDriver.html#method.getColor">getColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.resource"></a><span class="access">public</span> <span class="type">resource</span> <a href="GDDriver.html#property.resource"><span class="argument">$resource</span></a><div class="description">
La ressource GD contenant le dessin.
</div>
<div class="description-bottom"><a href="GDDriver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="GDDriver.html#method.__construct">__construct</a>()
<div class="description">
Construit le pilote.
Instancie les <a href="FontDriver.html">FontDriver</a> et initialise la propriété <a href="Driver.html#property.driverString">driverString</a> à 'gd'.
</div>
<div class="description-bottom"><a href="GDDriver.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getColor"></a><span class="access">public</span> <span class="type">int</span> <a href="GDDriver.html#method.getColor">getColor</a>(<a href="Color.html"><span class="type">Color</span></a> <span class="argument">$color</span>)
<div class="description">
Convertit un objet <a href="Color.html">Color</a> pour qu'il soit exploitable directement par les fonctions de dessins de GD.
Renvoie un entier identifiant la couleur aux yeux de GD.
</div>
<div class="description-bottom"><a href="GDDriver.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/Font.html
New file
0,0 → 1,96
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class Font</h2><div class="description">
<p>
La classe abstraite <a href="Font.html">Font</a> permet de gérer les polices de manière uniforme sur Artichow.
</p>
</div><div class="inherit">
Les classes suivantes dérivent de Font :
<ul>
<li><a href="PHPFont.html">PHPFont</a></li>
<li><a href="FileFont.html">FileFont</a></li>
</ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="methods">
<li>
<span class="access">public</span> <a href="Font.html#method.__construct">__construct</a>()
</li>
<li>
<span class="access">public</span> <a href="Font.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>, <a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>, <span class="type">int</span> <span class="argument">$width</span> := <span class="default">NULL</span>)
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Font.html#method.getTextWidth">getTextWidth</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
</li>
<li>
<span class="access">public</span> <span class="type">float</span> <a href="Font.html#method.getTextHeight">getTextHeight</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="Font.html#method.__construct">__construct</a>()
<div class="description">
Construit la police.
</div>
<div class="description-bottom"><a href="Font.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.draw"></a><span class="access">public</span> <a href="Font.html#method.draw">draw</a>(<a href="Driver.html"><span class="type">Driver</span></a> <span class="argument">$driver</span>, <a href="Point.html"><span class="type">Point</span></a> <span class="argument">$point</span>, <a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>, <span class="type">int</span> <span class="argument">$width</span> := <span class="default">NULL</span>)
<div class="description">
Dessine avec la police courante le texte $text.
Le pilote $driver sera utilisé pour le dessin tandis que le texte sera positionné au point $point.
Le paramètre $width permet de spécifier la largeur maximale en pixels de la boîte de texte.
</div>
<div class="description-bottom"><a href="Font.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getTextWidth"></a><span class="access">public</span> <span class="type">float</span> <a href="Font.html#method.getTextWidth">getTextWidth</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
<ul class="version"><li>
Supprimé à partir d'Artichow 1.1</li></ul>
<div class="description">
Retourne la largeur en pixels occupée par l'objet <a href="Text.html">Text</a> $text.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.getTextWidth">Driver::getTextWidth()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Font.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getTextHeight"></a><span class="access">public</span> <span class="type">float</span> <a href="Font.html#method.getTextHeight">getTextHeight</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
<ul class="version"><li>
Supprimé à partir d'Artichow 1.1</li></ul>
<div class="description">
Retourne la hauteur en pixels occupée par l'objet <a href="Text.html">Text</a> $text.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.getTextHeight">Driver::getTextHeight()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="Font.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/doc/FileFont.html
New file
0,0 → 1,214
<html>
<head>
<title>Documentation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='style.css' />
</head>
 
<body>
<div align='center'>
<table cellpadding='0' cellspacing='0' id='contenu' class='round' style='width: 80%; margin-bottom: 20px'>
<tr>
<td class='borderhg'>&nbsp;</td>
<td class='borderh'>&nbsp;</td>
<td class='cornerhd'></td>
</tr>
<tr>
<td class='borderg'>&nbsp;</td>
<td><a id="top"></a><h2> Class FileFont</h2><div class="extends"><ul>
<li><a href="Font.html">Font</a></li>
<ul><li>FileFont</li></ul>
</ul></div><div class="description">
<p>
La classe <a href="FileFont.html">FileFont</a> permet de gérer les polices représentée par un fichier, donc externe à PHP.
Quelques polices sont disponibles dans le répertoire <span style="font-weight: bold">font/</span> de Artichow.
Si vous connaissez d'autres polices intéressantes et dans le domaine public, n'hésitez pas à le signaler à <span style="text-decoration: underline">vincent</span> sur <span style="text-decoration: underline">artichow point org</span>.
</p>
<p>
Afin de simplifier l'utilisation de cette classe, plusieurs polices sont déjà prédéfinies sur Artichow.
Chacune de ces polices est une classe qui dérive de <a href="FileFont.html">FileFont</a> et dont le constructeur ne prend qu'un paramètre, la taille de la police. Voici les polices prédéfinies :
</p>
<ul>
<li>
<em>Famille Tuffy :</em> Tuffy, TuffyBold, TuffyItalic, TuffyBoldItalic</li>
</ul>
<p>
Voici un exemple d'utilisation pour les polices prédéfinies :
<pre>
 
&lt;?php
 
// On utilise Tuffy de taille 12
// Equivalent à new <a href="FileFont.html">FileFont</a>(ARTICHOW_FONT.'/Tuffy.ttf', 12);
$blue = new Tuffy(12);
 
// On utilise Tuffy en italique taille 42
// Equivalent à new <a href="FileFont.html">FileFont</a>(ARTICHOW_FONT.'/TuffyItalic.ttf', 42);
$orange = new TuffyItalic(42);
 
?&gt;
 
</pre>
</p>
</div><div class="inherit">
Les classes suivantes dérivent de FileFont :
<ul><li><a href="TTFFont.html">TTFFont</a></li></ul>
</div><ul class="links"><li><a href="index.html">Retourner voir la liste de toutes les classes</a></li></ul><h2>Méthodes et propriétés</h2><ul class="properties">
<li>
<span class="access">public</span> <span class="type">string</span> <a href="FileFont.html#property.name"><span class="argument">$name</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="FileFont.html#property.size"><span class="argument">$size</span></a>
</li>
<li>
<span class="access">public</span> <span class="type">string</span> <a href="FileFont.html#property.extension"><span class="argument">$extension</span></a>
</li>
</ul><ul class="methods">
<li>
<span class="access">public</span> <a href="FileFont.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$name</span>, <span class="type">int</span> <span class="argument">$size</span>)
</li>
<li>
<span class="access">public</span> <a href="FileFont.html#method.setName">setName</a>(<span class="type">string</span> <span class="argument">$name</span>)
</li>
<li>
<span class="access">public</span> <span class="type">string</span> <a href="FileFont.html#method.getName">getName</a>()
</li>
<li>
<span class="access">public</span> <a href="FileFont.html#method.setSize">setSize</a>(<span class="type">int</span> <span class="argument">$size</span>)
</li>
<li>
<span class="access">public</span> <span class="type">int</span> <a href="FileFont.html#method.getSize">getSize</a>()
</li>
<li>
<span class="access">public</span> <a href="FileFont.html#method.setExtension">setExtension</a>(<span class="type">string</span> <span class="argument">$extension</span>)
</li>
<li>
<span class="access">public</span> <span class="type">string</span> <a href="FileFont.html#method.getExtension">getExtension</a>()
</li>
<li>
<span class="access">public</span> <a href="FileFont.html#method.getTextWidth">getTextWidth</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
</li>
<li>
<span class="access">public</span> <a href="FileFont.html#method.getTextHeight">getTextHeight</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
</li>
</ul><h2>Documentation</h2><ul class="doc">
<li class="property">
<a id="property.name"></a><span class="access">public</span> <span class="type">string</span> <a href="FileFont.html#property.name"><span class="argument">$name</span></a><div class="description">
Le nom du fichier contenant la police, sans l'extension.
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.size"></a><span class="access">public</span> <span class="type">int</span> <a href="FileFont.html#property.size"><span class="argument">$size</span></a><div class="description">
La taille de la police, en pixels.
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="property">
<a id="property.extension"></a><span class="access">public</span> <span class="type">string</span> <a href="FileFont.html#property.extension"><span class="argument">$extension</span></a><div class="description">
L'extension du fichier. Cette propriété est utile si deux polices pouvant être utilisé par plusieurs pilotes doivent avoir une extension différente selon le cas. Voir à ce sujet le classe <a href="TTFFont.html">TTFFont</a>.
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.__construct"></a><span class="access">public</span> <a href="FileFont.html#method.__construct">__construct</a>(<span class="type">string</span> <span class="argument">$name</span>, <span class="type">int</span> <span class="argument">$size</span>)
<div class="description">
Construit la police de nom $name et de taille $size.
Le nom doit être soit un chemin d'accès absolu, soit un simple nom de fichier. Dans ce dernier cas, la police correspondante sera recherchée dans le dossier <span style="font-weight: bold;">font/</span> d'Artichow.
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setName"></a><span class="access">public</span> <a href="FileFont.html#method.setName">setName</a>(<span class="type">string</span> <span class="argument">$name</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Définit le nom du fichier contenant les informations de la police.
Ce nom doit être soit un chemin d'accès absolu, soit un simple nom de fichier. Dans ce dernier cas, la police correspondante sera recherchée dans le dossier <span style="font-weight: bold;">font/</span> d'Artichow.
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getName"></a><span class="access">public</span> <span class="type">string</span> <a href="FileFont.html#method.getName">getName</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Renvoie l'extension du fichier contenant les informations de la police.
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setSize"></a><span class="access">public</span> <a href="FileFont.html#method.setSize">setSize</a>(<span class="type">int</span> <span class="argument">$size</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Définit la taille de la police, en pixels.
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getSize"></a><span class="access">public</span> <span class="type">int</span> <a href="FileFont.html#method.getSize">getSize</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Renvoie la taille de la police, en pixels.
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.setExtension"></a><span class="access">public</span> <a href="FileFont.html#method.setExtension">setExtension</a>(<span class="type">string</span> <span class="argument">$extension</span>)
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Définit l'extension du fichier contenant les informations de la police.
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getExtension"></a><span class="access">public</span> <span class="type">string</span> <a href="FileFont.html#method.getExtension">getExtension</a>()
<ul class="version"><li>
Disponible depuis Artichow 1.1</li></ul>
<div class="description">
Renvoie l'extension du fichier contenant les informations de la police.
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getTextWidth"></a><span class="access">public</span> <a href="FileFont.html#method.getTextWidth">getTextWidth</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
<ul class="version"><li>
Supprimé à partir d'Artichow 1.1</li></ul>
<div class="description">
Renvoie la largeur en pixels occupée par l'objet <a href="Text.html">Text</a> $text.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.getTextWidth">Driver::getTextWidth()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
<li class="method">
<a id="method.getTextHeight"></a><span class="access">public</span> <a href="FileFont.html#method.getTextHeight">getTextHeight</a>(<a href="Text.html"><span class="type">Text</span></a> <span class="argument">$text</span>)
<ul class="version"><li>
Supprimé à partir d'Artichow 1.1</li></ul>
<div class="description">
Renvoie la hauteur en pixels occupée par l'objet <a href="Text.html">Text</a> $text.
<div class="see">
Voir aussi :
<ul><li><a href="Driver.html#method.getTextHeight">Driver::getTextHeight()</a></li></ul>
</div>
</div>
<div class="description-bottom"><a href="FileFont.html#top">Remonter</a></div>
</li>
</ul>
</td>
<td class='borderd'>&nbsp;</td>
</tr>
<tr>
<td class='cornerbg'></td>
<td class='borderb'>&nbsp;</td>
<td class='cornerbd'></td>
</tr>
</table>
</div>
</body>
</html>
/tags/v1.0-Homere/bibliotheque/artichow/TODO
New file
0,0 → 1,13
- message d'erreur si MING n'est pas installé
 
- setLabelPrecision a un booleen pour déterminer s'il faut remplir avec des zéros ou non
 
- Label => TextBox
- Excel/Spider/Splines/Bezier
 
- doc de Pattern
- bug de la grille
- pouvoir tracer des lignes verticales et horizontales à n'importe quel endroit sur les Plots
- avant de parler de SimpleLinePlot, ajouter une classe CommonLinePlot, dont dérivent tous les LinePlot
 
- faire un mode auto pour les Pie (au delà d'un certain nombre de parts, grouper le reste sous l'étiquette 'Divers' (choisie par le user))
/tags/v1.0-Homere/bibliotheque/artichow/font/TuffyItalic.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/font/TuffyItalic.ttf
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/font/TuffyBoldItalic.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/font/TuffyBoldItalic.ttf
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/font/Tuffy.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/font/Tuffy.ttf
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/font/TuffyBold.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/v1.0-Homere/bibliotheque/artichow/font/TuffyBold.ttf
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/v1.0-Homere/bibliotheque/artichow/AntiSpam.class.php
New file
0,0 → 1,224
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/Image.class.php";
 
/**
* AntiSpam
* String printed on the images are case insensitive.
*
* @package Artichow
*/
class awAntiSpam extends awImage {
 
/**
* Anti-spam string
*
* @var string
*/
protected $string;
 
/**
* Noise intensity
*
* @var int
*/
protected $noise = 0;
/**
* Construct a new awAntiSpam image
*
* @param string $string A string to display
*/
public function __construct($string = '') {
parent::__construct();
$this->string = (string)$string;
}
/**
* Create a random string
*
* @param int $length String length
* @return string String created
*/
public function setRand($length) {
$length = (int)$length;
$this->string = '';
$letters = 'aAbBCDeEFgGhHJKLmMnNpPqQRsStTuVwWXYZz2345679';
$number = strlen($letters);
for($i = 0; $i < $length; $i++) {
$this->string .= $letters{mt_rand(0, $number - 1)};
}
return $this->string;
}
/**
* Set noise on image
*
* @param int $nois Noise intensity (from 0 to 10)
*/
public function setNoise($noise) {
if($noise < 0) {
$noise = 0;
}
if($noise > 10) {
$noise = 10;
}
$this->noise = (int)$noise;
}
/**
* Save string value in session
* You can use check() to verify the value later
*
* @param string $qName A name that identify the anti-spam image
*/
public function save($qName) {
$this->session();
$session = 'artichow_'.(string)$qName;
$_SESSION[$session] = $this->string;
}
/**
* Verify user entry
*
* @param string $qName A name that identify the anti-spam image
* @param string $value User-defined value
* @param bool $case TRUE for case insensitive check, FALSE for case sensitive check ? (default to TRUE)
* @return bool TRUE if the value is correct, FALSE otherwise
*/
public function check($qName, $value, $case = TRUE) {
$this->session();
$session = 'artichow_'.(string)$qName;
return (
array_key_exists($session, $_SESSION) === TRUE and
$case ?
(strtolower($_SESSION[$session]) === strtolower((string)$value)) :
($_SESSION[$session] === (string)$value)
);
}
/**
* Draw image
*/
public function draw() {
 
$fonts = array(
'Tuffy',
'TuffyBold',
'TuffyItalic',
'TuffyBoldItalic'
);
$sizes = array(12, 12.5, 13, 13.5, 14, 15, 16, 17, 18, 19);
$widths = array();
$heights = array();
$texts = array();
// Set up a temporary driver to allow font size calculations...
$this->setSize(10, 10);
$driver = $this->getDriver();
for($i = 0; $i < strlen($this->string); $i++) {
$fontKey = array_rand($fonts);
$sizeKey = array_rand($sizes);
$font = new awTTFFont(
$fonts[$fontKey], $sizes[$sizeKey]
);
$text = new awText(
$this->string{$i},
$font,
NULL,
mt_rand(-15, 15)
);
$widths[] = $driver->getTextWidth($text);
$heights[] = $driver->getTextHeight($text);
$texts[] = $text;
}
// ... and get rid of it.
$this->driver = NULL;
$width = array_sum($widths);
$height = array_max($heights);
$totalWidth = $width + 10 + count($texts) * 10;
$totalHeight = $height + 20;
$this->setSize($totalWidth, $totalHeight);
$this->create();
for($i = 0; $i < strlen($this->string); $i++) {
$this->driver->string(
$texts[$i],
new awPoint(
5 + array_sum(array_slice($widths, 0, $i)) + $widths[$i] / 2 + $i * 10,
10 + ($height - $heights[$i]) / 2
)
);
}
$this->drawNoise($totalWidth, $totalHeight);
$this->send();
}
protected function drawNoise($width, $height) {
$points = $this->noise * 30;
$color = new awColor(0, 0, 0);
for($i = 0; $i < $points; $i++) {
$this->driver->point(
$color,
new awPoint(
mt_rand(0, $width),
mt_rand(0, $height)
)
);
}
}
protected function session() {
// Start session if needed
if(!session_id()) {
session_start();
}
}
 
}
 
registerClass('AntiSpam');
?>
/tags/v1.0-Homere/bibliotheque/artichow/Pie.class.php
New file
0,0 → 1,695
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/Component.class.php";
/**
* Pie
*
* @package Artichow
*/
class awPie extends awComponent {
 
/**
* A dark theme for pies
*
*
* @var int
*/
const DARK = 1;
 
/**
* A colored theme for pies
*
* @var int
*/
const COLORED = 2;
 
/**
* A water theme for pies
*
* @var int
*/
const AQUA = 3;
 
/**
* A earth theme for pies
*
* @var int
*/
const EARTH = 4;
/**
* Pie values
*
* @var array
*/
protected $values;
/**
* Pie colors
*
* @var array
*/
protected $colors;
/**
* Pie legend
*
* @var array
*/
protected $legendValues = array();
/**
* Intensity of the 3D effect
*
* @var int
*/
protected $size;
/**
* Border color
*
* @var Color
*/
protected $border;
/**
* Pie explode
*
* @var array
*/
protected $explode = array();
/**
* Initial angle
*
* @var int
*/
protected $angle = 0;
/**
* Labels precision
*
* @var int
*/
protected $precision;
/**
* Labels number
*
* @var int
*/
protected $number;
/**
* Labels minimum
*
* @var int
*/
protected $minimum;
/**
* Labels position
*
* @var int
*/
protected $position = 15;
/**
* Labels of your pie
*
* @var Label
*/
public $label;
/**
* Build the plot
*
* @param array $values Pie values
*/
public function __construct($values, $colors = awPie::COLORED) {
$this->setValues($values);
if(is_array($colors)) {
$this->colors = $colors;
} else {
switch($colors) {
case awPie::AQUA :
$this->colors = array(
new awColor(131, 220, 215),
new awColor(131, 190, 215),
new awColor(131, 160, 215),
new awColor(160, 140, 215),
new awColor(190, 131, 215),
new awColor(220, 131, 215)
);
break;
case awPie::EARTH :
$this->colors = array(
new awColor(97, 179, 110),
new awColor(130, 179, 97),
new awColor(168, 179, 97),
new awColor(179, 147, 97),
new awColor(179, 108, 97),
new awColor(99, 107, 189),
new awColor(99, 165, 189)
);
break;
case awPie::DARK :
$this->colors = array(
new awColor(140, 100, 170),
new awColor(130, 170, 100),
new awColor(160, 160, 120),
new awColor(150, 110, 140),
new awColor(130, 150, 160),
new awColor(90, 170, 140)
);
break;
default :
$this->colors = array(
new awColor(187, 213, 151),
new awColor(223, 177, 151),
new awColor(111, 186, 132),
new awColor(197, 160, 230),
new awColor(165, 169, 63),
new awColor(218, 177, 89),
new awColor(116, 205, 121),
new awColor(200, 201, 78),
new awColor(127, 205, 177),
new awColor(205, 160, 160),
new awColor(190, 190, 190)
);
break;
}
}
parent::__construct();
$this->label = new awLabel;
$this->label->setCallbackFunction('callbackPerCent');
}
/**
* Change legend values
*
* @param array $legend An array of values for each part of the pie
*/
public function setLegend($legend) {
$this->legendValues = (array)$legend;
}
/**
* Set a border all around the pie
*
* @param awColor $color A color for the border
*/
public function setBorderColor(awColor $color) {
$this->border = $color;
}
/**
* Set a border all around the pie
*
* @param awColor $color A color for the border
*/
public function setBorder(awColor $color) {
if(ARTICHOW_DEPRECATED === TRUE) {
awImage::drawError('Class Pie: Method setBorder() has been deprecated since Artichow 1.0.9. Please use setBorderColor() instead.');
} else {
$this->setBorderColor($color);
}
}
/**
* Change 3D effect intensity
*
* @param int $size Effect size
*/
public function set3D($size) {
$this->size = (int)$size;
}
/**
* Change initial angle
*
* @param int $angle New angle in degrees
*/
public function setStartAngle($angle) {
$this->angle = (int)$angle;
}
/**
* Change label precision
*
* @param int $precision New precision
*/
public function setLabelPrecision($precision) {
$this->precision = (int)$precision;
}
/**
* Change label position
*
* @param int $position New position in pixels
*/
public function setLabelPosition($position) {
$this->position = (int)$position;
}
/**
* Change label number
*
* @param int $number New number
*/
public function setLabelNumber($number) {
$this->number = is_null($number) ? $number : (int)$number;
}
/**
* Change label minimum
*
* @param int $minimum New minimum
*/
public function setLabelMinimum($minimum) {
$this->minimum = is_null($minimum) ? $minimum : (int)$minimum;
}
/**
* Change Pie explode
*
* @param array $explode
*/
public function explode($explode) {
$this->explode = (array)$explode;
}
public function drawEnvelope(awDriver $driver) {
}
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
$count = count($this->values);
$sum = array_sum($this->values);
$width = $x2 - $x1;
$height = $y2 - $y1;
if($aliasing) {
$x = $width / 2;
$y = $height / 2;
} else {
$x = $width / 2 + $x1;
$y = $height / 2 + $y1;
}
$position = $this->angle;
$values = array();
$parts = array();
$angles = 0;
if($aliasing) {
$side = new awSide(0, 0, 0, 0);
}
foreach($this->values as $key => $value) {
$angle = ($value / $sum * 360);
if($key === $count - 1) {
$angle = 360 - $angles;
}
$angles += $angle;
if(array_key_exists($key, $this->explode)) {
$middle = 360 - ($position + $angle / 2);
$posX = $this->explode[$key] * cos($middle * M_PI / 180);
$posY = $this->explode[$key] * sin($middle * M_PI / 180) * -1;
if($aliasing) {
$explode = new awPoint(
$posX * 2,
$posY * 2
);
$side->set(
max($side->left, $posX * -2),
max($side->right, $posX * 2),
max($side->top, $posY * -2),
max($side->bottom, $posY * 2)
);
} else {
$explode = new awPoint(
$posX,
$posY
);
}
} else {
$explode = new awPoint(0, 0);
}
$values[$key] = array(
$position, ($position + $angle), $explode
);
$color = $this->colors[$key % count($this->colors)];
$parts[$key] = new awPiePart($color);
// Add part to the legend
$legend = array_key_exists($key, $this->legendValues) ? $this->legendValues[$key] : $key;
$this->legend->add($parts[$key], $legend, awLegend::BACKGROUND);
$position += $angle;
}
if($aliasing) {
$mainDriver = $driver;
$x *= 2;
$y *= 2;
$width *= 2;
$height *= 2;
$this->size *= 2;
$image = new awImage;
$image->border->hide();
// Adds support for antialiased pies on non-white background
$background = $this->getBackground();
if($background instanceof awColor) {
$image->setBackgroundColor($background);
}
// elseif($background instanceof awGradient) {
// $image->setBackgroundColor(new White(100));
// }
$image->setSize(
$width + $side->left + $side->right,
$height + $side->top + $side->bottom + $this->size + 1 /* bugs.php.net ! */
);
$driver = $image->getDriver(
$width / $image->width,
$height / $image->height,
($width / 2 + $side->left) / $image->width,
($height / 2 + $side->top) / $image->height
);
}
// Draw 3D effect
for($i = $this->size; $i > 0; $i--) {
foreach($values as $key => $value) {
$color = clone $this->colors[$key % count($this->colors)];
$color->brightness(-50);
list($from, $to, $explode) = $value;
$driver->filledArc($color, $explode->move($x, $y + $i), $width, $height, $from, $to);
unset($color);
if($this->border instanceof awColor) {
$point = $explode->move($x, $y);
if($i === $this->size) {
$driver->arc($this->border, $point->move(0, $this->size), $width, $height, $from, $to);
}
}
}
}
foreach($values as $key => $value) {
$color = $this->colors[$key % count($this->colors)];
list($from, $to, $explode) = $value;
$driver->filledArc($color, $explode->move($x, $y), $width, $height, $from, $to);
if($this->border instanceof awColor) {
$point = $explode->move($x, $y);
$driver->arc($this->border, $point, $width, $height, $from, $to);
}
}
if($aliasing) {
$x = $x / 2 + $x1;
$y = $y / 2 + $y1;
$width /= 2;
$height /= 2;
$this->size /= 2;
foreach($values as $key => $value) {
$old = $values[$key][2];
$values[$key][2] = new awPoint(
$old->x / 2, $old->y / 2
);
}
$mainDriver->copyResizeImage(
$image,
new awPoint($x1 - $side->left / 2, $y1 - $side->top / 2),
new awPoint($x1 - $side->left / 2 + $image->width / 2, $y1 - $side->top / 2 + $image->height/ 2),
new awPoint(0, 0),
new awPoint($image->width, $image->height),
TRUE
);
$driver = $mainDriver;
}
// Get labels values
$pc = array();
foreach($this->values as $key => $value) {
$pc[$key] = round($value / $sum * 100, $this->precision);
}
if($this->label->count() === 0) { // Check that there is no user defined values
$this->label->set($pc);
}
$position = 0;
foreach($pc as $key => $value) {
// Limit number of labels to display
if($position === $this->number) {
break;
}
if(is_null($this->minimum) === FALSE and $value < $this->minimum) {
continue;
}
$position++;
list($from, $to, $explode) = $values[$key];
$angle = $from + ($to - $from) / 2;
$angleRad = (360 - $angle) * M_PI / 180;
$point = new awPoint(
$x + $explode->x + cos($angleRad) * ($width / 2 + $this->position),
$y + $explode->y - sin($angleRad) * ($height / 2 + $this->position)
);
$angle %= 360;
// We don't display labels on the 3D effect
if($angle > 0 and $angle < 180) {
$point = $point->move(0, -1 * sin($angleRad) * $this->size);
}
if($angle >= 45 and $angle < 135) {
$this->label->setAlign(awLabel::CENTER, awLabel::BOTTOM);
} else if($angle >= 135 and $angle < 225) {
$this->label->setAlign(awLabel::RIGHT, awLabel::MIDDLE);
} else if($angle >= 225 and $angle < 315) {
$this->label->setAlign(awLabel::CENTER, awLabel::TOP);
} else {
$this->label->setAlign(awLabel::LEFT, awLabel::MIDDLE);
}
$this->label->draw(
$driver,
$point,
$key
);
}
}
/**
* Return margins around the component
*
* @return array Left, right, top and bottom margins
*/
public function getMargin() {
// Get axis informations
$leftAxis = $this->padding->left;
$rightAxis = $this->padding->right;
$topAxis = $this->padding->top;
$bottomAxis = $this->padding->bottom;
return array($leftAxis, $rightAxis, $topAxis, $bottomAxis);
}
/**
* Change values of Y axis
* This method ignores not numeric values
*
* @param array $values
*/
public function setValues($values) {
$this->checkArray($values);
$this->values = $values;
}
/**
* Return values of Y axis
*
* @return array
*/
public function getValues() {
return $this->values;
}
private function checkArray(&$array) {
if(is_array($array) === FALSE) {
awImage::drawError("Class Pie: You tried to set values that are not an array.");
}
foreach($array as $key => $value) {
if(is_numeric($value) === FALSE) {
unset($array[$key]);
}
}
if(count($array) < 1) {
awImage::drawError("Class Pie: Your graph must have at least 1 value.");
}
}
 
}
 
registerClass('Pie');
 
/**
* Pie
*
* @package Artichow
*/
class awPiePart implements awLegendable {
 
/**
* Pie part color
*
* @var Color
*/
protected $color;
 
/**
* Build a new awPiePart
*
* @param awColor $color Pie part color
*/
public function __construct(awColor $color) {
$this->color = $color;
}
 
/**
* Get the background color or gradient of an element of the component
*
* @return Color, Gradient
*/
public function getLegendBackground() {
return $this->color;
}
 
/**
* Get the line thickness
*
* @return NULL
*/
public function getLegendLineThickness() {
}
 
/**
* Get the line type
*
* @return NULL
*/
public function getLegendLineStyle() {
}
 
/**
* Get the color of line
*
* @return NULL
*/
public function getLegendLineColor() {
}
 
/**
* Get a mark object
*
* @return NULL
*/
public function getLegendMark() {
}
 
}
 
registerClass('PiePart');
 
function callbackPerCent($value) {
return $value.'%';
}
?>
/tags/v1.0-Homere/bibliotheque/artichow/Pattern.class.php
New file
0,0 → 1,97
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/Graph.class.php";
 
/**
* All patterns must derivate from this class
*
* @package Artichow
*/
abstract class awPattern {
 
/**
* Pattern arguments
*
* @var array
*/
protected $args = array();
/**
* Load a pattern
*
* @param string $pattern Pattern name
* @return Component
*/
public static function get($pattern) {
$file = ARTICHOW_PATTERN.DIRECTORY_SEPARATOR.$pattern.'.php';
if(is_file($file)) {
require_once $file;
$class = $pattern.'Pattern';
if(class_exists($class)) {
return new $class;
} else {
awImage::drawError("Class Pattern: Class '".$class."' does not exist.");
}
} else {
awImage::drawError("Class Pattern: Pattern '".$pattern."' does not exist.");
}
}
/**
* Change pattern argument
*
* @param string $name Argument name
* @param mixed $value Argument value
*/
public function setArg($name, $value) {
if(is_string($name)) {
$this->args[$name] = $value;
}
}
/**
* Get an argument
*
* @param string $name
* @param mixed $default Default value if the argument does not exist (default to NULL)
* @return mixed Argument value
*/
protected function getArg($name, $default = NULL) {
if(array_key_exists($name, $this->args)) {
return $this->args[$name];
} else {
return $default;
}
}
/**
* Change several arguments
*
* @param array $args New arguments
*/
public function setArgs($args) {
if(is_array($args)) {
foreach($args as $name => $value) {
$this->setArg($name, $value);
}
}
}
 
}
 
registerClass('Pattern', TRUE);
?>
/tags/v1.0-Homere/bibliotheque/artichow/Plot.class.php
New file
0,0 → 1,1464
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/Component.class.php";
/**
* Graph using X and Y axis
*
* @package Artichow
*/
abstract class awPlot extends awComponent {
/**
* Values for Y axis
*
* @var array
*/
protected $datay;
 
/**
* Values for X axis
*
* @var array
*/
protected $datax;
/**
* Grid properties
*
* @var Grid
*/
public $grid;
/**
* X axis
*
* @var Axis
*/
public $xAxis;
/**
* Y axis
*
* @var Axis
*/
public $yAxis;
/**
* Position of X axis
*
* @var int
*/
protected $xAxisPosition = awPlot::BOTTOM;
/**
* Set X axis on zero ?
*
* @var bool
*/
protected $xAxisZero = TRUE;
/**
* Set Y axis on zero ?
*
* @var bool
*/
protected $yAxisZero = FALSE;
/**
* Position of Y axis
*
* @var int
*/
protected $yAxisPosition = awPlot::LEFT;
/**
* Change min value for Y axis
*
* @var mixed
*/
private $yMin = NULL;
/**
* Change max value for Y axis
*
* @var mixed
*/
private $yMax = NULL;
/**
* Change min value for X axis
*
* @var mixed
*/
private $xMin = NULL;
/**
* Change max value for X axis
*
* @var mixed
*/
private $xMax = NULL;
/**
* Left axis
*
* @var int
*/
const LEFT = 'left';
/**
* Right axis
*
* @var int
*/
const RIGHT = 'right';
/**
* Top axis
*
* @var int
*/
const TOP = 'top';
/**
* Bottom axis
*
* @var int
*/
const BOTTOM = 'bottom';
/**
* Both left/right or top/bottom axis
*
* @var int
*/
const BOTH = 'both';
/**
* Build the plot
*
*/
public function __construct() {
parent::__construct();
$this->grid = new awGrid;
$this->grid->setBackgroundColor(new awWhite);
 
$this->padding->add(20, 0, 0, 20);
$this->xAxis = new awAxis;
$this->xAxis->addTick('major', new awTick(0, 5));
$this->xAxis->addTick('minor', new awTick(0, 3));
$this->xAxis->setTickStyle(awTick::OUT);
$this->xAxis->label->setFont(new awTuffy(7));
$this->yAxis = new awAxis;
$this->yAxis->auto(TRUE);
$this->yAxis->addTick('major', new awTick(0, 5));
$this->yAxis->addTick('minor', new awTick(0, 3));
$this->yAxis->setTickStyle(awTick::OUT);
$this->yAxis->setNumberByTick('minor', 'major', 3);
$this->yAxis->label->setFont(new awTuffy(7));
$this->yAxis->title->setAngle(90);
}
/**
* Get plot values
*
* @return array
*/
public function getValues() {
return $this->datay;
}
/**
* Reduce number of values in the plot
*
* @param int $number Reduce number of values to $number
*/
public function reduce($number) {
$count = count($this->datay);
$ratio = ceil($count / $number);
if($ratio > 1) {
$tmpy = $this->datay;
$datay = array();
$datax = array();
$cbLabel = $this->xAxis->label->getCallbackFunction();
for($i = 0; $i < $count; $i += $ratio) {
$slice = array_slice($tmpy, $i, $ratio);
$datay[] = array_sum($slice) / count($slice);
// Reduce data on X axis if needed
if($cbLabel !== NULL) {
$datax[] = $cbLabel($i + round($ratio / 2));
}
}
$this->setValues($datay);
if($cbLabel !== NULL) {
$this->xAxis->setLabelText($datax);
}
}
}
/**
* Count values in the plot
*
* @return int
*/
public function getXAxisNumber() {
list($min, $max) = $this->xAxis->getRange();
return ($max - $min + 1);
}
/**
* Change X axis
*
* @param int $axis
*/
public function setXAxis($axis) {
$this->xAxisPosition = $axis;
}
/**
* Get X axis
*
* @return int
*/
public function getXAxis() {
return $this->xAxisPosition;
}
/**
* Set X axis on zero
*
* @param bool $zero
*/
public function setXAxisZero($zero) {
$this->xAxisZero = (bool)$zero;
}
/**
* Set Y axis on zero
*
* @param bool $zero
*/
public function setYAxisZero($zero) {
$this->yAxisZero = (bool)$zero;
}
/**
* Change Y axis
*
* @param int $axis
*/
public function setYAxis($axis) {
$this->yAxisPosition = $axis;
}
/**
* Get Y axis
*
* @return int
*/
public function getYAxis() {
return $this->yAxisPosition;
}
/**
* Change min value for Y axis
* Set NULL for auto selection.
*
* @param float $value
*/
public function setYMin($value) {
$this->yMin = $value;
$this->yAxis->auto(FALSE);
$this->updateAxis();
}
/**
* Change max value for Y axis
* Set NULL for auto selection.
*
* @param float $value
*/
public function setYMax($value) {
$this->yMax = $value;
$this->yAxis->auto(FALSE);
$this->updateAxis();
}
/**
* Change min value for X axis
* Set NULL for auto selection.
*
* @param float $value
*/
public function setXMin($value) {
$this->xMin = $value;
$this->updateAxis();
}
/**
* Change max value for X axis
* Set NULL for auto selection.
*
* @param float $value
*/
public function setXMax($value) {
$this->xMax = $value;
$this->updateAxis();
}
/**
* Get min value for Y axis
*
* @return float $value
*/
public function getYMin() {
if($this->auto) {
if(is_null($this->yMin)) {
$min = array_min($this->datay);
if($min > 0) {
return 0;
}
}
}
return is_null($this->yMin) ? array_min($this->datay) : (float)$this->yMin;
}
/**
* Get max value for Y axis
*
* @return float $value
*/
public function getYMax() {
if($this->auto) {
if(is_null($this->yMax)) {
$max = array_max($this->datay);
if($max < 0) {
return 0;
}
}
}
return is_null($this->yMax) ? array_max($this->datay) : (float)$this->yMax;
}
/**
* Get min value for X axis
*
* @return float $value
*/
public function getXMin() {
return floor(is_null($this->xMin) ? array_min($this->datax) : $this->xMin);
}
/**
* Get max value for X axis
*
* @return float $value
*/
public function getXMax() {
return (ceil(is_null($this->xMax) ? array_max($this->datax) : (float)$this->xMax)) + ($this->getXCenter() ? 1 : 0);
}
/**
* Get min value with spaces for Y axis
*
* @return float $value
*/
public function getRealYMin() {
$min = $this->getYMin();
if($this->space->bottom !== NULL) {
$interval = ($this->getYMax() - $min) * $this->space->bottom / 100;
return $min - $interval;
} else {
return is_null($this->yMin) ? $min : (float)$this->yMin;
}
}
/**
* Get max value with spaces for Y axis
*
* @return float $value
*/
public function getRealYMax() {
$max = $this->getYMax();
if($this->space->top !== NULL) {
$interval = ($max - $this->getYMin()) * $this->space->top / 100;
return $max + $interval;
} else {
return is_null($this->yMax) ? $max : (float)$this->yMax;
}
}
public function init(awDriver $driver) {
list($x1, $y1, $x2, $y2) = $this->getPosition();
// Get space informations
list($leftSpace, $rightSpace, $topSpace, $bottomSpace) = $this->getSpace($x2 - $x1, $y2 - $y1);
$this->xAxis->setPadding($leftSpace, $rightSpace);
if($this->space->bottom > 0 or $this->space->top > 0) {
list($min, $max) = $this->yAxis->getRange();
$interval = $max - $min;
$this->yAxis->setRange(
$min - $interval * $this->space->bottom / 100,
$max + $interval * $this->space->top / 100
);
}
// Auto-scaling mode
$this->yAxis->autoScale();
// Number of labels is not specified
if($this->yAxis->getLabelNumber() === NULL) {
$number = round(($y2 - $y1) / 75) + 2;
$this->yAxis->setLabelNumber($number);
}
$this->xAxis->line->setX($x1, $x2);
$this->yAxis->line->setY($y2, $y1);
// Set ticks
$this->xAxis->tick('major')->setNumber($this->getXAxisNumber());
$this->yAxis->tick('major')->setNumber($this->yAxis->getLabelNumber());
// Center X axis on zero
if($this->xAxisZero) {
$this->xAxis->setYCenter($this->yAxis, 0);
}
// Center Y axis on zero
if($this->yAxisZero) {
$this->yAxis->setXCenter($this->xAxis, 0);
}
// Set axis labels
$labels = array();
list($xMin, $xMax) = $this->xAxis->getRange();
for($i = $xMin; $i <= $xMax; $i++) {
$labels[] = $i;
}
$this->xAxis->label->set($labels);
parent::init($driver);
list($x1, $y1, $x2, $y2) = $this->getPosition();
list($leftSpace, $rightSpace) = $this->getSpace($x2 - $x1, $y2 - $y1);
// Create the grid
$this->createGrid();
// Draw the grid
$this->grid->setSpace($leftSpace, $rightSpace, 0, 0);
$this->grid->draw($driver, $x1, $y1, $x2, $y2);
}
public function drawEnvelope(awDriver $driver) {
list($x1, $y1, $x2, $y2) = $this->getPosition();
if($this->getXCenter()) {
$size = $this->xAxis->getDistance(0, 1);
$this->xAxis->label->move($size / 2, 0);
$this->xAxis->label->hideLast(TRUE);
}
// Draw top axis
if($this->xAxisPosition === awPlot::TOP or $this->xAxisPosition === awPlot::BOTH) {
$top = clone $this->xAxis;
if($this->xAxisZero === FALSE) {
$top->line->setY($y1, $y1);
}
$top->label->setAlign(NULL, awLabel::TOP);
$top->label->move(0, -3);
$top->title->move(0, -25);
$top->draw($driver);
}
// Draw bottom axis
if($this->xAxisPosition === awPlot::BOTTOM or $this->xAxisPosition === awPlot::BOTH) {
$bottom = clone $this->xAxis;
if($this->xAxisZero === FALSE) {
$bottom->line->setY($y2, $y2);
}
$bottom->label->setAlign(NULL, awLabel::BOTTOM);
$bottom->label->move(0, 3);
$bottom->reverseTickStyle();
$bottom->title->move(0, 25);
$bottom->draw($driver);
}
// Draw left axis
if($this->yAxisPosition === awPlot::LEFT or $this->yAxisPosition === awPlot::BOTH) {
$left = clone $this->yAxis;
if($this->yAxisZero === FALSE) {
$left->line->setX($x1, $x1);
}
$left->label->setAlign(awLabel::RIGHT);
$left->label->move(-6, 0);
$left->title->move(-25, 0);
$left->draw($driver);
}
// Draw right axis
if($this->yAxisPosition === awPlot::RIGHT or $this->yAxisPosition === awPlot::BOTH) {
$right = clone $this->yAxis;
if($this->yAxisZero === FALSE) {
$right->line->setX($x2, $x2);
}
$right->label->setAlign(awLabel::LEFT);
$right->label->move(6, 0);
$right->reverseTickStyle();
$right->title->move(25, 0);
$right->draw($driver);
}
}
protected function createGrid() {
$max = $this->getRealYMax();
$min = $this->getRealYMin();
 
$number = $this->yAxis->getLabelNumber() - 1;
if($number < 1) {
return;
}
// Horizontal lines of the grid
$h = array();
for($i = 0; $i <= $number; $i++) {
$h[] = $i / $number;
}
// Vertical lines
$major = $this->yAxis->tick('major');
$interval = $major->getInterval();
$number = $this->getXAxisNumber() - 1;
$w = array();
if($number > 0) {
for($i = 0; $i <= $number; $i++) {
if($i%$interval === 0) {
$w[] = $i / $number;
}
}
}
$this->grid->setGrid($w, $h);
}
/**
* Change values of Y axis
* This method ignores not numeric values
*
* @param array $datay
* @param array $datax
*/
public function setValues($datay, $datax = NULL) {
$this->checkArray($datay);
foreach($datay as $key => $value) {
unset($datay[$key]);
$datay[(int)$key] = $value;
}
if($datax === NULL) {
$datax = array();
for($i = 0; $i < count($datay); $i++) {
$datax[] = $i;
}
} else {
foreach($datax as $key => $value) {
unset($datax[$key]);
$datax[(int)$key] = $value;
}
}
$this->checkArray($datax);
if(count($datay) === count($datax)) {
// Set values
$this->datay = $datay;
$this->datax = $datax;
// Update axis with the new awvalues
$this->updateAxis();
} else {
awImage::drawError("Class Plot: Plots must have the same number of X and Y points.");
}
}
/**
* Return begin and end values
*
* @return array
*/
protected function getLimit() {
$i = 0;
while(array_key_exists($i, $this->datay) and $this->datay[$i] === NULL) {
$i++;
}
$start = $i;
$i = count($this->datay) - 1;
while(array_key_exists($i, $this->datay) and $this->datay[$i] === NULL) {
$i--;
}
$stop = $i;
return array($start, $stop);
}
/**
* Return TRUE if labels must be centered on X axis, FALSE otherwise
*
* @return bool
*/
abstract public function getXCenter();
private function updateAxis() {
$this->xAxis->setRange(
$this->getXMin(),
$this->getXMax()
);
$this->yAxis->setRange(
$this->getRealYMin(),
$this->getRealYMax()
);
}
private function checkArray(&$array) {
if(is_array($array) === FALSE) {
awImage::drawError("Class Plot: You tried to set a value that is not an array.");
}
foreach($array as $key => $value) {
if(is_numeric($value) === FALSE and is_null($value) === FALSE) {
awImage::drawError("Class Plot: Expected numeric values for the plot.");
}
}
if(count($array) < 1) {
awImage::drawError("Class Plot: Your plot must have at least 1 value.");
}
}
 
}
 
registerClass('Plot', TRUE);
 
class awPlotAxis {
 
/**
* Left axis
*
* @var Axis
*/
public $left;
 
/**
* Right axis
*
* @var Axis
*/
public $right;
 
/**
* Top axis
*
* @var Axis
*/
public $top;
 
/**
* Bottom axis
*
* @var Axis
*/
public $bottom;
 
/**
* Build the group of axis
*/
public function __construct() {
$this->left = new awAxis;
$this->left->auto(TRUE);
$this->left->label->setAlign(awLabel::RIGHT);
$this->left->label->move(-6, 0);
$this->yAxis($this->left);
$this->left->setTickStyle(awTick::OUT);
$this->left->title->move(-25, 0);
$this->right = new awAxis;
$this->right->auto(TRUE);
$this->right->label->setAlign(awLabel::LEFT);
$this->right->label->move(6, 0);
$this->yAxis($this->right);
$this->right->setTickStyle(awTick::IN);
$this->right->title->move(25, 0);
$this->top = new awAxis;
$this->top->label->setAlign(NULL, awLabel::TOP);
$this->top->label->move(0, -3);
$this->xAxis($this->top);
$this->top->setTickStyle(awTick::OUT);
$this->top->title->move(0, -25);
$this->bottom = new awAxis;
$this->bottom->label->setAlign(NULL, awLabel::BOTTOM);
$this->bottom->label->move(0, 3);
$this->xAxis($this->bottom);
$this->bottom->setTickStyle(awTick::IN);
$this->bottom->title->move(0, 25);
}
protected function xAxis(awAxis $axis) {
$axis->addTick('major', new awTick(0, 5));
$axis->addTick('minor', new awTick(0, 3));
$axis->label->setFont(new awTuffy(7));
}
protected function yAxis(awAxis $axis) {
$axis->addTick('major', new awTick(0, 5));
$axis->addTick('minor', new awTick(0, 3));
$axis->setNumberByTick('minor', 'major', 3);
$axis->label->setFont(new awTuffy(7));
$axis->title->setAngle(90);
}
 
}
 
registerClass('PlotAxis');
 
/**
* A graph with axis can contain some groups of components
*
* @package Artichow
*/
class awPlotGroup extends awComponentGroup {
/**
* Grid properties
*
* @var Grid
*/
public $grid;
/**
* Left, right, top and bottom axis
*
* @var PlotAxis
*/
public $axis;
/**
* Set the X axis on zero
*
* @var bool
*/
protected $xAxisZero = TRUE;
/**
* Set the Y axis on zero
*
* @var bool
*/
protected $yAxisZero = FALSE;
/**
* Real axis used for Y axis
*
* @var string
*/
private $yRealAxis = awPlot::LEFT;
/**
* Real axis used for X axis
*
* @var string
*/
private $xRealAxis = awPlot::BOTTOM;
/**
* Change min value for Y axis
*
* @var mixed
*/
private $yMin = NULL;
/**
* Change max value for Y axis
*
* @var mixed
*/
private $yMax = NULL;
/**
* Change min value for X axis
*
* @var mixed
*/
private $xMin = NULL;
/**
* Change max value for X axis
*
* @var mixed
*/
private $xMax = NULL;
/**
* Build the PlotGroup
*
*/
public function __construct() {
parent::__construct();
$this->grid = new awGrid;
$this->grid->setBackgroundColor(new awWhite);
$this->axis = new awPlotAxis;
}
/**
* Set the X axis on zero or not
*
* @param bool $zero
*/
public function setXAxisZero($zero) {
$this->xAxisZero = (bool)$zero;
}
/**
* Set the Y axis on zero or not
*
* @param bool $zero
*/
public function setYAxisZero($zero) {
$this->yAxisZero = (bool)$zero;
}
/**
* Change min value for Y axis
* Set NULL for auto selection.
*
* @param float $value
*/
public function setYMin($value) {
$this->axis->left->auto(FALSE);
$this->axis->right->auto(FALSE);
$this->yMin = $value;
}
/**
* Change max value for Y axis
* Set NULL for auto selection.
*
* @param float $value
*/
public function setYMax($value) {
$this->axis->left->auto(FALSE);
$this->axis->right->auto(FALSE);
$this->yMax = $value;
}
/**
* Change min value for X axis
* Set NULL for auto selection.
*
* @param float $value
*/
public function setXMin($value) {
$this->xMin = $value;
}
/**
* Change max value for X axis
* Set NULL for auto selection.
*
* @param float $value
*/
public function setXMax($value) {
$this->xMax = $value;
}
/**
* Get min value for X axis
*
* @return float $value
*/
public function getXMin() {
return $this->getX('min');
}
/**
* Get max value for X axis
*
* @return float $value
*/
public function getXMax() {
return $this->getX('max');
}
private function getX($type) {
switch($type) {
case 'max' :
if($this->xMax !== NULL) {
return $this->xMax;
}
break;
case 'min' :
if($this->xMin !== NULL) {
return $this->xMin;
}
break;
}
$value = NULL;
$get = 'getX'.ucfirst($type);
for($i = 0; $i < count($this->components); $i++) {
$component = $this->components[$i];
if($value === NULL) {
$value = $component->$get();
} else {
$value = $type($value, $component->$get());
}
}
return $value;
}
/**
* Get min value with spaces for Y axis
*
* @param string $axis Axis name
* @return float $value
*/
public function getRealYMin($axis = NULL) {
if($axis === NULL) {
return NULL;
}
$min = $this->getRealY('min', $axis);
$max = $this->getRealY('max', $axis);
if($this->space->bottom !== NULL) {
$interval = ($min - $max) * $this->space->bottom / 100;
return $min + $interval;
} else {
return $min;
}
}
/**
* Get max value with spaces for Y axis
*
* @param string $axis Axis name
* @return float $value
*/
public function getRealYMax($axis = NULL) {
if($axis === NULL) {
return NULL;
}
$min = $this->getRealY('min', $axis);
$max = $this->getRealY('max', $axis);
if($this->space->top !== NULL) {
$interval = ($max - $min) * $this->space->top / 100;
return $max + $interval;
} else {
return $max;
}
}
private function getRealY($type, $axis) {
switch($type) {
case 'max' :
if($this->yMax !== NULL) {
return $this->yMax;
}
break;
case 'min' :
if($this->yMin !== NULL) {
return $this->yMin;
}
break;
}
$value = NULL;
$get = 'getY'.ucfirst($type);
for($i = 0; $i < count($this->components); $i++) {
$component = $this->components[$i];
switch($axis) {
case awPlot::LEFT :
case awPlot::RIGHT :
$test = ($component->getYAxis() === $axis);
break;
default :
$test = FALSE;
}
if($test) {
$auto = $component->yAxis->isAuto();
$this->axis->{$axis}->auto($auto);
if($value === NULL) {
$value = $component->$get();
} else {
$value = $type($value, $component->$get());
}
}
}
return $value;
}
public function init(awDriver $driver) {
list($x1, $y1, $x2, $y2) = $this->getPosition();
// Get PlotGroup space
list($leftSpace, $rightSpace, $topSpace, $bottomSpace) = $this->getSpace($x2 - $x1, $y2 - $y1);
// Count values in the group
$values = $this->getXAxisNumber();
// Init the PlotGroup
$this->axis->top->line->setX($x1, $x2);
$this->axis->bottom->line->setX($x1, $x2);
$this->axis->left->line->setY($y2, $y1);
$this->axis->right->line->setY($y2, $y1);
$this->axis->top->setPadding($leftSpace, $rightSpace);
$this->axis->bottom->setPadding($leftSpace, $rightSpace);
$xMin = $this->getXMin();
$xMax = $this->getXMax();
$this->axis->top->setRange($xMin, $xMax);
$this->axis->bottom->setRange($xMin, $xMax);
for($i = 0; $i < count($this->components); $i++) {
$component = $this->components[$i];
$component->auto($this->auto);
// Copy space to the component
$component->setSpace($this->space->left, $this->space->right, $this->space->top, $this->space->bottom);
$component->xAxis->setPadding($leftSpace, $rightSpace);
$component->xAxis->line->setX($x1, $x2);
$component->yAxis->line->setY($y2, $y1);
}
// Set Y axis range
foreach(array('left', 'right') as $axis) {
if($this->isAxisUsed($axis)) {
$min = $this->getRealYMin($axis);
$max = $this->getRealYMax($axis);
$interval = $max - $min;
$this->axis->{$axis}->setRange(
$min - $interval * $this->space->bottom / 100,
$max + $interval * $this->space->top / 100
);
// Auto-scaling mode
if($this->axis->{$axis}->isAuto()) {
$this->axis->{$axis}->autoScale();
}
}
}
if($this->axis->left->getLabelNumber() === NULL) {
$number = round(($y2 - $y1) / 75) + 2;
$this->axis->left->setLabelNumber($number);
}
if($this->axis->right->getLabelNumber() === NULL) {
$number = round(($y2 - $y1) / 75) + 2;
$this->axis->right->setLabelNumber($number);
}
// Center labels on X axis if needed
$test = array(awPlot::TOP => FALSE, awPlot::BOTTOM => FALSE);
for($i = 0; $i < count($this->components); $i++) {
$component = $this->components[$i];
if($component->getValues() !== NULL) {
$axis = $component->getXAxis();
if($test[$axis] === FALSE) {
// Center labels for bar plots
if($component->getXCenter()) {
$size = $this->axis->{$axis}->getDistance(0, 1);
$this->axis->{$axis}->label->move($size / 2, 0);
$this->axis->{$axis}->label->hideLast(TRUE);
$test[$axis] = TRUE;
}
}
}
}
// Set axis labels
$labels = array();
for($i = $xMin; $i <= $xMax; $i++) {
$labels[] = $i;
}
if($this->axis->top->label->count() === 0) {
$this->axis->top->label->set($labels);
}
if($this->axis->bottom->label->count() === 0) {
$this->axis->bottom->label->set($labels);
}
// Set ticks
$this->axis->top->tick('major')->setNumber($values);
$this->axis->bottom->tick('major')->setNumber($values);
$this->axis->left->tick('major')->setNumber($this->axis->left->getLabelNumber());
$this->axis->right->tick('major')->setNumber($this->axis->right->getLabelNumber());
// Set X axis on zero
if($this->xAxisZero) {
$axis = $this->selectYAxis();
$this->axis->bottom->setYCenter($axis, 0);
$this->axis->top->setYCenter($axis, 0);
}
// Set Y axis on zero
if($this->yAxisZero) {
$axis = $this->selectXAxis();
$this->axis->left->setXCenter($axis, 1);
$this->axis->right->setXCenter($axis, 1);
}
parent::init($driver);
list($leftSpace, $rightSpace, $topSpace, $bottomSpace) = $this->getSpace($x2 - $x1, $y2 - $y1);
// Create the grid
$this->createGrid();
// Draw the grid
$this->grid->setSpace($leftSpace, $rightSpace, 0, 0);
$this->grid->draw($driver, $x1, $y1, $x2, $y2);
}
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
$xMin = $this->getXMin();
$xMax = $this->getXMax();
$maxLeft = $this->getRealYMax(awPlot::LEFT);
$maxRight = $this->getRealYMax(awPlot::RIGHT);
$minLeft = $this->getRealYMin(awPlot::LEFT);
$minRight = $this->getRealYMin(awPlot::RIGHT);
foreach($this->components as $component) {
$min = $component->getYMin();
$max = $component->getYMax();
// Set component minimum and maximum
if($component->getYAxis() === awPlot::LEFT) {
list($min, $max) = $this->axis->left->getRange();
$component->setYMin($min);
$component->setYMax($max);
} else {
list($min, $max) = $this->axis->right->getRange();
$component->setYMin($min);
$component->setYMax($max);
}
$component->setXAxisZero($this->xAxisZero);
$component->setYAxisZero($this->yAxisZero);
$component->xAxis->setRange($xMin, $xMax);
$component->drawComponent(
$driver,
$x1, $y1,
$x2, $y2,
$aliasing
);
$component->setYMin($min);
$component->setYMax($max);
}
}
public function drawEnvelope(awDriver $driver) {
list($x1, $y1, $x2, $y2) = $this->getPosition();
// Hide unused axis
foreach(array(awPlot::LEFT, awPlot::RIGHT, awPlot::TOP, awPlot::BOTTOM) as $axis) {
if($this->isAxisUsed($axis) === FALSE) {
$this->axis->{$axis}->hide(TRUE);
}
}
// Draw top axis
$top = $this->axis->top;
if($this->xAxisZero === FALSE) {
$top->line->setY($y1, $y1);
}
$top->draw($driver);
// Draw bottom axis
$bottom = $this->axis->bottom;
if($this->xAxisZero === FALSE) {
$bottom->line->setY($y2, $y2);
}
$bottom->draw($driver);
// Draw left axis
$left = $this->axis->left;
if($this->yAxisZero === FALSE) {
$left->line->setX($x1, $x1);
}
$left->draw($driver);
// Draw right axis
$right = $this->axis->right;
if($this->yAxisZero === FALSE) {
$right->line->setX($x2, $x2);
}
$right->draw($driver);
}
/**
* Is the specified axis used ?
*
* @param string $axis Axis name
* @return bool
*/
protected function isAxisUsed($axis) {
for($i = 0; $i < count($this->components); $i++) {
$component = $this->components[$i];
switch($axis) {
case awPlot::LEFT :
case awPlot::RIGHT :
if($component->getYAxis() === $axis) {
return TRUE;
}
break;
case awPlot::TOP :
case awPlot::BOTTOM :
if($component->getXAxis() === $axis) {
return TRUE;
}
break;
}
}
return FALSE;
}
protected function createGrid() {
$max = $this->getRealYMax(awPlot::LEFT);
$min = $this->getRealYMin(awPlot::RIGHT);
// Select axis (left if possible, right otherwise)
$axis = $this->selectYAxis();
$number = $axis->getLabelNumber() - 1;
if($number < 1) {
return;
}
// Horizontal lines of grid
$h = array();
for($i = 0; $i <= $number; $i++) {
$h[] = $i / $number;
}
// Vertical lines
$major = $axis->tick('major');
$interval = $major->getInterval();
$number = $this->getXAxisNumber() - 1;
$w = array();
if($number > 0) {
for($i = 0; $i <= $number; $i++) {
if($i%$interval === 0) {
$w[] = $i / $number;
}
}
}
$this->grid->setGrid($w, $h);
}
protected function selectYAxis(){
// Select axis (left if possible, right otherwise)
if($this->isAxisUsed(awPlot::LEFT)) {
$axis = $this->axis->left;
} else {
$axis = $this->axis->right;
}
return $axis;
}
protected function selectXAxis(){
// Select axis (bottom if possible, top otherwise)
if($this->isAxisUsed(awPlot::BOTTOM)) {
$axis = $this->axis->bottom;
} else {
$axis = $this->axis->top;
}
return $axis;
}
protected function getXAxisNumber() {
$offset = $this->components[0];
$max = $offset->getXAxisNumber();
for($i = 1; $i < count($this->components); $i++) {
$offset = $this->components[$i];
$max = max($max, $offset->getXAxisNumber());
}
return $max;
}
 
}
 
registerClass('PlotGroup');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Tools.class.php
New file
0,0 → 1,175
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
 
/**
* Objects capable of being positioned
*
* @package Artichow
*/
interface awPositionable {
 
/**
* Left align
*
* @var int
*/
const LEFT = 1;
 
/**
* Right align
*
* @var int
*/
const RIGHT = 2;
 
/**
* Center align
*
* @var int
*/
const CENTER = 3;
 
/**
* Top align
*
* @var int
*/
const TOP = 4;
 
/**
* Bottom align
*
* @var int
*/
const BOTTOM = 5;
 
/**
* Middle align
*
* @var int
*/
const MIDDLE = 6;
/**
* Change alignment
*
* @param int $h Horizontal alignment
* @param int $v Vertical alignment
*/
public function setAlign($h = NULL, $v = NULL);
}
 
registerInterface('Positionable');
 
/**
* Manage left, right, top and bottom sides
*
* @package Artichow
*/
class awSide {
 
/**
* Left side
*
* @var int
*/
public $left = 0;
 
/**
* Right side
*
* @var int
*/
public $right = 0;
 
/**
* Top side
*
* @var int
*/
public $top = 0;
 
/**
* Bottom side
*
* @var int
*/
public $bottom = 0;
/**
* Build the side
*
* @param mixed $left
* @param mixed $right
* @param mixed $top
* @param mixed $bottom
*/
public function __construct($left = NULL, $right = NULL, $top = NULL, $bottom = NULL) {
$this->set($left, $right, $top, $bottom);
}
/**
* Change side values
*
* @param mixed $left
* @param mixed $right
* @param mixed $top
* @param mixed $bottom
*/
public function set($left = NULL, $right = NULL, $top = NULL, $bottom = NULL) {
if($left !== NULL) {
$this->left = (float)$left;
}
if($right !== NULL) {
$this->right = (float)$right;
}
if($top !== NULL) {
$this->top = (float)$top;
}
if($bottom !== NULL) {
$this->bottom = (float)$bottom;
}
}
/**
* Add values to each side
*
* @param mixed $left
* @param mixed $right
* @param mixed $top
* @param mixed $bottom
*/
public function add($left = NULL, $right = NULL, $top = NULL, $bottom = NULL) {
if($left !== NULL) {
$this->left += (float)$left;
}
if($right !== NULL) {
$this->right += (float)$right;
}
if($top !== NULL) {
$this->top += (float)$top;
}
if($bottom !== NULL) {
$this->bottom += (float)$bottom;
}
}
 
}
 
registerClass('Side');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Axis.class.php
New file
0,0 → 1,769
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/../Graph.class.php";
 
/**
* Handle axis
*
* @package Artichow
*/
class awAxis {
 
/**
* Axis line
*
* @var Line
*/
public $line;
 
/**
* Axis labels
*
* @var Label
*/
public $label;
 
/**
* Axis title
*
* @var Label
*/
public $title;
 
/**
* Title position
*
* @var float
*/
protected $titlePosition = 0.5;
 
/**
* Labels number
*
* @var int
*/
protected $labelNumber;
 
/**
* Axis ticks
*
* @var array
*/
protected $ticks = array();
 
/**
* Axis and ticks color
*
* @var Color
*/
protected $color;
 
/**
* Axis left and right padding
*
* @var Side
*/
protected $padding;
 
/**
* Axis range
*
* @var array
*/
protected $range;
 
/**
* Hide axis
*
* @var bool
*/
protected $hide = FALSE;
 
/**
* Auto-scaling mode
*
* @var bool
*/
protected $auto = TRUE;
 
/**
* Axis range callback function
*
* @var array
*/
protected $rangeCallback = array(
'toValue' => 'toProportionalValue',
'toPosition' => 'toProportionalPosition'
);
 
/**
* Build the axis
*
* @param float $min Begin of the range of the axis
* @param float $max End of the range of the axis
*/
public function __construct($min = NULL, $max = NULL) {
 
$this->line = new awVector(
new awPoint(0, 0),
new awPoint(0, 0)
);
 
$this->label = new awLabel;
$this->padding = new awSide;
 
$this->title = new awLabel(
NULL,
NULL,
NULL,
0
);
 
$this->setColor(new awBlack);
 
if($min !== NULL and $max !== NULL) {
$this->setRange($min, $max);
}
 
}
 
/**
* Enable/disable auto-scaling mode
*
* @param bool $auto
*/
public function auto($auto) {
$this->auto = (bool)$auto;
}
 
/**
* Get auto-scaling mode status
*
* @return bool
*/
public function isAuto() {
return $this->auto;
}
 
/**
* Hide axis
*
* @param bool $hide
*/
public function hide($hide = TRUE) {
$this->hide = (bool)$hide;
}
 
/**
* Show axis
*
* @param bool $show
*/
public function show($show = TRUE) {
$this->hide = !(bool)$show;
}
 
/**
* Return a tick object from its name
*
* @param string $name Tick object name
* @return Tick
*/
public function tick($name) {
return array_key_exists($name, $this->ticks) ? $this->ticks[$name] : NULL;
}
 
/**
* Add a tick object
*
* @param string $name Tick object name
* @param awTick $tick Tick object
*/
public function addTick($name, awTick $tick) {
$this->ticks[$name] = $tick;
}
 
/**
* Delete a tick object
*
* @param string $name Tick object name
*/
public function deleteTick($name) {
if(array_key_exists($name, $this->ticks)) {
unset($this->ticks[$name]);
}
}
 
/**
* Hide all ticks
*
* @param bool $hide Hide or not ?
*/
public function hideTicks($hide = TRUE) {
foreach($this->ticks as $tick) {
$tick->hide($hide);
}
}
 
/**
* Change ticks style
*
* @param int $style Ticks style
*/
public function setTickStyle($style) {
foreach($this->ticks as $tick) {
$tick->setStyle($style);
}
}
 
/**
* Change ticks interval
*
* @param int $interval Ticks interval
*/
public function setTickInterval($interval) {
foreach($this->ticks as $tick) {
$tick->setInterval($interval);
}
}
 
/**
* Change number of ticks relative to others ticks
*
* @param awTick $to Change number of theses ticks
* @param awTick $from Ticks reference
* @param float $number Number of ticks by the reference
*/
public function setNumberByTick($to, $from, $number) {
$this->ticks[$to]->setNumberByTick($this->ticks[$from], $number);
}
 
/**
* Reverse ticks style
*/
public function reverseTickStyle() {
foreach($this->ticks as $tick) {
if($tick->getStyle() === awTick::IN) {
$tick->setStyle(awTick::OUT);
} else if($tick->getStyle() === awTick::OUT) {
$tick->setStyle(awTick::IN);
}
}
}
 
/**
* Change interval of labels
*
* @param int $interval Interval
*/
public function setLabelInterval($interval) {
$this->auto(FALSE);
$this->setTickInterval($interval);
$this->label->setInterval($interval);
}
 
/**
* Change number of labels
*
* @param int $number Number of labels to display (can be NULL)
*/
public function setLabelNumber($number) {
$this->auto(FALSE);
$this->labelNumber = is_null($number) ? NULL : (int)$number;
}
 
/**
* Get number of labels
*
* @return int
*/
public function getLabelNumber() {
return $this->labelNumber;
}
 
/**
* Change precision of labels
*
* @param int $precision Precision
*/
public function setLabelPrecision($precision) {
$this->auto(FALSE);
$function = 'axis'.time().'_'.(microtime() * 1000000);
eval('function '.$function.'($value) {
return sprintf("%.'.(int)$precision.'f", $value);
}');
$this->label->setCallbackFunction($function);
}
 
/**
* Change text of labels
*
* @param array $texts Some texts
*/
public function setLabelText($texts) {
if(is_array($texts)) {
$this->auto(FALSE);
$function = 'axis'.time().'_'.(microtime() * 1000000);
eval('function '.$function.'($value) {
$texts = '.var_export($texts, TRUE).';
return isset($texts[$value]) ? $texts[$value] : \'?\';
}');
$this->label->setCallbackFunction($function);
}
}
 
/**
* Get the position of a point
*
* @param awAxis $xAxis X axis
* @param awAxis $yAxis Y axis
* @param awPoint $p Position of the point
* @return Point Position on the axis
*/
public static function toPosition(awAxis $xAxis, awAxis $yAxis, awPoint $p) {
 
$p1 = $xAxis->getPointFromValue($p->x);
$p2 = $yAxis->getPointFromValue($p->y);
 
return new awPoint(
round($p1->x),
round($p2->y)
);
 
}
 
/**
* Change title alignment
*
* @param int $alignment New Alignment
*/
public function setTitleAlignment($alignment) {
 
switch($alignment) {
 
case awLabel::TOP :
$this->setTitlePosition(1);
$this->title->setAlign(NULL, awLabel::BOTTOM);
break;
 
case awLabel::BOTTOM :
$this->setTitlePosition(0);
$this->title->setAlign(NULL, awLabel::TOP);
break;
 
case awLabel::LEFT :
$this->setTitlePosition(0);
$this->title->setAlign(awLabel::LEFT);
break;
 
case awLabel::RIGHT :
$this->setTitlePosition(1);
$this->title->setAlign(awLabel::RIGHT);
break;
 
}
 
}
 
/**
* Change title position on the axis
*
* @param float $position A new awposition between 0 and 1
*/
public function setTitlePosition($position) {
$this->titlePosition = (float)$position;
}
 
/**
* Change axis and axis title color
*
* @param awColor $color
*/
public function setColor(awColor $color) {
$this->color = $color;
$this->title->setColor($color);
}
 
/**
* Change axis padding
*
* @param int $left Left padding in pixels
* @param int $right Right padding in pixels
*/
public function setPadding($left, $right) {
$this->padding->set($left, $right);
}
 
/**
* Get axis padding
*
* @return Side
*/
public function getPadding() {
return $this->padding;
}
 
/**
* Change axis range
*
* @param float $min
* @param float $max
*/
public function setRange($min, $max) {
if($min !== NULL) {
$this->range[0] = (float)$min;
}
if($max !== NULL) {
$this->range[1] = (float)$max;
}
}
 
/**
* Get axis range
*
* @return array
*/
public function getRange() {
return $this->range;
}
 
/**
* Change axis range callback function
*
* @param string $toValue Transform a position between 0 and 1 to a value
* @param string $toPosition Transform a value to a position between 0 and 1 on the axis
*/
public function setRangeCallback($toValue, $toPosition) {
$this->rangeCallback = array(
'toValue' => (string)$toValue,
'toPosition' => (string)$toPosition
);
}
 
/**
* Center X values of the axis
*
* @param awAxis $axis An axis
* @param float $value The reference value on the axis
*/
public function setXCenter(awAxis $axis, $value) {
 
// Check vector angle
if($this->line->isVertical() === FALSE) {
awImage::drawError("Class Axis: setXCenter() can only be used on vertical axes.");
}
 
$p = $axis->getPointFromValue($value);
 
$this->line->setX(
$p->x,
$p->x
);
 
}
 
/**
* Center Y values of the axis
*
* @param awAxis $axis An axis
* @param float $value The reference value on the axis
*/
public function setYCenter(awAxis $axis, $value) {
 
// Check vector angle
if($this->line->isHorizontal() === FALSE) {
awImage::drawError("Class Axis: setYCenter() can only be used on horizontal axes.");
}
 
$p = $axis->getPointFromValue($value);
 
$this->line->setY(
$p->y,
$p->y
);
 
}
 
/**
* Get the distance between to values on the axis
*
* @param float $from The first value
* @param float $to The last value
* @return Point
*/
public function getDistance($from, $to) {
 
$p1 = $this->getPointFromValue($from);
$p2 = $this->getPointFromValue($to);
 
return $p1->getDistance($p2);
 
}
 
/**
* Get a point on the axis from a value
*
* @param float $value
* @return Point
*/
protected function getPointFromValue($value) {
 
$callback = $this->rangeCallback['toPosition'];
 
list($min, $max) = $this->range;
$position = $callback($value, $min, $max);
 
return $this->getPointFromPosition($position);
 
}
 
/**
* Get a point on the axis from a position
*
* @param float $position A position between 0 and 1
* @return Point
*/
protected function getPointFromPosition($position) {
 
$vector = $this->getVector();
 
$angle = $vector->getAngle();
$size = $vector->getSize();
 
return $vector->p1->move(
cos($angle) * $size * $position,
-1 * sin($angle) * $size * $position
);
 
}
 
/**
* Draw axis
*
* @param awDriver $driver A driver
*/
public function draw(awDriver $driver) {
 
if($this->hide) {
return;
}
 
$vector = $this->getVector();
 
// Draw axis ticks
$this->drawTicks($driver, $vector);
 
// Draw axis line
$this->line($driver);
 
// Draw labels
$this->drawLabels($driver);
 
// Draw axis title
$p = $this->getPointFromPosition($this->titlePosition);
$this->title->draw($driver, $p);
 
}
 
public function autoScale() {
 
if($this->isAuto() === FALSE) {
return;
}
 
list($min, $max) = $this->getRange();
$interval = $max - $min;
 
if($interval > 0) {
$partMax = $max / $interval;
$partMin = $min / $interval;
} else {
$partMax = 0;
$partMin = 0;
}
 
$difference = log($interval) / log(10);
$difference = floor($difference);
 
$pow = pow(10, $difference);
 
if($pow > 0) {
$intervalNormalize = $interval / $pow;
} else {
$intervalNormalize = 0;
}
 
if($difference <= 0) {
 
$precision = $difference * -1 + 1;
 
if($intervalNormalize > 2) {
$precision--;
}
 
} else {
$precision = 0;
}
 
if($min != 0 and $max != 0) {
$precision++;
}
 
if($this->label->getCallbackFunction() === NULL) {
$this->setLabelPrecision($precision);
}
 
if($intervalNormalize <= 1.5) {
$intervalReal = 1.5;
$labelNumber = 4;
} else if($intervalNormalize <= 2) {
$intervalReal = 2;
$labelNumber = 5;
} else if($intervalNormalize <= 3) {
$intervalReal = 3;
$labelNumber = 4;
} else if($intervalNormalize <= 4) {
$intervalReal = 4;
$labelNumber = 5;
} else if($intervalNormalize <= 5) {
$intervalReal = 5;
$labelNumber = 6;
} else if($intervalNormalize <= 8) {
$intervalReal = 8;
$labelNumber = 5;
} else if($intervalNormalize <= 10) {
$intervalReal = 10;
$labelNumber = 6;
}
 
if($min == 0) {
 
$this->setRange(
$min,
$intervalReal * $pow
);
 
} else if($max == 0) {
 
$this->setRange(
$intervalReal * $pow * -1,
0
);
 
}
 
$this->setLabelNumber($labelNumber);
 
}
 
protected function line(awDriver $driver) {
 
$driver->line(
$this->color,
$this->line
);
 
}
 
protected function drawTicks(awDriver $driver, awVector $vector) {
 
foreach($this->ticks as $tick) {
$tick->setColor($this->color);
$tick->draw($driver, $vector);
}
 
}
 
protected function drawLabels($driver) {
 
if($this->labelNumber !== NULL) {
list($min, $max) = $this->range;
$number = $this->labelNumber - 1;
if($number < 1) {
return;
}
$function = $this->rangeCallback['toValue'];
$labels = array();
for($i = 0; $i <= $number; $i++) {
$labels[] = $function($i / $number, $min, $max);
}
$this->label->set($labels);
}
 
$labels = $this->label->count();
 
for($i = 0; $i < $labels; $i++) {
 
$p = $this->getPointFromValue($this->label->get($i));
$this->label->draw($driver, $p, $i);
 
}
 
}
 
protected function getVector() {
 
$angle = $this->line->getAngle();
 
// Compute paddings
$vector = new awVector(
$this->line->p1->move(
cos($angle) * $this->padding->left,
-1 * sin($angle) * $this->padding->left
),
$this->line->p2->move(
-1 * cos($angle) * $this->padding->right,
-1 * -1 * sin($angle) * $this->padding->right
)
);
 
return $vector;
 
}
 
public function __clone() {
 
$this->label = clone $this->label;
$this->line = clone $this->line;
$this->title = clone $this->title;
 
foreach($this->ticks as $name => $tick) {
$this->ticks[$name] = clone $tick;
}
 
}
 
}
 
registerClass('Axis');
 
function toProportionalValue($position, $min, $max) {
return $min + ($max - $min) * $position;
}
 
function toProportionalPosition($value, $min, $max) {
if($max - $min == 0) {
return 0;
}
return ($value - $min) / ($max - $min);
}
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Font.class.php
New file
0,0 → 1,263
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/../Graph.class.php";
 
/**
* Common font characteristics and methods.
* Declared abstract only so that it can't be instanciated.
* Users have to call 'new awPHPFont' or 'new awFileFont',
* or any of their inherited classes (awFont1, awTuffy, awTTFFont, etc.)
*
* @package Artichow
*/
abstract class awFont {
 
/**
* Build the font
*
*/
public function __construct() {
}
 
/**
* Draw a text
*
* @param awDriver $driver
* @param awPoint $p Draw text at this point
* @param awText $text The text
* @param int $width Text box width
*/
public function draw(awDriver $driver, awPoint $point, awText $text, $width = NULL) {
$driver->string($this, $text, $point, $width);
}
 
}
 
registerClass('Font', TRUE);
 
/**
* Class for fonts that cannot be transformed,
* like the built-in PHP fonts for example.
*
* @package Artichow
*/
class awPHPFont extends awFont {
/**
* The used font identifier
*
* @var int
*/
public $font;
public function __construct($font = NULL) {
parent::__construct();
if($font !== NULL) {
$this->font = (int)$font;
}
}
}
 
registerClass('PHPFont');
 
/**
* Class for fonts that can be transformed (rotated, skewed, etc.),
* like TTF or FDB fonts for example.
*
* @package Artichow
*/
class awFileFont extends awFont {
/**
* The name of the font, without the extension
*
* @var string
*/
protected $name;
/**
* The size of the font
*
* @var int
*/
protected $size;
/**
* The font filename extension
*
* @var string
*/
protected $extension;
public function __construct($name, $size) {
parent::__construct();
$this->setName($name);
$this->setSize($size);
}
/**
* Set the name of the font. The $name variable can contain the full path,
* or just the filename. Artichow will try to do The Right Thing,
* as well as set the extension property correctly if possible.
*
* @param string $name
*/
public function setName($name) {
$fontInfo = pathinfo((string)$name);
if(strpos($fontInfo['dirname'], '/') !== 0) {
// Path is not absolute, use ARTICHOW_FONT
$name = ARTICHOW_FONT.DIRECTORY_SEPARATOR.$fontInfo['basename'];
$fontInfo = pathinfo($name);
}
$this->name = $fontInfo['dirname'].DIRECTORY_SEPARATOR.$fontInfo['basename'];
if(array_key_exists('extension', $fontInfo) and $fontInfo['extension'] !== '') {
$this->setExtension($fontInfo['extension']);
}
}
/**
* Return the name of the font, i.e. the absolute path and the filename, without the extension.
*
* @return string
*/
public function getName() {
return $this->name;
}
/**
* Set the size of the font, in pixels
*
* @param int $size
*/
public function setSize($size) {
$this->size = (int)$size;
}
/**
* Return the size of the font, in pixels
*
* @return int
*/
public function getSize() {
return $this->size;
}
/**
* Set the extension, without the dot
*
* @param string $extension
*/
public function setExtension($extension) {
$this->extension = (string)$extension;
}
/**
* Get the filename extension for that font
*
* @return string
*/
public function getExtension() {
return $this->extension;
}
 
}
 
registerClass('FileFont');
 
/**
* Class representing TTF fonts
*
* @package Artichow
*/
class awTTFFont extends awFileFont {
public function __construct($name, $size) {
parent::__construct($name, $size);
if($this->getExtension() === NULL) {
$this->setExtension('ttf');
}
}
 
}
 
registerClass('TTFFont');
 
 
 
$php = '';
 
for($i = 1; $i <= 5; $i++) {
 
$php .= '
class awFont'.$i.' extends awPHPFont {
 
public function __construct() {
parent::__construct('.$i.');
}
 
}
';
 
if(ARTICHOW_PREFIX !== 'aw') {
$php .= '
class '.ARTICHOW_PREFIX.'Font'.$i.' extends awFont'.$i.' {
}
';
}
 
}
 
eval($php);
 
$php = '';
 
foreach($fonts as $font) {
 
$php .= '
class aw'.$font.' extends awFileFont {
 
public function __construct($size) {
parent::__construct(\''.$font.'\', $size);
}
 
}
';
 
if(ARTICHOW_PREFIX !== 'aw') {
$php .= '
class '.ARTICHOW_PREFIX.$font.' extends aw'.$font.' {
}
';
}
 
}
 
eval($php);
 
 
 
/*
* Environment modification for GD2 and TTF fonts
*/
if(function_exists('putenv')) {
putenv('GDFONTPATH='.ARTICHOW_FONT);
}
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Border.class.php
New file
0,0 → 1,198
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
/**
* Draw border
*
* @package Artichow
*/
class awBorder {
 
/**
* Border color
*
* @var Color
*/
protected $color;
 
/**
* Hide border ?
*
* @var bool
*/
protected $hide = FALSE;
 
/**
* Border line style
*
* @var int
*/
protected $style;
/**
* Build the border
*
* @param awColor $color Border color
* @param int $style Border style
*/
public function __construct($color = NULL, $style = awLine::SOLID) {
$this->setStyle($style);
if($color instanceof awColor) {
$this->setColor($color);
} else {
$this->setColor(new awBlack);
}
}
/**
* Change border color
* This method automatically shows the border if it is hidden
*
* @param awColor $color
*/
public function setColor(awColor $color) {
$this->color = $color;
$this->show();
}
/**
* Change border style
*
* @param int $style
*/
public function setStyle($style) {
$this->style = (int)$style;
}
/**
* Hide border ?
*
* @param bool $hide
*/
public function hide($hide = TRUE) {
$this->hide = (bool)$hide;
}
/**
* Show border ?
*
* @param bool $show
*/
public function show($show = TRUE) {
$this->hide = (bool)!$show;
}
/**
* Is the border visible ?
*
* @return bool
*/
public function visible() {
return !$this->hide;
}
/**
* Draw border as a rectangle
*
* @param awDriver $driver
* @param awPoint $p1 Top-left corner
* @param awPoint $p2 Bottom-right corner
*/
public function rectangle(awDriver $driver, awPoint $p1, awPoint $p2) {
// Border is hidden
if($this->hide) {
return;
}
$line = new awLine;
$line->setStyle($this->style);
$line->setLocation($p1, $p2);
$driver->rectangle($this->color, $line);
}
/**
* Draw border as an ellipse
*
* @param awDriver $driver
* @param awPoint $center Ellipse center
* @param int $width Ellipse width
* @param int $height Ellipse height
*/
public function ellipse(awDriver $driver, awPoint $center, $width, $height) {
// Border is hidden
if($this->hide) {
return;
}
switch($this->style) {
case awLine::SOLID :
$driver->ellipse($this->color, $center, $width, $height);
break;
default :
awImage::drawError("Class Border: Dashed and dotted borders and not yet implemented on ellipses.");
break;
}
}
/**
* Draw border as a polygon
*
* @param awDriver $driver A Driver object
* @param awPolygon $polygon A Polygon object
*/
public function polygon(awDriver $driver, awPolygon $polygon) {
// Border is hidden
if($this->hide) {
return;
}
$polygon->setStyle($this->style);
$driver->polygon($this->color, $polygon);
// In case of Line::SOLID, Driver::polygon() uses imagepolygon()
// which automatically closes the shape. In any other case,
// we have to do it manually here.
if($this->style !== Line::SOLID) {
$this->closePolygon($driver, $polygon);
}
}
/**
* Draws the last line of a Polygon, between the first and last point
*
* @param awDriver $driver A Driver object
* @param awPolygon $polygon The polygon object to close
*/
private function closePolygon(awDriver $driver, awPolygon $polygon) {
$first = $polygon->get(0);
$last = $polygon->get($polygon->count() - 1);
$line = new awLine($first, $last, $this->style, $polygon->getThickness());
$driver->line($this->color, $line);
}
}
 
registerClass('Border');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Color.class.php
New file
0,0 → 1,165
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
 
/**
* Create your colors
*
* @package Artichow
*/
class awColor {
public $red;
public $green;
public $blue;
public $alpha;
 
/**
* Build your color
*
* @var int $red Red intensity (from 0 to 255)
* @var int $green Green intensity (from 0 to 255)
* @var int $blue Blue intensity (from 0 to 255)
* @var int $alpha Alpha channel (from 0 to 100)
*/
public function __construct($red, $green, $blue, $alpha = 0) {
$this->red = (int)$red;
$this->green = (int)$green;
$this->blue = (int)$blue;
$this->alpha = (int)round($alpha * 127 / 100);
}
/**
* Get RGB and alpha values of your color
*
* @return array
*/
public function getColor() {
return $this->rgba();
}
/**
* Change color brightness
*
* @param int $brightness Add this intensity to the color (betweeen -255 and +255)
*/
public function brightness($brightness) {
$brightness = (int)$brightness;
$this->red = min(255, max(0, $this->red + $brightness));
$this->green = min(255, max(0, $this->green + $brightness));
$this->blue = min(255, max(0, $this->blue + $brightness));
}
 
/**
* Get RGB and alpha values of your color
*
* @return array
*/
public function rgba() {
return array($this->red, $this->green, $this->blue, $this->alpha);
}
 
}
 
registerClass('Color');
 
$colors = array(
'Black' => array(0, 0, 0),
'AlmostBlack' => array(48, 48, 48),
'VeryDarkGray' => array(88, 88, 88),
'DarkGray' => array(128, 128, 128),
'MidGray' => array(160, 160, 160),
'LightGray' => array(195, 195, 195),
'VeryLightGray' => array(220, 220, 220),
'White' => array(255, 255, 255),
'VeryDarkRed' => array(64, 0, 0),
'DarkRed' => array(128, 0, 0),
'MidRed' => array(192, 0, 0),
'Red' => array(255, 0, 0),
'LightRed' => array(255, 192, 192),
'VeryDarkGreen' => array(0, 64, 0),
'DarkGreen' => array(0, 128, 0),
'MidGreen' => array(0, 192, 0),
'Green' => array(0, 255, 0),
'LightGreen' => array(192, 255, 192),
'VeryDarkBlue' => array(0, 0, 64),
'DarkBlue' => array(0, 0, 128),
'MidBlue' => array(0, 0, 192),
'Blue' => array(0, 0, 255),
'LightBlue' => array(192, 192, 255),
'VeryDarkYellow' => array(64, 64, 0),
'DarkYellow' => array(128, 128, 0),
'MidYellow' => array(192, 192, 0),
'Yellow' => array(255, 255, 2),
'LightYellow' => array(255, 255, 192),
'VeryDarkCyan' => array(0, 64, 64),
'DarkCyan' => array(0, 128, 128),
'MidCyan' => array(0, 192, 192),
'Cyan' => array(0, 255, 255),
'LightCyan' => array(192, 255, 255),
'VeryDarkMagenta' => array(64, 0, 64),
'DarkMagenta' => array(128, 0, 128),
'MidMagenta' => array(192, 0, 192),
'Magenta' => array(255, 0, 255),
'LightMagenta' => array(255, 192, 255),
'DarkOrange' => array(192, 88, 0),
'Orange' => array(255, 128, 0),
'LightOrange' => array(255, 168, 88),
'VeryLightOrange' => array(255, 220, 168),
'DarkPink' => array(192, 0, 88),
'Pink' => array(255, 0, 128),
'LightPink' => array(255, 88, 168),
'VeryLightPink' => array(255, 168, 220),
'DarkPurple' => array(88, 0, 192),
'Purple' => array(128, 0, 255),
'LightPurple' => array(168, 88, 255),
'VeryLightPurple' => array(220, 168, 255),
);
 
 
 
$php = '';
 
foreach($colors as $name => $color) {
 
list($red, $green, $blue) = $color;
 
$php .= '
class aw'.$name.' extends awColor {
public function __construct($alpha = 0) {
parent::__construct('.$red.', '.$green.', '.$blue.', $alpha);
}
}
';
if(ARTICHOW_PREFIX !== 'aw') {
$php .= '
class '.ARTICHOW_PREFIX.$name.' extends aw'.$name.' {
}
';
}
 
}
 
eval($php);
 
 
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Label.class.php
New file
0,0 → 1,588
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
/**
* Draw labels
*
* @package Artichow
*/
class awLabel implements awPositionable {
 
/**
* Label border
*
* @var int
*/
public $border;
 
/**
* Label texts
*
* @var array
*/
protected $texts;
 
/**
* Text font
*
* @var int
*/
protected $font;
 
/**
* Text angle
*
* @var int
*/
protected $angle = 0;
 
/**
* Text color
*
* @var Color
*/
protected $color;
 
/**
* Text background
*
* @var Color, Gradient
*/
private $background;
 
/**
* Callback function
*
* @var string
*/
private $function;
 
/**
* Padding
*
* @var int
*/
private $padding;
 
/**
* Move position from this vector
*
* @var Point
*/
protected $move;
 
/**
* Label interval
*
* @var int
*/
protected $interval = 1;
 
/**
* Horizontal align
*
* @var int
*/
protected $hAlign = awLabel::CENTER;
 
/**
* Vertical align
*
* @var int
*/
protected $vAlign = awLabel::MIDDLE;
/**
* Hide all labels ?
*
* @var bool
*/
protected $hide = FALSE;
/**
* Keys to hide
*
* @var array
*/
protected $hideKey = array();
/**
* Values to hide
*
* @var array
*/
protected $hideValue = array();
/**
* Hide first label
*
* @var bool
*/
protected $hideFirst = FALSE;
/**
* Hide last label
*
* @var bool
*/
protected $hideLast = FALSE;
/**
* Build the label
*
* @param string $label First label
*/
public function __construct($label = NULL, $font = NULL, $color = NULL, $angle = 0) {
if(is_array($label)) {
$this->set($label);
} else if(is_string($label)) {
$this->set(array($label));
}
if($font === NULL) {
$font = new awFont2;
}
$this->setFont($font);
$this->setAngle($angle);
if($color instanceof awColor) {
$this->setColor($color);
} else {
$this->setColor(new awColor(0, 0, 0));
}
$this->move = new awPoint(0, 0);
$this->border = new awBorder;
$this->border->hide();
}
/**
* Get an element of the label from its key
*
* @param int $key Element key
* @return string A value
*/
public function get($key) {
return array_key_exists($key, $this->texts) ? $this->texts[$key] : NULL;
}
/**
* Get all labels
*
* @return array
*/
public function all() {
return $this->texts;
}
/**
* Set one or several labels
*
* @param array $labels Array of string or a string
*/
public function set($labels) {
if(is_array($labels)) {
$this->texts = $labels;
} else {
$this->texts = array((string)$labels);
}
}
/**
* Count number of texts in the label
*
* @return int
*/
public function count() {
return is_array($this->texts) ? count($this->texts) : 0;
}
/**
* Set a callback function for labels
*
* @param string $function
*/
public function setCallbackFunction($function) {
$this->function = is_null($function) ? $function : (string)$function;
}
/**
* Return the callback function for labels
*
* @return string
*/
public function getCallbackFunction() {
return $this->function;
}
/**
* Change labels format
*
* @param string $format New format (printf style: %.2f for example)
*/
public function setFormat($format) {
$function = 'label'.time().'_'.(microtime() * 1000000);
eval('function '.$function.'($value) {
return sprintf("'.addcslashes($format, '"').'", $value);
}');
$this->setCallbackFunction($function);
}
/**
* Change font for label
*
* @param awFont $font New font
* @param awColor $color Font color (can be NULL)
*/
public function setFont(awFont $font, $color = NULL) {
$this->font = $font;
if($color instanceof awColor) {
$this->setColor($color);
}
}
/**
* Change font angle
*
* @param int $angle New angle
*/
public function setAngle($angle) {
$this->angle = (int)$angle;
}
/**
* Change font color
*
* @param awColor $color
*/
public function setColor(awColor $color) {
$this->color = $color;
}
/**
* Change text background
*
* @param mixed $background
*/
public function setBackground($background) {
$this->background = $background;
}
/**
* Change text background color
*
* @param Color
*/
public function setBackgroundColor(awColor $color) {
$this->background = $color;
}
/**
* Change text background gradient
*
* @param Gradient
*/
public function setBackgroundGradient(awGradient $gradient) {
$this->background = $gradient;
}
 
/**
* Change padding
*
* @param int $left Left padding
* @param int $right Right padding
* @param int $top Top padding
* @param int $bottom Bottom padding
*/
public function setPadding($left, $right, $top, $bottom) {
$this->padding = array((int)$left, (int)$right, (int)$top, (int)$bottom);
}
/**
* Hide all labels ?
*
* @param bool $hide
*/
public function hide($hide = TRUE) {
$this->hide = (bool)$hide;
}
/**
* Show all labels ?
*
* @param bool $show
*/
public function show($show = TRUE) {
$this->hide = (bool)!$show;
}
/**
* Hide a key
*
* @param int $key The key to hide
*/
public function hideKey($key) {
$this->hideKey[$key] = TRUE;
}
/**
* Hide a value
*
* @param int $value The value to hide
*/
public function hideValue($value) {
$this->hideValue[] = $value;
}
/**
* Hide first label
*
* @param bool $hide
*/
public function hideFirst($hide) {
$this->hideFirst = (bool)$hide;
}
/**
* Hide last label
*
* @param bool $hide
*/
public function hideLast($hide) {
$this->hideLast = (bool)$hide;
}
/**
* Set label interval
*
* @param int
*/
public function setInterval($interval) {
$this->interval = (int)$interval;
}
/**
* Change label position
*
* @param int $x Add this interval to X coord
* @param int $y Add this interval to Y coord
*/
public function move($x, $y) {
$this->move = $this->move->move($x, $y);
}
/**
* Change alignment
*
* @param int $h Horizontal alignment
* @param int $v Vertical alignment
*/
public function setAlign($h = NULL, $v = NULL) {
if($h !== NULL) {
$this->hAlign = (int)$h;
}
if($v !== NULL) {
$this->vAlign = (int)$v;
}
}
/**
* Get a text from the labele
*
* @param mixed $key Key in the array text
* @return Text
*/
public function getText($key) {
if(is_array($this->texts) and array_key_exists($key, $this->texts)) {
$value = $this->texts[$key];
if(is_string($this->function)) {
$value = call_user_func($this->function, $value);
}
$text = new awText($value);
$text->setFont($this->font);
$text->setAngle($this->angle);
$text->setColor($this->color);
if($this->background instanceof awColor) {
$text->setBackgroundColor($this->background);
} else if($this->background instanceof awGradient) {
$text->setBackgroundGradient($this->background);
}
$text->border = $this->border;
if($this->padding !== NULL) {
call_user_func_array(array($text, 'setPadding'), $this->padding);
}
return $text;
} else {
return NULL;
}
}
/**
* Get max width of all texts
*
* @param awDriver $driver A driver
* @return int
*/
public function getMaxWidth(awDriver $driver) {
return $this->getMax($driver, 'getTextWidth');
}
/**
* Get max height of all texts
*
* @param awDriver $driver A driver
* @return int
*/
public function getMaxHeight(awDriver $driver) {
return $this->getMax($driver, 'getTextHeight');
}
/**
* Draw the label
*
* @param awDriver $driver
* @param awPoint $p Label center
* @param int $key Text position in the array of texts (default to zero)
*/
public function draw(awDriver $driver, awPoint $p, $key = 0) {
if(($key % $this->interval) !== 0) {
return;
}
// Hide all labels
if($this->hide) {
return;
}
// Key is hidden
if(array_key_exists($key, $this->hideKey)) {
return;
}
// Hide first label
if($key === 0 and $this->hideFirst) {
return;
}
// Hide last label
if($key === count($this->texts) - 1 and $this->hideLast) {
return;
}
$text = $this->getText($key);
if($text !== NULL) {
// Value must be hidden
if(in_array($text->getText(), $this->hideValue)) {
return;
}
$x = $p->x;
$y = $p->y;
// Get padding
list($left, $right, $top, $bottom) = $text->getPadding();
// $font = $text->getFont();
$width = $driver->getTextWidth($text);
$height = $driver->getTextHeight($text);
switch($this->hAlign) {
case awLabel::RIGHT :
$x -= ($width + $right);
break;
case awLabel::CENTER :
$x -= ($width - $left + $right) / 2;
break;
case awLabel::LEFT :
$x += $left;
break;
}
switch($this->vAlign) {
case awLabel::TOP :
$y -= ($height + $bottom);
break;
case awLabel::MIDDLE :
$y -= ($height - $top + $bottom) / 2;
break;
case awLabel::BOTTOM :
$y += $top;
break;
}
$driver->string($text, $this->move->move($x, $y));
}
}
protected function getMax(awDriver $driver, $function) {
$max = NULL;
foreach($this->texts as $key => $text) {
$text = $this->getText($key);
$font = $text->getFont();
if(is_null($max)) {
$max = $font->{$function}($text);
} else {
$max = max($max, $font->{$function}($text));
}
}
return $max;
}
 
}
 
registerClass('Label');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Text.class.php
New file
0,0 → 1,233
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
 
/**
* To handle text
*
* @package Artichow
*/
class awText {
 
/**
* Your text
*
* @var string
*/
private $text;
 
/**
* Text font
*
* @var Font
*/
private $font;
 
/**
* Text angle
* Can be 0 or 90
*
* @var int
*/
private $angle;
 
/**
* Text color
*
* @var Color
*/
private $color;
 
/**
* Text background
*
* @var Color, Gradient
*/
private $background;
 
/**
* Padding
*
* @var array Array for left, right, top and bottom paddings
*/
private $padding;
 
/**
* Text border
*
* @var Border
*/
public $border;
/**
* Build a new awtext
*
* @param string $text Your text
*/
public function __construct($text, $font = NULL, $color = NULL, $angle = 0) {
if(is_null($font)) {
$font = new awFont2;
}
$this->setText($text);
$this->setFont($font);
// Set default color to black
if($color === NULL) {
$color = new awColor(0, 0, 0);
}
$this->setColor($color);
$this->setAngle($angle);
$this->border = new awBorder;
$this->border->hide();
}
/**
* Get text
*
* @return string
*/
public function getText() {
return $this->text;
}
/**
* Change text
*
* @param string $text New text
*/
public function setText($text) {
$this->text = (string)$text;
$this->text = str_replace("\r", "", $text);
}
 
/**
* Change text font
*
* @param Font
*/
public function setFont(awFont $font) {
$this->font = $font;
}
/**
* Get text font
*
* @return int
*/
public function getFont() {
return $this->font;
}
 
/**
* Change text angle
*
* @param int
*/
public function setAngle($angle) {
$this->angle = (int)$angle;
}
/**
* Get text angle
*
* @return int
*/
public function getAngle() {
return $this->angle;
}
 
/**
* Change text color
*
* @param Color
*/
public function setColor(awColor $color) {
$this->color = $color;
}
/**
* Get text color
*
* @return Color
*/
public function getColor() {
return $this->color;
}
/**
* Change text background
*
* @param mixed $background
*/
public function setBackground($background) {
if($background instanceof awColor) {
$this->setBackgroundColor($background);
} elseif($background instanceof awGradient) {
$this->setBackgroundGradient($background);
}
}
/**
* Change text background color
*
* @param awColor $color
*/
public function setBackgroundColor(awColor $color) {
$this->background = $color;
}
/**
* Change text background gradient
*
* @param awGradient $gradient
*/
public function setBackgroundGradient(awGradient $gradient) {
$this->background = $gradient;
}
/**
* Get text background
*
* @return Color, Gradient
*/
public function getBackground() {
return $this->background;
}
 
/**
* Change padding
*
* @param int $left Left padding
* @param int $right Right padding
* @param int $top Top padding
* @param int $bottom Bottom padding
*/
public function setPadding($left, $right, $top, $bottom) {
$this->padding = array((int)$left, (int)$right, (int)$top, (int)$bottom);
}
/**
* Get current padding
*
* @return array
*/
public function getPadding() {
return $this->padding;
}
 
}
 
registerClass('Text');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/drivers/gd.class.php
New file
0,0 → 1,1336
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Driver.class.php";
 
/**
* Draw your objects
*
* @package Artichow
*/
 
class awGDDriver extends Driver {
/**
* A GD resource
*
* @var $resource
*/
public $resource;
public function __construct() {
parent::__construct();
$this->driverString = 'gd';
}
 
public function init(awImage $image) {
if($this->resource === NULL) {
$this->setImageSize($image->width, $image->height);
// Create image
$this->resource = imagecreatetruecolor($this->imageWidth, $this->imageHeight);
if(!$this->resource) {
awImage::drawError("Class Image: Unable to create a graph.");
}
imagealphablending($this->resource, TRUE);
// Antialiasing is now handled by the Driver object
$this->setAntiAliasing($image->getAntiAliasing());
// Original color
$this->filledRectangle(
new awWhite,
new awLine(
new awPoint(0, 0),
new awPoint($this->imageWidth, $this->imageHeight)
)
);
$shadow = $image->shadow;
if($shadow !== NULL) {
$shadow = $shadow->getSpace();
$p1 = new awPoint($shadow->left, $shadow->top);
$p2 = new awPoint($this->imageWidth - $shadow->right - 1, $this->imageHeight - $shadow->bottom - 1);
// Draw image background
$this->filledRectangle($image->getBackground(), new awLine($p1, $p2));
// Draw image border
$image->border->rectangle($this, $p1, $p2);
}
}
}
public function initFromFile(awFileImage $fileImage, $file) {
$image = @getimagesize((string)$file);
if($image and in_array($image[2], array(2, 3))) {
$fileImage->setSize($image[0], $image[1]);
switch($image[2]) {
case 2 :
$this->resource = imagecreatefromjpeg($file);
break;
case 3 :
$this->resource = imagecreatefrompng($file);
break;
}
 
$this->setImageSize($fileImage->width, $fileImage->height);
} else {
awImage::drawError("Class FileImage: Artichow does not support the format of this image (must be in PNG or JPEG)");
}
}
public function setImageSize($width, $height) {
$this->imageWidth = $width;
$this->imageHeight = $height;
}
public function setPosition($x, $y) {
// Calculate absolute position
$this->x = round($x * $this->imageWidth - $this->w / 2);
$this->y = round($y * $this->imageHeight - $this->h / 2);
}
public function setAbsPosition($x, $y) {
$this->x = $x;
$this->y = $y;
}
public function movePosition($x, $y) {
 
$this->x += (int)$x;
$this->y += (int)$y;
}
public function setSize($w, $h) {
// Calcul absolute size
$this->w = round($w * $this->imageWidth);
$this->h = round($h * $this->imageHeight);
return $this->getSize();
}
public function setAbsSize($w, $h) {
$this->w = $w;
$this->h = $h;
return $this->getSize();
}
public function getSize() {
return array($this->w, $this->h);
}
public function setAntiAliasing($bool) {
if(function_exists('imageantialias')) {
imageantialias($this->resource, (bool)$bool);
 
$this->antiAliasing = (bool)$bool;
} else {
awImage::drawErrorFile('missing-anti-aliasing');
}
}
public function getColor(awColor $color) {
 
if($color->alpha === 0 or function_exists('imagecolorallocatealpha') === FALSE) {
$gdColor = imagecolorallocate($this->resource, $color->red, $color->green, $color->blue);
} else {
$gdColor = imagecolorallocatealpha($this->resource, $color->red, $color->green, $color->blue, $color->alpha);
}
 
return $gdColor;
}
public function copyImage(awImage $image, awPoint $p1, awPoint $p2) {
list($x1, $y1) = $p1->getLocation();
list($x2, $y2) = $p2->getLocation();
$driver = $image->getDriver();
imagecopy($this->resource, $driver->resource, $this->x + $x1, $this->y + $y1, 0, 0, $x2 - $x1, $y2 - $y1);
}
public function copyResizeImage(awImage $image, awPoint $d1, awPoint $d2, awPoint $s1, awPoint $s2, $resample = TRUE) {
if($resample) {
$function = 'imagecopyresampled';
} else {
$function = 'imagecopyresized';
}
$driver = $image->getDriver();
$function(
$this->resource,
$driver->resource,
$this->x + $d1->x, $this->y + $d1->y,
$s1->x, $s1->y,
$d2->x - $d1->x, $d2->y - $d1->y,
$s2->x - $s1->x, $s2->y - $s1->y
);
}
public function string(awText $text, awPoint $point, $width = NULL) {
$font = $text->getFont();
// Can we deal with that font?
if($this->isCompatibleWithFont($font) === FALSE) {
awImage::drawError('Class GDDriver: Incompatible font type (\''.get_class($font).'\')');
}
// Check which FontDriver to use
if($font instanceof awPHPFont) {
$fontDriver = $this->phpFontDriver;
} else {
$fontDriver = $this->fileFontDriver;
}
if($text->getBackground() !== NULL or $text->border->visible()) {
list($left, $right, $top, $bottom) = $text->getPadding();
 
$textWidth = $fontDriver->getTextWidth($text, $this);
$textHeight = $fontDriver->getTextHeight($text, $this);
$x1 = floor($point->x - $left);
$y1 = floor($point->y - $top);
$x2 = $x1 + $textWidth + $left + $right;
$y2 = $y1 + $textHeight + $top + $bottom;
$this->filledRectangle(
$text->getBackground(),
awLine::build($x1, $y1, $x2, $y2)
);
$text->border->rectangle(
$this,
new awPoint($x1 - 1, $y1 - 1),
new awPoint($x2 + 1, $y2 + 1)
);
}
$fontDriver->string($this, $text, $point, $width);
}
public function point(awColor $color, awPoint $p) {
if($p->isHidden() === FALSE) {
$rgb = $this->getColor($color);
imagesetpixel($this->resource, $this->x + round($p->x), $this->y + round($p->y), $rgb);
}
}
public function line(awColor $color, awLine $line) {
if($line->thickness > 0 and $line->isHidden() === FALSE) {
$rgb = $this->getColor($color);
$thickness = $line->thickness;
list($p1, $p2) = $line->getLocation();
$this->startThickness($thickness);
switch($line->getStyle()) {
case awLine::SOLID :
imageline($this->resource, $this->x + round($p1->x), $this->y + round($p1->y), $this->x + round($p2->x), $this->y + round($p2->y), $rgb);
break;
case awLine::DOTTED :
$size = sqrt(pow($p2->y - $p1->y, 2) + pow($p2->x - $p1->x, 2));
$cos = ($p2->x - $p1->x) / $size;
$sin = ($p2->y - $p1->y) / $size;
for($i = 0; $i <= $size; $i += 2) {
$p = new awPoint(
round($i * $cos + $p1->x),
round($i * $sin + $p1->y)
);
$this->point($color, $p);
}
break;
case awLine::DASHED :
$width = $p2->x - $p1->x;
$height = $p2->y - $p1->y;
$size = sqrt(pow($height, 2) + pow($width, 2));
if($size == 0) {
return;
}
$cos = $width / $size;
$sin = $height / $size;
$functionX = ($width > 0) ? 'min' : 'max';
$functionY = ($height > 0) ? 'min' : 'max';
for($i = 0; $i <= $size; $i += 6) {
$t1 = new awPoint(
round($i * $cos + $p1->x),
round($i * $sin + $p1->y)
);
$t2 = new awPoint(
round($functionX(($i + 3) * $cos, $width) + $p1->x),
round($functionY(($i + 3) * $sin, $height) + $p1->y)
);
$this->line($color, new awLine($t1, $t2));
}
break;
}
$this->stopThickness($thickness);
}
}
public function arc(awColor $color, awPoint $center, $width, $height, $from, $to) {
imagefilledarc(
$this->resource,
$this->x + $center->x, $this->y + $center->y,
$width, $height,
$from, $to,
$this->getColor($color),
IMG_ARC_EDGED | IMG_ARC_NOFILL
);
}
public function filledArc(awColor $color, awPoint $center, $width, $height, $from, $to) {
imagefilledarc(
$this->resource,
$this->x + $center->x, $this->y + $center->y,
$width, $height,
$from, $to,
$this->getColor($color),
IMG_ARC_PIE
);
}
public function ellipse(awColor $color, awPoint $center, $width, $height) {
list($x, $y) = $center->getLocation();
$rgb = $this->getColor($color);
imageellipse(
$this->resource,
$this->x + $x,
$this->y + $y,
$width,
$height,
$rgb
);
}
public function filledEllipse($background, awPoint $center, $width, $height) {
if($background instanceof awColor) {
list($x, $y) = $center->getLocation();
$rgb = $this->getColor($background);
imagefilledellipse(
$this->resource,
$this->x + $x,
$this->y + $y,
$width,
$height,
$rgb
);
} else if($background instanceof awGradient) {
list($x, $y) = $center->getLocation();
$x1 = $x - round($width / 2);
$y1 = $y - round($height / 2);
$x2 = $x1 + $width;
$y2 = $y1 + $height;
$gradientDriver = new awGDGradientDriver($this);
$gradientDriver->filledEllipse(
$background,
$x1, $y1,
$x2, $y2
);
}
}
public function rectangle(awColor $color, awLine $line) {
list($p1, $p2) = $line->getLocation();
switch($line->getStyle()) {
case awLine::SOLID :
$thickness = $line->getThickness();
$this->startThickness($thickness);
$rgb = $this->getColor($color);
imagerectangle($this->resource, $this->x + $p1->x, $this->y + $p1->y, $this->x + $p2->x, $this->y + $p2->y, $rgb);
$this->stopThickness($thickness);
break;
default :
$side = clone $line;
// Top side
$side->setLocation(
new awPoint($p1->x, $p1->y),
new awPoint($p2->x, $p1->y)
);
$this->line($color, $side);
// Right side
$side->setLocation(
new awPoint($p2->x, $p1->y),
new awPoint($p2->x, $p2->y)
);
$this->line($color, $side);
// Bottom side
$side->setLocation(
new awPoint($p1->x, $p2->y),
new awPoint($p2->x, $p2->y)
);
$this->line($color, $side);
// Left side
$side->setLocation(
new awPoint($p1->x, $p1->y),
new awPoint($p1->x, $p2->y)
);
$this->line($color, $side);
break;
}
}
public function filledRectangle($background, awLine $line) {
$p1 = $line->p1;
$p2 = $line->p2;
if($background instanceof awColor) {
$rgb = $this->getColor($background);
imagefilledrectangle($this->resource, $this->x + $p1->x, $this->y + $p1->y, $this->x + $p2->x, $this->y + $p2->y, $rgb);
} else if($background instanceof awGradient) {
$gradientDriver = new awGDGradientDriver($this);
$gradientDriver->filledRectangle($background, $p1, $p2);
}
}
public function polygon(awColor $color, awPolygon $polygon) {
switch($polygon->getStyle()) {
case awPolygon::SOLID :
$thickness = $polygon->getThickness();
$this->startThickness($thickness);
$points = $this->getPolygonPoints($polygon);
$rgb = $this->getColor($color);
imagepolygon($this->resource, $points, $polygon->count(), $rgb);
$this->stopThickness($thickness);
break;
default :
if($polygon->count() > 1) {
$prev = $polygon->get(0);
$line = new awLine;
$line->setStyle($polygon->getStyle());
$line->setThickness($polygon->getThickness());
for($i = 1; $i < $polygon->count(); $i++) {
$current = $polygon->get($i);
$line->setLocation($prev, $current);
$this->line($color, $line);
$prev = $current;
}
// Close the polygon
$line->setLocation($prev, $polygon->get(0));
$this->line($color, $line);
}
}
}
public function filledPolygon($background, awPolygon $polygon) {
if($background instanceof awColor) {
$points = $this->getPolygonPoints($polygon);
$rgb = $this->getColor($background);
imagefilledpolygon($this->resource, $points, $polygon->count(), $rgb);
} else if($background instanceof awGradient) {
$gradientDriver = new awGDGradientDriver($this);
$gradientDriver->filledPolygon($background, $polygon);
}
 
}
 
public function send(awImage $image) {
 
$this->drawImage($image);
 
}
public function get(awImage $image) {
return $this->drawImage($image, TRUE, FALSE);
}
public function getTextWidth(awText $text) {
$font = $text->getFont();
if($font instanceof awPHPFont) {
$fontDriver = $this->phpFontDriver;
} else {
$fontDriver = $this->fileFontDriver;
}
return $fontDriver->getTextWidth($text, $this);
}
public function getTextHeight(awText $text) {
$font = $text->getFont();
if($font instanceof awPHPFont) {
$fontDriver = $this->phpFontDriver;
} else {
$fontDriver = $this->fileFontDriver;
}
return $fontDriver->getTextHeight($text, $this);
}
protected function isCompatibleWithFont(awFont $font) {
if($font instanceof awFDBFont) {
return FALSE;
} else {
return TRUE;
}
}
private function drawImage(awImage $image, $return = FALSE, $header = TRUE) {
$format = $image->getFormatString();
// Test if format is available
if((imagetypes() & $image->getFormat()) === FALSE) {
awImage::drawError("Class Image: Format '".$format."' is not available on your system. Check that your PHP has been compiled with the good libraries.");
}
// Get some infos about this image
switch($format) {
case 'jpeg' :
$function = 'imagejpeg';
break;
case 'png' :
$function = 'imagepng';
break;
case 'gif' :
$function = 'imagegif';
break;
}
// Send headers to the browser
if($header === TRUE) {
$image->sendHeaders();
}
if($return) {
ob_start();
}
$function($this->resource);
if($return) {
return ob_get_clean();
}
}
private function getPolygonPoints(awPolygon $polygon) {
$points = array();
foreach($polygon->all() as $point) {
$points[] = $point->x + $this->x;
$points[] = $point->y + $this->y;
}
return $points;
}
private function startThickness($thickness) {
if($thickness > 1) {
// Beurk :'(
if($this->antiAliasing and function_exists('imageantialias')) {
imageantialias($this->resource, FALSE);
}
imagesetthickness($this->resource, $thickness);
}
}
private function stopThickness($thickness) {
if($thickness > 1) {
if($this->antiAliasing and function_exists('imageantialias')) {
imageantialias($this->resource, TRUE);
}
imagesetthickness($this->resource, 1);
}
}
 
}
 
registerClass('GDDriver');
 
/**
* To your gradients
*
* @package Artichow
*/
 
class awGDGradientDriver {
 
/**
* A driver
*
* @var awGDDriver
*/
protected $driver;
 
/**
* Build your GDGradientDriver
*
* @var awGDDriver $driver
*/
public function __construct(awGDDriver $driver) {
$this->driver = $driver;
}
public function drawFilledFlatTriangle(awGradient $gradient, awPoint $a, awPoint $b, awPoint $c) {
if($gradient->angle !== 0) {
awImage::drawError("Class GDGradientDriver: Flat triangles can only be used with 0 degree gradients.");
}
// Look for right-angled triangle
if($a->x !== $b->x and $b->x !== $c->x) {
awImage::drawError("Class GDGradientDriver: Not right-angled flat triangles are not supported yet.");
}
if($a->x === $b->x) {
$d = $a;
$e = $c;
} else {
$d = $c;
$e = $a;
}
$this->init($gradient, $b->y - $d->y);
for($i = $c->y + 1; $i < $b->y; $i++) {
$color = $this->color($i - $d->y);
$pos = ($i - $d->y) / ($b->y - $d->y);
$p1 = new awPoint($e->x, $i);
$p2 = new awPoint(1 + floor($e->x - $pos * ($e->x - $d->x)), $i);
$this->driver->filledRectangle($color, new awLine($p1, $p2));
unset($color);
}
}
protected function drawFilledTriangle(awGradient $gradient, awPolygon $polygon) {
if($gradient->angle === 0) {
$this->drawFilledTriangleVertically($gradient, $polygon);
} elseif($gradient->angle === 90) {
$this->drawFilledTriangleHorizontally($gradient, $polygon);
}
}
private function drawFilledTriangleVertically(awGradient $gradient, awPolygon $polygon) {
list($yMin, $yMax) = $polygon->getBoxYRange();
$this->init($gradient, $yMax - $yMin);
// Get the triangle line we will draw our lines from
$fromLine = NULL;
$lines = $polygon->getLines();
$count = count($lines);
// Pick the side of the triangle going from the top
// to the bottom of the surrounding box
for($i = 0; $i < $count; $i++) {
if($lines[$i]->isTopToBottom($polygon)) {
list($fromLine) = array_splice($lines, $i, 1);
break;
}
}
// If for some reason the three points are aligned,
// $fromLine will still be NULL
if($fromLine === NULL) {
return;
}
$fillLine = NULL;
for($y = round($yMin); $y < round($yMax); $y++) {
$fromX = $fromLine->getXFrom($y);
$toX = array();
foreach($lines as $line) {
$xValue = $line->getXFrom($y);
if(!is_null($xValue)) {
$toX[] = $xValue;
}
}
if(count($toX) === 1) {
$fillLine = new Line(
new Point($fromX, $y),
new Point($toX[0], $y)
);
} else {
$line1 = new Line(
new Point($fromX, $y),
new Point($toX[0], $y)
);
$line2 = new Line(
new Point($fromX, $y),
new Point($toX[1], $y)
);
if($line1->getSize() < $line2->getSize()) {
$fillLine = $line1;
} else {
$fillLine = $line2;
}
}
if(!$fillLine->isPoint()) {
$color = $this->color($y - $yMin);
$this->driver->line($color, $fillLine);
unset($color);
}
}
}
private function drawFilledTriangleHorizontally(awGradient $gradient, awPolygon $polygon) {
list($xMin, $xMax) = $polygon->getBoxXRange();
$this->init($gradient, $xMax - $xMin);
// Get the triangle line we will draw our lines from
$fromLine = NULL;
$lines = $polygon->getLines();
$count = count($lines);
// Pick the side of the triangle going all the way
// from the left side to the right side of the surrounding box
for($i = 0; $i < $count; $i++) {
if($lines[$i]->isLeftToRight($polygon)) {
list($fromLine) = array_splice($lines, $i, 1);
break;
}
}
// If for some reason the three points are aligned,
// $fromLine will still be NULL
if($fromLine === NULL) {
return;
}
 
$fillLine = NULL;
for($x = round($xMin); $x < round($xMax); $x++) {
$fromY = floor($fromLine->getYFrom($x));
$toY = array();
foreach($lines as $line) {
$yValue = $line->getYFrom($x);
if(!is_null($yValue)) {
$toY[] = floor($yValue);
}
}
if(count($toY) === 1) {
$fillLine = new Line(
new Point($x, $fromY),
new Point($x, $toY[0])
);
} else {
$line1 = new Line(
new Point($x, $fromY),
new Point($x, $toY[0])
);
$line2 = new Line(
new Point($x, $fromY),
new Point($x, $toY[1])
);
if($line1->getSize() < $line2->getSize()) {
$fillLine = $line1;
} else {
$fillLine = $line2;
}
}
$color = $this->color($x - $xMin);
if($fillLine->isPoint()) {
$this->driver->point($color, $fillLine->p1);
} elseif($fillLine->getSize() >= 1) {
$this->driver->line($color, $fillLine);
}
unset($color);
}
}
public function filledRectangle(awGradient $gradient, awPoint $p1, awPoint $p2) {
list($x1, $y1) = $p1->getLocation();
list($x2, $y2) = $p2->getLocation();
if($y1 < $y2) {
$y1 ^= $y2 ^= $y1 ^= $y2;
}
if($x2 < $x1) {
$x1 ^= $x2 ^= $x1 ^= $x2;
}
if($gradient instanceof awLinearGradient) {
$this->rectangleLinearGradient($gradient, new awPoint($x1, $y1), new awPoint($x2, $y2));
} else {
awImage::drawError("Class GDGradientDriver: This gradient is not supported by rectangles.");
}
}
public function filledPolygon(awGradient $gradient, awPolygon $polygon) {
if($gradient instanceof awLinearGradient) {
$this->polygonLinearGradient($gradient, $polygon);
} else {
awImage::drawError("Class GDGradientDriver: This gradient is not supported by polygons.");
}
}
protected function rectangleLinearGradient(awLinearGradient $gradient, awPoint $p1, awPoint $p2) {
list($x1, $y1) = $p1->getLocation();
list($x2, $y2) = $p2->getLocation();
if($y1 - $y2 > 0) {
if($gradient->angle === 0) {
$this->init($gradient, $y1 - $y2);
for($i = $y2; $i <= $y1; $i++) {
$color = $this->color($i - $y2);
$p1 = new awPoint($x1, $i);
$p2 = new awPoint($x2, $i);
$this->driver->filledRectangle($color, new awLine($p1, $p2));
unset($color);
}
} else if($gradient->angle === 90) {
$this->init($gradient, $x2 - $x1);
for($i = $x1; $i <= $x2; $i++) {
$color = $this->color($i - $x1);
$p1 = new awPoint($i, $y2);
$p2 = new awPoint($i, $y1);
$this->driver->filledRectangle($color, new awLine($p1, $p2));
unset($color);
}
}
}
}
public function filledEllipse(awGradient $gradient, $x1, $y1, $x2, $y2) {
if($y1 < $y2) {
$y1 ^= $y2 ^= $y1 ^= $y2;
}
if($x2 < $x1) {
$x1 ^= $x2 ^= $x1 ^= $x2;
}
if($gradient instanceof awRadialGradient) {
$this->ellipseRadialGradient($gradient, $x1, $y1, $x2, $y2);
} else if($gradient instanceof awLinearGradient) {
$this->ellipseLinearGradient($gradient, $x1, $y1, $x2, $y2);
} else {
awImage::drawError("Class GDGradientDriver: This gradient is not supported by ellipses.");
}
}
protected function ellipseRadialGradient(awGradient $gradient, $x1, $y1, $x2, $y2) {
if($y1 - $y2 > 0) {
if($y1 - $y2 != $x2 - $x1) {
awImage::drawError("Class GDGradientDriver: Radial gradients are only implemented on circle, not ellipses.");
}
$c = new awPoint($x1 + ($x2 - $x1) / 2, $y1 + ($y2 - $y1) / 2);
$r = ($x2 - $x1) / 2;
$ok = array();
// Init gradient
$this->init($gradient, $r);
for($i = 0; $i <= $r; $i += 0.45) {
$p = ceil((2 * M_PI * $i));
if($p > 0) {
$interval = 360 / $p;
} else {
$interval = 360;
}
$color = $this->color($i);
for($j = 0; $j < 360; $j += $interval) {
$rad = ($j / 360) * (2 * M_PI);
$x = round($i * cos($rad));
$y = round($i * sin($rad));
$l = sqrt($x * $x + $y * $y);
if($l <= $r) {
if(
array_key_exists((int)$x, $ok) === FALSE or
array_key_exists((int)$y, $ok[$x]) === FALSE
) {
// Print the point
$this->driver->point($color, new awPoint($c->x + $x, $c->y + $y));
$ok[(int)$x][(int)$y] = TRUE;
}
}
}
unset($color);
}
}
}
protected function ellipseLinearGradient(awGradient $gradient, $x1, $y1, $x2, $y2) {
// Gauche->droite : 90°
if($y1 - $y2 > 0) {
if($y1 - $y2 != $x2 - $x1) {
awImage::drawError("Class GDGradientDriver: Linear gradients are only implemented on circle, not ellipses.");
}
$r = ($x2 - $x1) / 2;
// Init gradient
$this->init($gradient, $x2 - $x1);
for($i = -$r; $i <= $r; $i++) {
$h = sin(acos($i / $r)) * $r;
$color = $this->color($i + $r);
if($gradient->angle === 90) {
// Print the line
$p1 = new awPoint(
$x1 + $i + $r,
round(max($y2 + $r - $h + 1, $y2))
);
$p2 = new awPoint(
$x1 + $i + $r,
round(min($y1 - $r + $h - 1, $y1))
);
} else {
// Print the line
$p1 = new awPoint(
round(max($x1 + $r - $h + 1, $x1)),
$y2 + $i + $r
);
$p2 = new awPoint(
round(min($x2 - $r + $h - 1, $x2)),
$y2 + $i + $r
);
}
$this->driver->filledRectangle($color, new awLine($p1, $p2));
unset($color);
}
}
}
protected function polygonLinearGradient(awLinearGradient $gradient, awPolygon $polygon) {
$count = $polygon->count();
if($count >= 4) {
$left = $polygon->get(0);
$right = $polygon->get($count - 1);
if($gradient->angle === 0) {
// Get polygon maximum and minimum
$offset = $polygon->get(0);
$max = $min = $offset->y;
for($i = 1; $i < $count - 1; $i++) {
$offset = $polygon->get($i);
$max = max($max, $offset->y);
$min = min($min, $offset->y);
}
$this->init($gradient, $max - $min);
$prev = $polygon->get(1);
$sum = 0;
for($i = 2; $i < $count - 1; $i++) {
$current = $polygon->get($i);
$interval = 1;
if($i !== $count - 2) {
$current->x -= $interval;
}
if($current->x - $prev->x > 0) {
// Draw rectangle
$x1 = $prev->x;
$x2 = $current->x;
$y1 = max($prev->y, $current->y);
$y2 = $left->y;
$gradient = new awLinearGradient(
$this->color($max - $min - ($y2 - $y1)),
$this->color($max - $min),
0
);
if($y1 > $y2) {
$y2 = $y1;
}
$this->driver->filledRectangle(
$gradient,
awLine::build($x1, $y1, $x2, $y2)
);
$top = ($prev->y < $current->y) ? $current : $prev;
$bottom = ($prev->y >= $current->y) ? $current : $prev;
$gradient = new awLinearGradient(
$this->color($bottom->y - $min),
$this->color($max - $min - ($y2 - $y1)),
0
);
$gradientDriver = new awGDGradientDriver($this->driver);
$gradientDriver->drawFilledFlatTriangle(
$gradient,
new awPoint($prev->x, min($prev->y, $current->y)),
$top,
new awPoint($current->x, min($prev->y, $current->y))
);
unset($gradientDriver);
$sum += $current->x - $prev->x;
}
$prev = $current;
$prev->x += $interval;
}
} else if($gradient->angle === 90) {
$width = $right->x - $left->x;
$this->init($gradient, $width);
$pos = 1;
$next = $polygon->get($pos++);
$this->next($polygon, $pos, $prev, $next);
for($i = 0; $i <= $width; $i++) {
$x = $left->x + $i;
$y1 = round($prev->y + ($next->y - $prev->y) * (($i + $left->x - $prev->x) / ($next->x - $prev->x)));
$y2 = $left->y;
// Draw line
$color = $this->color($i);
// YaPB : PHP does not handle alpha on lines
$this->driver->filledRectangle($color, awLine::build($x, $y1, $x, $y2));
 
unset($color);
// Jump to next point
if($next->x == $i + $left->x) {
$this->next($polygon, $pos, $prev, $next);
}
}
}
} else if($count === 3) {
$this->drawFilledTriangle(
$gradient,
$polygon
);
}
}
private function next($polygon, &$pos, &$prev, &$next) {
do {
$prev = $next;
$next = $polygon->get($pos++);
}
while($next->x - $prev->x == 0 and $pos < $polygon->count());
}
/**
* Start colors
*
* @var int
*/
private $r1, $g1, $b1, $a1;
/**
* Stop colors
*
* @var int
*/
private $r2, $g2, $b2, $a2;
/**
* Gradient size in pixels
*
* @var int
*/
private $size;
private function init(awGradient $gradient, $size) {
list(
$this->r1, $this->g1, $this->b1, $this->a1
) = $gradient->from->rgba();
list(
$this->r2, $this->g2, $this->b2, $this->a2
) = $gradient->to->rgba();
$this->size = $size;
}
private function color($pos) {
return new awColor(
$this->getRed($pos),
$this->getGreen($pos),
$this->getBlue($pos),
$this->getAlpha($pos)
);
}
private function getRed($pos) {
if((float)$this->size !== 0.0) {
return (int)round($this->r1 + ($pos / $this->size) * ($this->r2 - $this->r1));
} else {
return 0;
}
}
private function getGreen($pos) {
if((float)$this->size !== 0.0) {
return (int)round($this->g1 + ($pos / $this->size) * ($this->g2 - $this->g1));
} else {
return 0;
}
}
private function getBlue($pos) {
if((float)$this->size !== 0.0) {
return (int)round($this->b1 + ($pos / $this->size) * ($this->b2 - $this->b1));
} else {
return 0;
}
}
private function getAlpha($pos) {
if((float)$this->size !== 0.0) {
return (int)round(($this->a1 + ($pos / $this->size) * ($this->a2 - $this->a1)) / 127 * 100);
} else {
return 0;
}
}
 
}
 
registerClass('GDGradientDriver');
 
/*
* Check for GD2
*/
if(function_exists('imagecreatetruecolor') === FALSE) {
awImage::drawErrorFile('missing-gd2');
}
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/drivers/ming.class.php
New file
0,0 → 1,774
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Driver.class.php";
 
/**
* Draw your objects
*
* @package Artichow
*/
class awMingDriver extends awDriver {
/**
* The Flash movie
*
* @var $movie
*/
public $movie;
public function __construct() {
parent::__construct();
$this->driverString = 'ming';
// Nice defaults
ming_setScale(20.0);
ming_useswfversion(6);
 
}
/**
* Initialize the driver for a particular awImage object
*
* @param awImage $image
*/
public function init(awImage $image) {
 
if($this->movie === NULL) {
$this->setImageSize($image->width, $image->height);
// Create movie
$this->movie = new SWFMovie();
if(!$this->movie) {
awImage::drawError("Class Image: Unable to create a graph.");
}
$this->movie->setDimension($image->width, $image->height);
$this->setAntiAliasing($image->getAntiAliasing());
// Original color
$this->filledRectangle(
new awWhite,
new awLine(
new awPoint(0, 0),
new awPoint($this->imageWidth, $this->imageHeight)
)
);
$shadow = $image->shadow;
if($shadow !== NULL) {
$shadow = $shadow->getSpace();
$p1 = new awPoint($shadow->left, $shadow->top);
$p2 = new awPoint($this->imageWidth - $shadow->right - 1, $this->imageHeight - $shadow->bottom - 1);
// Draw image background
$this->filledRectangle($image->getBackground(), new awLine($p1, $p2));
// Draw image border
$image->border->rectangle($this, $p1, $p2);
}
}
}
/**
* Initialize the Driver for a particular FileImage object
*
* @param awFileImage $fileImage The FileImage object to work on
* @param string $file Image filename
*/
public function initFromFile(awFileImage $fileImage, $file) {
}
/**
* Change the image size
*
* @param int $width Image width
* @param int $height Image height
*/
public function setImageSize($width, $height) {
$this->imageWidth = $width;
$this->imageHeight = $height;
}
/**
* Inform the driver of the position of your image
*
* @param float $x Position on X axis of the center of the component
* @param float $y Position on Y axis of the center of the component
*/
public function setPosition($x, $y) {
// Calculate absolute position
$this->x = round($x * $this->imageWidth - $this->w / 2);
$this->y = round($y * $this->imageHeight - $this->h / 2);
}
/**
* Inform the driver of the position of your image
* This method need absolutes values
*
* @param int $x Left-top corner X position
* @param int $y Left-top corner Y position
*/
public function setAbsPosition($x, $y) {
$this->x = $x;
$this->y = $y;
}
/**
* Move the position of the image
*
* @param int $x Add this value to X axis
* @param int $y Add this value to Y axis
*/
public function movePosition($x, $y) {
$this->x += (int)$x;
$this->y += (int)$y;
}
/**
* Inform the driver of the size of your image
* Height and width must be between 0 and 1.
*
* @param int $w Image width
* @param int $h Image height
* @return array Absolute width and height of the image
*/
public function setSize($w, $h) {
// Calcul absolute size
$this->w = round($w * $this->imageWidth);
$this->h = round($h * $this->imageHeight);
return $this->getSize();
}
/**
* Inform the driver of the size of your image
* You can set absolute size with this method.
*
* @param int $w Image width
* @param int $h Image height
*/
public function setAbsSize($w, $h) {
$this->w = $w;
$this->h = $h;
return $this->getSize();
}
/**
* Get the size of the component handled by the driver
*
* @return array Absolute width and height of the component
*/
public function getSize() {
return array($this->w, $this->h);
}
/**
* Turn antialiasing on or off
*
* @var bool $bool
*/
public function setAntiAliasing($bool) {
if($this->movie !== NULL) {
 
$actionscript = '
_quality = "%s";
';
 
if((bool)$bool) {
$actionscript = sprintf($actionscript, 'high');
} else {
$actionscript = sprintf($actionscript, 'low');
}
$this->movie->add(new SWFAction(str_replace("\r", "", $actionscript)));
}
}
/**
* When passed a Color object, returns the corresponding
* color identifier (driver dependant).
*
* @param awColor $color A Color object
* @return array $rgba A color identifier representing the color composed of the given RGB components
*/
public function getColor(awColor $color) {
// Ming simply works with R, G, B and Alpha values.
list($red, $green, $blue, $alpha) = $color->rgba();
// However, the Ming alpha channel ranges from 255 (opaque) to 0 (transparent),
// while the awColor alpha channel ranges from 0 (opaque) to 100 (transparent).
// First, we convert from 0-100 to 0-255.
$alpha = (int)($alpha * 255 / 100);
// Then from 0-255 to 255-0.
$alpha = abs($alpha - 255);
return array($red, $green, $blue, $alpha);
}
/**
* Draw an image here
*
* @param awImage $image Image
* @param int $p1 Image top-left point
* @param int $p2 Image bottom-right point
*/
public function copyImage(awImage $image, awPoint $p1, awPoint $p2) {
}
/**
* Draw an image here
*
* @param awImage $image Image
* @param int $d1 Destination top-left position
* @param int $d2 Destination bottom-right position
* @param int $s1 Source top-left position
* @param int $s2 Source bottom-right position
* @param bool $resample Resample image ? (default to TRUE)
*/
public function copyResizeImage(awImage $image, awPoint $d1, awPoint $d2, awPoint $s1, awPoint $s2, $resample = TRUE) {
}
/**
* Draw a string
*
* @var awText $text Text to print
* @param awPoint $point Draw the text at this point
* @param int $width Text max width
*/
public function string(awText $text, awPoint $point, $width = NULL) {
$font = $text->getFont();
// Can we deal with that font?
if($this->isCompatibleWithFont($font) === FALSE) {
awImage::drawError('Class MingDriver: Incompatible font type (\''.get_class($font).'\')');
}
// Ming can only work with awFileFont objects for now
// (i.e. awFDBFont, or awTuffy et al.)
$fontDriver = $this->fileFontDriver;
if($text->getBackground() !== NULL or $text->border->visible()) {
list($left, $right, $top, $bottom) = $text->getPadding();
 
$textWidth = $fontDriver->getTextWidth($text, $this);
$textHeight = $fontDriver->getTextHeight($text, $this);
$x1 = floor($point->x - $left);
$y1 = floor($point->y - $top);
$x2 = $x1 + $textWidth + $left + $right;
$y2 = $y1 + $textHeight + $top + $bottom;
$this->filledRectangle(
$text->getBackground(),
awLine::build($x1, $y1, $x2, $y2)
);
$text->border->rectangle(
$this,
new awPoint($x1 - 1, $y1 - 1),
new awPoint($x2 + 1, $y2 + 1)
);
}
$fontDriver->string($this, $text, $point, $width);
}
/**
* Draw a pixel
*
* @param awColor $color Pixel color
* @param awPoint $p
*/
public function point(awColor $color, awPoint $p) {
if($p->isHidden() === FALSE) {
list($red, $green, $blue, $alpha) = $this->getColor($color);
$point = new SWFShape();
$point->setLine(1, $red, $green, $blue, $alpha);
$point->movePenTo($this->x + round($p->x), $this->y + round($p->y));
$point->drawLine(0.5, 0.5);
$point->movePen(-0.5, 0);
$point->drawLine(0.5, -0.5);
$this->movie->add($point);
}
}
/**
* Draw a colored line
*
* @param awColor $color Line color
* @param awLine $line
* @param int $thickness Line tickness
*/
public function line(awColor $color, awLine $line) {
if($line->getThickness() > 0 and $line->isHidden() === FALSE) {
list($red, $green, $blue, $alpha) = $this->getColor($color);
 
$mingLine = new SWFShape();
$mingLine->setLine($line->getThickness(), $red, $green, $blue, $alpha);
 
list($p1, $p2) = $line->getLocation();
$mingLine->movePenTo($this->x + round($p1->x), $this->y + round($p1->y));
 
switch($line->getStyle()) {
case awLine::SOLID :
$mingLine->drawLineTo($this->x + round($p2->x), $this->y + round($p2->y));
$this->movie->add($mingLine);
break;
case awLine::DOTTED :
$size = sqrt(pow($p2->y - $p1->y, 2) + pow($p2->x - $p1->x, 2));
$cos = ($p2->x - $p1->x) / $size;
$sin = ($p2->y - $p1->y) / $size;
for($i = 0; $i <= $size; $i += 2) {
$p = new awPoint(
round($i * $cos + $p1->x),
round($i * $sin + $p1->y)
);
$this->point($color, $p);
}
break;
case awLine::DASHED :
$width = $p2->x - $p1->x;
$height = $p2->y - $p1->y;
$size = sqrt(pow($height, 2) + pow($width, 2));
if($size == 0) {
return;
}
$cos = $width / $size;
$sin = $height / $size;
$functionX = ($width > 0) ? 'min' : 'max';
$functionY = ($height > 0) ? 'min' : 'max';
for($i = 0; $i <= $size; $i += 6) {
$t1 = new awPoint(
round($i * $cos + $p1->x),
round($i * $sin + $p1->y)
);
$t2 = new awPoint(
round($functionX(($i + 3) * $cos, $width) + $p1->x),
round($functionY(($i + 3) * $sin, $height) + $p1->y)
);
$this->line($color, new awLine($t1, $t2));
}
break;
}
}
}
/**
* Draw a color arc
* @param awColor $color Arc color
* @param awPoint $center Point center
* @param int $width Ellipse width
* @param int $height Ellipse height
* @param int $from Start angle
* @param int $to End angle
*/
public function arc(awColor $color, awPoint $center, $width, $height, $from, $to) {
}
/**
* Draw an arc with a background color
*
* @param awColor $color Arc background color
* @param awPoint $center Point center
* @param int $width Ellipse width
* @param int $height Ellipse height
* @param int $from Start angle
* @param int $to End angle
*/
public function filledArc(awColor $color, awPoint $center, $width, $height, $from, $to) {
}
/**
* Draw a colored ellipse
*
* @param awColor $color Ellipse color
* @param awPoint $center Ellipse center
* @param int $width Ellipse width
* @param int $height Ellipse height
*/
public function ellipse(awColor $color, awPoint $center, $width, $height) {
}
/**
* Draw an ellipse with a background
*
* @param mixed $background Background (can be a color or a gradient)
* @param awPoint $center Ellipse center
* @param int $width Ellipse width
* @param int $height Ellipse height
*/
public function filledEllipse($background, awPoint $center, $width, $height) {
}
/**
* Draw a colored rectangle
*
* @param awColor $color Rectangle color
* @param awLine $line Rectangle diagonale
* @param awPoint $p2
*/
public function rectangle(awColor $color, awLine $line) {
list($p1, $p2) = $line->getLocation();
// Get Red, Green, Blue and Alpha values for the line
list($r, $g, $b, $a) = $this->getColor($color);
// Calculate the coordinates of the two other points of the rectangle
$p3 = new Point($p1->x, $p2->y);
$p4 = new Point($p2->x, $p1->y);
$side = clone $line;
// Draw the four sides of the rectangle, clockwise
if(
($p1->x <= $p2->x and $p1->y <= $p2->y)
or
($p1->x >= $p2->x and $p1->y >= $p2->y)
) {
$side->setLocation($p1, $p4);
$this->line($color, $side);
$side->setLocation($p4, $p2);
$this->line($color, $side);
$side->setLocation($p2, $p3);
$this->line($color, $side);
$side->setLocation($p3, $p1);
$this->line($color, $side);
} else {
$side->setLocation($p1, $p3);
$this->line($color, $side);
$side->setLocation($p3, $p2);
$this->line($color, $side);
$side->setLocation($p2, $p4);
$this->line($color, $side);
$side->setLocation($p4, $p1);
$this->line($color, $side);
}
}
/**
* Draw a rectangle with a background
*
* @param mixed $background Background (can be a color or a gradient)
* @param awLine $line Rectangle diagonale
*/
public function filledRectangle($background, awLine $line) {
list($p1, $p2) = $line->getLocation();
// Common shape settings
$shape = new SWFShape();
$shape->setLine(0);
if($background instanceof awColor) {
// Get the Red, Green, Blue and Alpha values
list($r, $g, $b, $a) = $this->getColor($background);
$shape->setRightFill($r, $g, $b, $a);
} else if($background instanceof awGradient) {
// Get the Gradient object as an SWFGradient one
list($flashGradient, $style) = $this->getGradient($background);
$fill = $shape->addFill($flashGradient, $style);
// Angles between Artichow and Ming don't match.
// Don't use abs() or vertical gradients get inverted.
$angle = $background->angle - 90;
$fill->rotateTo($angle);
// Move the gradient based on the position of the rectangle we're drawing
$centerX = min($p1->x, $p2->y) + abs($p1->x - $p2->x) / 2;
$centerY = min($p1->y, $p2->y) + abs($p1->y - $p2->y) / 2;
$fill->moveTo($centerX, $centerY);
// Ming draws its gradients on a 1600x1600 image,
// so we have to resize it.
if($angle === -90) {
$ratio = abs($p1->y - $p2->y) / 1600;
} else {
$ratio = abs($p1->x - $p2->x) / 1600;
}
$fill->scaleTo($ratio);
$shape->setRightFill($fill);
}
// Set starting position
$shape->movePenTo($this->x + round($p1->x), $this->y + round($p1->y));
// Depending on the points' relative positions,
// we have two drawing possibilities
if(
($p1->x <= $p2->x and $p1->y <= $p2->y)
or
($p1->x >= $p2->x and $p1->y >= $p2->y)
) {
$shape->drawLineTo($this->x + round($p2->x), $this->y + round($p1->y));
$shape->drawLineTo($this->x + round($p2->x), $this->y + round($p2->y));
$shape->drawLineTo($this->x + round($p1->x), $this->y + round($p2->y));
$shape->drawLineTo($this->x + round($p1->x), $this->y + round($p1->y));
} else {
$shape->drawLineTo($this->x + round($p1->x), $this->y + round($p2->y));
$shape->drawLineTo($this->x + round($p2->x), $this->y + round($p2->y));
$shape->drawLineTo($this->x + round($p2->x), $this->y + round($p1->y));
$shape->drawLineTo($this->x + round($p1->x), $this->y + round($p1->y));
}
$this->movie->add($shape);
}
/**
* Draw a polygon
*
* @param awColor $color Polygon color
* @param Polygon A polygon
*/
public function polygon(awColor $color, awPolygon $polygon) {
$points = $polygon->all();
$count = count($points);
if($count > 1) {
$side = new awLine;
$side->setStyle($polygon->getStyle());
$side->setThickness($polygon->getThickness());
$prev = $points[0];
for($i = 1; $i < $count; $i++) {
$current = $points[$i];
$side->setLocation($prev, $current);
$this->line($color, $side);
$prev = $current;
}
// Close the polygon
$side->setLocation($prev, $points[0]);
$this->line($color, $side);
}
}
/**
* Draw a polygon with a background
*
* @param mixed $background Background (can be a color or a gradient)
* @param Polygon A polygon
*/
public function filledPolygon($background, awPolygon $polygon) {
$shape = new SWFShape();
if($background instanceof awColor) {
list($red, $green, $blue, $alpha) = $this->getColor($background);
$shape->setRightFill($red, $green, $blue, $alpha);
} elseif($background instanceof awGradient) {
list($flashGradient, $style) = $this->getGradient($background);
$fill = $shape->addFill($flashGradient, $style);
list($xMin, $xMax) = $polygon->getBoxXRange();
list($yMin, $yMax) = $polygon->getBoxYRange();
if($background->angle === 0) {
$fill->scaleTo(($yMax - $yMin) / 1600);
} else {
$fill->scaleTo(($xMax - $xMin) / 1600);
}
$fill->moveTo($xMin + ($xMax - $xMin) / 2, $yMin + ($yMax - $yMin) / 2);
$shape->setRightFill($fill);
}
$points = $polygon->all();
$count = count($points);
if($count > 1) {
$prev = $points[0];
$shape->movePenTo($prev->x, $prev->y);
for($i = 1; $i < $count; $i++) {
$current = $points[$i];
$shape->drawLineTo($current->x, $current->y);
}
// Close the polygon
$shape->drawLineTo($prev->x, $prev->y);
$this->movie->add($shape);
}
}
 
/**
* Sends the image, as well as the correct HTTP headers, to the browser
*
* @param awImage $image The Image object to send
*/
public function send(awImage $image) {
$this->drawImage($image);
}
/**
* Get the image as binary data
*
* @param awImage $image
*/
public function get(awImage $image) {
return $this->drawImage($image, TRUE, FALSE);
}
public function getTextWidth(awText $text) {
$font = $text->getFont();
if($this->isCompatibleWithFont($font) === FALSE) {
awImage::drawError('Class MingDriver: Incompatible font type (\''.get_class($font).'\')');
}
// Ming only supports FileFont
$fontDriver = $this->fileFontDriver;
return $fontDriver->getTextWidth($text, $this);
}
public function getTextHeight(awText $text) {
$font = $text->getFont();
if($this->isCompatibleWithFont($font) === FALSE) {
awImage::drawError('Class MingDriver: Incompatible font type (\''.get_class($font).'\')');
}
// Ming only supports FileFont
$fontDriver = $this->fileFontDriver;
return $fontDriver->getTextHeight($text, $this);
}
protected function isCompatibleWithFont(awFont $font) {
if($font instanceof awTTFFont or $font instanceof awPHPFont) {
return FALSE;
} else {
return TRUE;
}
}
private function drawImage(awImage $image, $return = FALSE, $header = TRUE) {
// Send headers to the browser
if($header === TRUE) {
$image->sendHeaders();
}
if($return) {
ob_start();
}
$this->movie->output();
if($return) {
return ob_get_clean();
}
}
 
/**
* Convert an awGradient object to an SWFGradient one.
* Returns an object as well as the style of the Flash gradient.
*
* @param awGradient $gradient The awGradient object to convert
* @return array
*/
private function getGradient(awGradient $gradient) {
$flashGradient = new SWFGradient();
// Get RGBA values for the gradient boundaries
list($r1, $g1, $b1, $a1) = $this->getColor($gradient->from);
list($r2, $g2, $b2, $a2) = $this->getColor($gradient->to);
$flashGradient->addEntry(0, $r1, $g1, $b1, $a1);
if($gradient instanceof awBilinearGradient) {
$flashGradient->addEntry($gradient->center, $r2, $g2, $b2, $a2);
$flashGradient->addEntry(1, $r1, $g1, $b1, $a1);
return array($flashGradient, SWFFILL_LINEAR_GRADIENT);
} else {
 
$flashGradient->addEntry(1, $r2, $g2, $b2, $a2);
if($gradient instanceof awLinearGradient) {
return array($flashGradient, SWFFILL_LINEAR_GRADIENT);
} else {
return array($flashGradient, SWFFILL_RADIAL_GRADIENT);
}
}
}
// abstract private function getPolygonPoints(awPolygon $polygon);
 
}
 
registerClass('MingDriver');
 
/*
* Check for ming presence
*/
if(function_exists('ming_useswfversion') === FALSE) {
awImage::drawErrorFile('missing-ming');
}
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Grid.class.php
New file
0,0 → 1,291
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
/**
* Grid
*
* @package Artichow
*/
class awGrid {
/**
* Vertical lines of the grid
*
* @var array
*/
private $xgrid = array();
/**
* Horizontal lines of the grid
*
* @var array
*/
private $ygrid = array();
 
/**
* Is the component grid hidden ?
*
* @var bool
*/
private $hide = FALSE;
 
/**
* Are horizontal lines hidden ?
*
* @var bool
*/
private $hideHorizontal = FALSE;
 
/**
* Are vertical lines hidden ?
*
* @var bool
*/
private $hideVertical = FALSE;
/**
* Grid color
*
* @var Color
*/
private $color;
/**
* Grid space
*
* @var int
*/
private $space;
/**
* Line type
*
* @var int
*/
private $type = awLine::SOLID;
/**
* Grid interval
*
* @var int
*/
private $interval = array(1, 1);
/**
* Grid background color
*
* @var Color
*/
private $background;
/**
* Build the factory
*/
public function __construct() {
// Set a grid default color
$this->color = new awColor(210, 210, 210);
$this->background = new awColor(255, 255, 255, 100);
}
/**
* Hide grid ?
*
* @param bool $hide
*/
public function hide($hide = TRUE) {
$this->hide = (bool)$hide;
}
/**
* Hide horizontal lines ?
*
* @param bool $hideHorizontal
*/
public function hideHorizontal($hide = TRUE) {
$this->hideHorizontal = (bool)$hide;
}
/**
* Hide vertical lines ?
*
* @param bool $hideVertical
*/
public function hideVertical($hide = TRUE) {
$this->hideVertical = (bool)$hide;
}
/**
* Change grid color
*
* @param awColor $color
*/
public function setColor(awColor $color) {
$this->color = $color;
}
/**
* Remove grid background
*/
public function setNoBackground() {
$this->background = NULL;
}
/**
* Change grid background color
*
* @param awColor $color
*/
public function setBackgroundColor(awColor $color) {
$this->background = $color;
}
/**
* Change line type
*
* @param int $type
*/
public function setType($type) {
$this->type = (int)$type;
}
/**
* Change grid interval
*
* @param int $hInterval
* @param int $vInterval
*/
public function setInterval($hInterval, $vInterval) {
$this->interval = array((int)$hInterval, (int)$vInterval);
}
/**
* Set grid space
*
* @param int $left Left space in pixels
* @param int $right Right space in pixels
* @param int $top Top space in pixels
* @param int $bottom Bottom space in pixels
*/
public function setSpace($left, $right, $top, $bottom) {
$this->space = array((int)$left, (int)$right, (int)$top, (int)$bottom);
}
/**
* Change the current grid
*
* @param array $xgrid Vertical lines
* @param array $ygrid Horizontal lines
*/
public function setGrid($xgrid, $ygrid) {
if(empty($this->xgrid)) {
$this->xgrid = $xgrid;
}
if(empty($this->ygrid)) {
$this->ygrid = $ygrid;
}
}
/**
* Draw grids
*
* @param awDriver $driver A driver object
* @param int $x1
* @param int $y1
* @param int $x2
* @param int $y2
*/
public function draw(awDriver $driver, $x1, $y1, $x2, $y2) {
if($this->background instanceof awColor) {
// Draw background color
$driver->filledRectangle(
$this->background,
awLine::build($x1, $y1, $x2, $y2)
);
}
 
if($this->hide === FALSE) {
$this->drawGrid(
$driver,
$this->color,
$this->hideVertical ? array() : $this->xgrid,
$this->hideHorizontal ? array() : $this->ygrid,
$x1, $y1, $x2, $y2,
$this->type,
$this->space,
$this->interval[0],
$this->interval[1]
);
}
}
private function drawGrid(
awDriver $driver, awColor $color,
$nx, $ny, $x1, $y1, $x2, $y2,
$type, $space, $hInterval, $vInterval
) {
list($left, $right, $top, $bottom) = $space;
$width = $x2 - $x1 - $left - $right;
$height = $y2 - $y1 - $top - $bottom;
foreach($nx as $key => $n) {
if(($key % $vInterval) === 0) {
$pos = (int)round($x1 + $left + $n * $width);
$driver->line(
$color,
new awLine(
new awPoint($pos, $y1),
new awPoint($pos, $y2),
$type
)
);
}
}
foreach($ny as $key => $n) {
if(($key % $hInterval) === 0) {
$pos = (int)round($y1 + $top + $n * $height);
$driver->line(
$color,
new awLine(
new awPoint($x1, $pos),
new awPoint($x2, $pos),
$type
)
);
}
}
}
 
}
 
registerClass('Grid');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Shadow.class.php
New file
0,0 → 1,406
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
 
/**
* Draw shadows
*
*/
class awShadow {
 
/**
* Shadow on left and top sides
*
* @var int
*/
const LEFT_TOP = 1;
 
/**
* Shadow on left and bottom sides
*
* @var int
*/
const LEFT_BOTTOM = 2;
 
/**
* Shadow on right and top sides
*
* @var int
*/
const RIGHT_TOP = 3;
 
/**
* Shadow on right and bottom sides
*
* @var int
*/
const RIGHT_BOTTOM = 4;
/**
* In mode
*
* @var int
*/
const IN = 1;
/**
* Out mode
*
* @var int
*/
const OUT = 2;
 
/**
* Shadow size
*
* @var int
*/
private $size = 0;
/**
* Hide shadow ?
*
* @var bool
*/
protected $hide = FALSE;
 
/**
* Shadow color
*
* @var Color
*/
private $color;
 
/**
* Shadow position
*
* @var int
*/
private $position;
 
/**
* Smooth shadow ?
*
* @var bool
*/
private $smooth = FALSE;
/**
* Shadow constructor
*
* @param int $position Shadow position
*/
public function __construct($position) {
$this->setPosition($position);
}
/**
* Hide shadow ?
*
* @param bool $hide
*/
public function hide($hide = TRUE) {
$this->hide = (bool)$hide;
}
/**
* Show shadow ?
*
* @param bool $show
*/
public function show($show = TRUE) {
$this->hide = (bool)!$show;
}
/**
* Change shadow size
*
* @param int $size
* @param bool $smooth Smooth the shadow (facultative argument)
*/
public function setSize($size, $smooth = NULL) {
$this->size = (int)$size;
if($smooth !== NULL) {
$this->smooth($smooth);
}
}
/**
* Change shadow color
*
* @param awColor $color
*/
public function setColor(awColor $color) {
$this->color = $color;
}
/**
* Change shadow position
*
* @param int $position
*/
public function setPosition($position) {
$this->position = (int)$position;
}
/**
* Smooth shadow ?
*
* @param bool $smooth
*/
public function smooth($smooth) {
$this->smooth = (bool)$smooth;
}
/**
* Get the space taken by the shadow
*
* @return Side
*/
public function getSpace() {
return new awSide(
($this->position === awShadow::LEFT_TOP or $this->position === awShadow::LEFT_BOTTOM) ? $this->size : 0,
($this->position === awShadow::RIGHT_TOP or $this->position === awShadow::RIGHT_BOTTOM) ? $this->size : 0,
($this->position === awShadow::LEFT_TOP or $this->position === awShadow::RIGHT_TOP) ? $this->size : 0,
($this->position === awShadow::LEFT_BOTTOM or $this->position === awShadow::RIGHT_BOTTOM) ? $this->size : 0
);
}
/**
* Draw shadow
*
* @param awDriver $driver
* @param awPoint $p1 Top-left point
* @param awPoint $p2 Right-bottom point
* @param int Drawing mode
*/
public function draw(awDriver $driver, awPoint $p1, awPoint $p2, $mode) {
if($this->hide) {
return;
}
if($this->size <= 0) {
return;
}
$driver = clone $driver;
$color = ($this->color instanceof awColor) ? $this->color : new awColor(125, 125, 125);
switch($this->position) {
case awShadow::RIGHT_BOTTOM :
if($mode === awShadow::OUT) {
$t1 = $p1->move(0, 0);
$t2 = $p2->move($this->size + 1, $this->size + 1);
} else { // PHP 4 compatibility
$t1 = $p1->move(0, 0);
$t2 = $p2->move(0, 0);
}
$width = $t2->x - $t1->x;
$height = $t2->y - $t1->y;
$driver->setAbsPosition($t1->x + $driver->x, $t1->y + $driver->y);
$driver->filledRectangle(
$color,
new awLine(
new awPoint($width - $this->size, $this->size),
new awPoint($width - 1, $height - 1)
)
);
$driver->filledRectangle(
$color,
new awLine(
new awPoint($this->size, $height - $this->size),
new awPoint($width - $this->size - 1, $height - 1)
)
);
$this->smoothPast($driver, $color, $width, $height);
break;
case awShadow::LEFT_TOP :
if($mode === awShadow::OUT) {
$t1 = $p1->move(- $this->size, - $this->size);
$t2 = $p2->move(0, 0);
} else { // PHP 4 compatibility
$t1 = $p1->move(0, 0);
$t2 = $p2->move(0, 0);
}
$width = $t2->x - $t1->x;
$height = $t2->y - $t1->y;
$driver->setAbsPosition($t1->x + $driver->x, $t1->y + $driver->y);
$height = max($height + 1, $this->size);
$driver->filledRectangle(
$color,
new awLine(
new awPoint(0, 0),
new awPoint($this->size - 1, $height - $this->size - 1)
)
);
$driver->filledRectangle(
$color,
new awLine(
new awPoint($this->size, 0),
new awPoint($width - $this->size - 1, $this->size - 1)
)
);
$this->smoothPast($driver, $color, $width, $height);
break;
case awShadow::RIGHT_TOP :
if($mode === awShadow::OUT) {
$t1 = $p1->move(0, - $this->size);
$t2 = $p2->move($this->size + 1, 0);
} else { // PHP 4 compatibility
$t1 = $p1->move(0, 0);
$t2 = $p2->move(0, 0);
}
$width = $t2->x - $t1->x;
$height = $t2->y - $t1->y;
$driver->setAbsPosition($t1->x + $driver->x, $t1->y + $driver->y);
$height = max($height + 1, $this->size);
$driver->filledRectangle(
$color,
new awLine(
new awPoint($width - $this->size, 0),
new awPoint($width - 1, $height - $this->size - 1)
)
);
$driver->filledRectangle(
$color,
new awLine(
new awPoint($this->size, 0),
new awPoint($width - $this->size - 1, $this->size - 1)
)
);
$this->smoothFuture($driver, $color, $width, $height);
break;
case awShadow::LEFT_BOTTOM :
if($mode === awShadow::OUT) {
$t1 = $p1->move(- $this->size, 0);
$t2 = $p2->move(0, $this->size + 1);
} else { // PHP 4 compatibility
$t1 = $p1->move(0, 0);
$t2 = $p2->move(0, 0);
}
$width = $t2->x - $t1->x;
$height = $t2->y - $t1->y;
$driver->setAbsPosition($t1->x + $driver->x, $t1->y + $driver->y);
$driver->filledRectangle(
$color,
new awLine(
new awPoint(0, $this->size),
new awPoint($this->size - 1, $height - 1)
)
);
$driver->filledRectangle(
$color,
new awLine(
new awPoint($this->size, $height - $this->size),
new awPoint($width - $this->size - 1, $height - 1)
)
);
$this->smoothFuture($driver, $color, $width, $height);
break;
}
}
private function smoothPast(awDriver $driver, awColor $color, $width, $height) {
if($this->smooth) {
for($i = 0; $i < $this->size; $i++) {
for($j = 0; $j <= $i; $j++) {
$driver->point(
$color,
new awPoint($i, $j + $height - $this->size)
);
}
}
for($i = 0; $i < $this->size; $i++) {
for($j = 0; $j <= $i; $j++) {
$driver->point(
$color,
new awPoint($width - $this->size + $j, $i)
);
}
}
}
}
private function smoothFuture(awDriver $driver, awColor $color, $width, $height) {
if($this->smooth) {
for($i = 0; $i < $this->size; $i++) {
for($j = 0; $j <= $i; $j++) {
$driver->point(
$color,
new awPoint($i, $this->size - $j - 1)
);
}
}
for($i = 0; $i < $this->size; $i++) {
for($j = 0; $j <= $i; $j++) {
$driver->point(
$color,
new awPoint($width - $this->size + $j, $height - $i - 1)
);
}
}
}
}
 
}
 
registerClass('Shadow');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Math.class.php
New file
0,0 → 1,832
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
 
abstract class awShape {
/**
* Is the shape hidden ?
*
* @var bool
*/
protected $hide = FALSE;
/**
* Shape style
*
* @var int
*/
public $style;
/**
* Shape thickness
*
* @var int
*/
public $thickness;
/**
* Solid shape
*
* @var int
*/
const SOLID = 1;
/**
* Dotted shape
*
* @var int
*/
const DOTTED = 2;
/**
* Dashed shape
*
* @var int
*/
const DASHED = 3;
/**
* Change shape style
*
* @param int $style Line style
*/
public function setStyle($style) {
$this->style = (int)$style;
}
/**
* Return shape style
*
* @return int
*/
public function getStyle() {
return $this->style;
}
/**
* Change shape thickness
*
* @param int $thickness Shape thickness in pixels
*/
public function setThickness($thickness) {
$this->thickness = (int)$thickness;
}
/**
* Return shape thickness
*
* @return int
*/
public function getThickness() {
return $this->thickness;
}
/**
* Hide the shape
*
* @param bool $hide
*/
public function hide($hide) {
$this->hide = (bool)$hide;
}
/**
* Show the shape
*
* @param bool $shape
*/
public function show($shape) {
$this->hide = (bool)!$shape;
}
/**
* Is the line hidden ?
*
* @return bool
*/
public function isHidden() {
return $this->hide;
}
}
 
registerClass('Shape', TRUE);
 
/**
* Describe a point
*
* @package Artichow
*/
class awPoint extends awShape {
 
/**
* X coord
*
* @var float
*/
public $x;
 
/**
* Y coord
*
* @var float
*/
public $y;
/**
* Build a new awpoint
*
* @param float $x
* @param float $y
*/
public function __construct($x, $y) {
$this->setLocation($x, $y);
}
/**
* Change X value
*
* @param float $x
*/
public function setX($x) {
$this->x = (float)$x;
}
/**
* Change Y value
*
* @param float $y
*/
public function setY($y) {
$this->y = (float)$y;
}
/**
* Change point location
*
* @param float $x
* @param float $y
*/
public function setLocation($x, $y) {
$this->setX($x);
$this->setY($y);
}
/**
* Get point location
*
* @param array Point location
*/
public function getLocation() {
return array($this->x, $this->y);
}
/**
* Get distance to another point
*
* @param awPoint $p A point
* @return float
*/
public function getDistance(awPoint $p) {
return sqrt(pow($p->x - $this->x, 2) + pow($p->y - $this->y, 2));
}
/**
* Move the point to another location
*
* @param Point A Point with the new awlocation
*/
public function move($x, $y) {
return new awPoint(
$this->x + $x,
$this->y + $y
);
}
 
}
 
registerClass('Point');
 
/**
* Describe a line
*
* @package Artichow
*/
class awLine extends awShape {
 
/**
* Line first point
*
* @param Point
*/
public $p1;
 
/**
* Line second point
*
* @param Point
*/
public $p2;
/**
* The line slope (the m in y = mx + p)
*
* @param float
*/
private $slope;
/**
* The y-intercept value of the line (the p in y = mx + p)
*
* @param float
*/
private $origin;
/**
* Build a new awline
*
* @param awPoint $p1 First point
* @param awPoint $p2 Second point
* @param int $type Style of line (default to solid)
* @param int $thickness Line thickness (default to 1)
*/
public function __construct($p1 = NULL, $p2 = NULL, $type = awLine::SOLID, $thickness = 1) {
$this->setLocation($p1, $p2);
$this->setStyle($type);
$this->setThickness($thickness);
}
/**
* Build a line from 4 coords
*
* @param int $x1 Left position
* @param int $y1 Top position
* @param int $x2 Right position
* @param int $y2 Bottom position
*/
public static function build($x1, $y1, $x2, $y2) {
return new awLine(
new awPoint($x1, $y1),
new awPoint($x2, $y2)
);
}
/**
* Change X values of the line
*
* @param int $x1 Begin value
* @param int $x2 End value
*/
public function setX($x1, $x2) {
$this->p1->setX($x1);
$this->p2->setX($x2);
// Resets slope and origin values so they are
// recalculated when and if needed.
$this->slope = NULL;
$this->origin = NULL;
}
/**
* Change Y values of the line
*
* @param int $y1 Begin value
* @param int $y2 End value
*/
public function setY($y1, $y2) {
$this->p1->setY($y1);
$this->p2->setY($y2);
// Resets slope and origin values so they are
// recalculated when and if needed.
$this->slope = NULL;
$this->origin = NULL;
}
/**
* Change line location
*
* @param awPoint $p1 First point
* @param awPoint $p2 Second point
*/
public function setLocation($p1, $p2) {
if(is_null($p1) or $p1 instanceof awPoint) {
$this->p1 = $p1;
}
if(is_null($p2) or $p2 instanceof awPoint) {
$this->p2 = $p2;
}
// Resets slope and origin values so they are
// recalculated when and if needed.
$this->slope = NULL;
$this->origin = NULL;
}
/**
* Get line location
*
* @param array Line location
*/
public function getLocation() {
return array($this->p1, $this->p2);
}
/**
* Get the line size
*
* @return float
*/
public function getSize() {
$square = pow($this->p2->x - $this->p1->x, 2) + pow($this->p2->y - $this->p1->y, 2);
return sqrt($square);
}
/**
* Calculate the line slope
*
*/
private function calculateSlope() {
if($this->isHorizontal()) {
$this->slope = 0;
} else {
$slope = ($this->p1->y - $this->p2->y) / ($this->p1->x - $this->p2->x);
$this->slope = $slope;
}
}
/**
* Calculate the y-intercept value of the line
*
*/
private function calculateOrigin() {
if($this->isHorizontal()) {
$this->origin = $this->p1->y; // Or p2->y
} else {
$y1 = $this->p1->y;
$y2 = $this->p2->y;
$x1 = $this->p1->x;
$x2 = $this->p2->x;
$origin = ($y2 * $x1 - $y1 * $x2) / ($x1 - $x2);
$this->origin = $origin;
}
}
/**
* Calculate the slope and y-intercept value of the line
*
*/
private function calculateEquation() {
$this->calculateSlope();
$this->calculateOrigin();
}
/**
* Get the line slope value
*
* @return float
*/
public function getSlope() {
if($this->isVertical()) {
return NULL;
} elseif($this->slope !== NULL) {
return $this->slope;
} else {
$this->calculateSlope();
return $this->slope;
}
}
/**
* Get the line y-intercept value
*
* @return float
*/
public function getOrigin() {
if($this->isVertical()) {
return NULL;
} elseif($this->origin !== NULL) {
return $this->origin;
} else {
$this->calculateOrigin();
return $this->origin;
}
}
/**
* Get the line equation
*
* @return array An array containing the slope and y-intercept value of the line
*/
public function getEquation() {
$slope = $this->getSlope();
$origin = $this->getOrigin();
return array($slope, $origin);
}
/**
* Return the x coordinate of a point on the line
* given its y coordinate.
*
* @param float $y The y coordinate of the Point
* @return float $x The corresponding x coordinate
*/
public function getXFrom($y) {
$x = NULL;
if($this->isVertical()) {
list($p, ) = $this->getLocation();
$x = $p->x;
} else {
list($slope, $origin) = $this->getEquation();
if($slope !== 0) {
$y = (float)$y;
$x = ($y - $origin) / $slope;
}
}
return $x;
}
/**
* Return the y coordinate of a point on the line
* given its x coordinate.
*
* @param float $x The x coordinate of the Point
* @return float $y The corresponding y coordinate
*/
public function getYFrom($x) {
$y = NULL;
if($this->isHorizontal()) {
list($p, ) = $this->getLocation();
$y = $p->y;
} else {
list($slope, $origin) = $this->getEquation();
if($slope !== NULL) {
$x = (float)$x;
$y = $slope * $x + $origin;
}
}
return $y;
}
/**
* Test if the line can be considered as a point
*
* @return bool
*/
public function isPoint() {
return ($this->p1->x === $this->p2->x and $this->p1->y === $this->p2->y);
}
/**
* Test if the line is a vertical line
*
* @return bool
*/
public function isVertical() {
return ($this->p1->x === $this->p2->x);
}
/**
* Test if the line is an horizontal line
*
* @return bool
*/
public function isHorizontal() {
return ($this->p1->y === $this->p2->y);
}
/**
* Returns TRUE if the line is going all the way from the top
* to the bottom of the polygon surrounding box.
*
* @param $polygon Polygon A Polygon object
* @return bool
*/
public function isTopToBottom(awPolygon $polygon) {
list($xMin, $xMax) = $polygon->getBoxXRange();
list($yMin, $yMax) = $polygon->getBoxYRange();
if($this->isHorizontal()) {
return FALSE;
} else {
if($this->p1->y < $this->p2->y) {
$top = $this->p1;
$bottom = $this->p2;
} else {
$top = $this->p2;
$bottom = $this->p1;
}
return (
$this->isOnBoxTopSide($top, $xMin, $xMax, $yMin)
and
$this->isOnBoxBottomSide($bottom, $xMin, $xMax, $yMax)
);
}
}
/**
* Returns TRUE if the line is going all the way from the left side
* to the right side of the polygon surrounding box.
*
* @param $polygon Polygon A Polygon object
* @return bool
*/
public function isLeftToRight(awPolygon $polygon) {
list($xMin, $xMax) = $polygon->getBoxXRange();
list($yMin, $yMax) = $polygon->getBoxYRange();
if($this->isVertical()) {
return FALSE;
} else {
if($this->p1->x < $this->p2->x) {
$left = $this->p1;
$right = $this->p2;
} else {
$left = $this->p2;
$right = $this->p1;
}
}
return (
$this->isOnBoxLeftSide($left, $yMin, $yMax, $xMin)
and
$this->isOnBoxRightSide($right, $yMin, $yMax, $xMax)
);
}
private function isOnBoxTopSide(awPoint $point, $xMin, $xMax, $yMin) {
if(
$point->y === $yMin
and
$point->x >= $xMin
and
$point->x <= $xMax
) {
return TRUE;
} else {
return FALSE;
}
}
 
private function isOnBoxBottomSide(awPoint $point, $xMin, $xMax, $yMax) {
if(
$point->y === $yMax
and
$point->x >= $xMin
and
$point->x <= $xMax
) {
return TRUE;
} else {
return FALSE;
}
}
private function isOnBoxLeftSide(awPoint $point, $yMin, $yMax, $xMin) {
if(
$point->x === $xMin
and
$point->y >= $yMin
and
$point->y <= $yMax
) {
return TRUE;
} else {
return FALSE;
}
}
private function isOnBoxRightSide(awPoint $point, $yMin, $yMax, $xMax) {
if(
$point->x === $xMax
and
$point->y >= $yMin
and
$point->y <= $yMax
) {
return TRUE;
} else {
return FALSE;
}
}
}
 
registerClass('Line');
 
/**
* A vector is a type of line
* The sense of the vector goes from $p1 to $p2.
*
* @package Artichow
*/
class awVector extends awLine {
/**
* Get vector angle in radians
*
* @return float
*/
public function getAngle() {
if($this->isPoint()) {
return 0.0;
}
$size = $this->getSize();
$width = ($this->p2->x - $this->p1->x);
$height = ($this->p2->y - $this->p1->y) * -1;
if($width >= 0 and $height >= 0) {
return acos($width / $size);
} else if($width <= 0 and $height >= 0) {
return acos($width / $size);
} else {
$height *= -1;
if($width >= 0 and $height >= 0) {
return 2 * M_PI - acos($width / $size);
} else if($width <= 0 and $height >= 0) {
return 2 * M_PI - acos($width / $size);
}
}
}
 
}
 
registerClass('Vector');
 
/**
* Describe a polygon
*
* @package Artichow
*/
class awPolygon extends awShape {
 
/**
* Polygon points
*
* @var array
*/
protected $points = array();
 
/**
* Set a point in the polygon
*
* @param int $pos Point position
* @param awPoint $point
*/
public function set($pos, $point) {
if(is_null($point) or $point instanceof awPoint) {
$this->points[$pos] = $point;
}
}
/**
* Add a point at the end of the polygon
*
* @param awPoint $point
*/
public function append($point) {
if(is_null($point) or $point instanceof awPoint) {
$this->points[] = $point;
}
}
/**
* Get a point at a position in the polygon
*
* @param int $pos Point position
* @return Point
*/
public function get($pos) {
return $this->points[$pos];
}
/**
* Count number of points in the polygon
*
* @return int
*/
public function count() {
return count($this->points);
}
/**
* Returns all points in the polygon
*
* @return array
*/
public function all() {
return $this->points;
}
/**
* Returns the different lines formed by the polygon vertices
*
* @return array
*/
public function getLines() {
$lines = array();
$count = $this->count();
for($i = 0; $i < $count - 1; $i++) {
$lines[] = new Line($this->get($i), $this->get($i + 1));
}
// "Close" the polygon
$lines[] = new Line($this->get($count - 1), $this->get(0));
 
return $lines;
}
/**
* Get the upper-left and lower-right points
* of the bounding box around the polygon
*
* @return array An array of two Point objects
*/
public function getBoxPoints() {
$count = $this->count();
$x = $y = array();
for($i = 0; $i < $count; $i++) {
$point = $this->get($i);
list($x[], $y[]) = $point->getLocation();
}
$upperLeft = new Point(min($x), min($y));
$lowerRight = new Point(max($x), max($y));
return array($upperLeft, $lowerRight);
}
/**
* Return the range of the polygon on the y axis,
* i.e. the minimum and maximum y value of any point in the polygon
*
* @return array
*/
public function getBoxYRange() {
list($p1, $p2) = $this->getBoxPoints();
list(, $yMin) = $p1->getLocation();
list(, $yMax) = $p2->getLocation();
return array($yMin, $yMax);
}
/**
* Return the range of the polygon on the x axis,
* i.e. the minimum and maximum x value of any point in the polygon
*
* @return array
*/
public function getBoxXRange() {
list($p1, $p2) = $this->getBoxPoints();
list($xMin, ) = $p1->getLocation();
list($xMax, ) = $p2->getLocation();
return array($xMin, $xMax);
}
 
}
 
registerClass('Polygon');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Mark.class.php
New file
0,0 → 1,490
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
 
/**
* Draw marks
*
* @package Artichow
*/
class awMark {
 
/**
* Circle mark
*
* @var int
*/
const CIRCLE = 1;
 
/**
* Square mark
*
* @var int
*/
const SQUARE = 2;
 
/**
* Triangle mark
*
* @var int
*/
const TRIANGLE = 3;
/**
* Inverted triangle mark
*
* @var int
*/
const INVERTED_TRIANGLE = 4;
 
/**
* Rhombus mark
*
* @var int
*/
const RHOMBUS = 5;
 
/**
* Cross (X) mark
*
* @var int
*/
const CROSS = 6;
 
/**
* Plus mark
*
* @var int
*/
const PLUS = 7;
 
/**
* Image mark
*
* @var int
*/
const IMAGE = 8;
 
/**
* Star mark
*
* @var int
*/
const STAR = 9;
 
/**
* Paperclip mark
*
* @var int
*/
const PAPERCLIP = 10;
 
/**
* Book mark
*
* @var int
*/
const BOOK = 11;
 
/**
* Must marks be hidden ?
*
* @var bool
*/
protected $hide;
 
/**
* Mark type
*
* @var int
*/
protected $type;
 
/**
* Mark size
*
* @var int
*/
protected $size = 8;
 
/**
* Fill mark
*
* @var Color, Gradient
*/
protected $fill;
 
/**
* Mark image
*
* @var Image
*/
protected $image;
 
/**
* To draw marks
*
* @var Driver
*/
protected $driver;
 
/**
* Move position from this vector
*
* @var Point
*/
protected $move;
/**
* Marks border
*
* @var Border
*/
public $border;
 
/**
* Build the mark
*/
public function __construct() {
$this->fill = new awColor(255, 0, 0, 0);
$this->border = new awBorder;
$this->border->hide();
$this->move = new awPoint(0, 0);
}
/**
* Change mark position
*
* @param int $x Add this interval to X coord
* @param int $y Add this interval to Y coord
*/
public function move($x, $y) {
$this->move = $this->move->move($x, $y);
}
/**
* Hide marks ?
*
* @param bool $hide TRUE to hide marks, FALSE otherwise
*/
public function hide($hide = TRUE) {
$this->hide = (bool)$hide;
}
/**
* Show marks ?
*
* @param bool $show
*/
public function show($show = TRUE) {
$this->hide = (bool)!$show;
}
/**
* Change mark type
*
* @param int $size Size in pixels
*/
public function setSize($size) {
$this->size = (int)$size;
}
/**
* Change mark type
*
* @param int $type New mark type
* @param int $size Mark size (can be NULL)
*/
public function setType($type, $size = NULL) {
$this->type = (int)$type;
if($size !== NULL) {
$this->setSize($size);
}
}
/**
* Fill the mark with a color or a gradient
*
* @param mixed $fill A color or a gradient
*/
public function setFill($fill) {
if($fill instanceof awColor or $fill instanceof awGradient) {
$this->fill = $fill;
}
}
/**
* Set an image
* Only for awMark::IMAGE type.
*
* @param Image An image
*/
public function setImage(awImage $image) {
$this->image = $image;
}
/**
* Draw the mark
*
* @param awDriver $driver
* @param awPoint $point Mark center
*/
public function draw(awDriver $driver, awPoint $point) {
// Hide marks ?
if($this->hide) {
return;
}
// Check if we can print marks
if($this->type !== NULL) {
$this->driver = $driver;
$realPoint = $this->move->move($point->x, $point->y);
switch($this->type) {
case awMark::CIRCLE :
$this->drawCircle($realPoint);
break;
case awMark::SQUARE :
$this->drawSquare($realPoint);
break;
case awMark::TRIANGLE :
$this->drawTriangle($realPoint);
break;
 
case awMark::INVERTED_TRIANGLE :
$this->drawTriangle($realPoint, TRUE);
break;
case awMark::RHOMBUS :
$this->drawRhombus($realPoint);
break;
 
case awMark::CROSS :
$this->drawCross($realPoint);
break;
case awMark::PLUS :
$this->drawCross($realPoint, TRUE);
break;
case awMark::IMAGE :
$this->drawImage($realPoint);
break;
case awMark::STAR :
$this->changeType('star');
$this->draw($driver, $point);
break;
case awMark::PAPERCLIP :
$this->changeType('paperclip');
$this->draw($driver, $point);
break;
case awMark::BOOK :
$this->changeType('book');
$this->draw($driver, $point);
break;
}
}
}
protected function changeType($image) {
$this->setType(awMARK::IMAGE);
$this->setImage(new awFileImage(ARTICHOW_IMAGE.DIRECTORY_SEPARATOR.$image.'.png'));
}
protected function drawCircle(awPoint $point) {
$this->driver->filledEllipse(
$this->fill,
$point,
$this->size, $this->size
);
$this->border->ellipse(
$this->driver,
$point,
$this->size, $this->size
);
}
protected function drawSquare(awPoint $point) {
list($x, $y) = $point->getLocation();
$x1 = (int)($x - $this->size / 2);
$x2 = $x1 + $this->size;
$y1 = (int)($y - $this->size / 2);
$y2 = $y1 + $this->size;
$this->border->rectangle($this->driver, new awPoint($x1, $y1), new awPoint($x2, $y2));
$size = $this->border->visible() ? 1 : 0;
$this->driver->filledRectangle(
$this->fill,
new awLine(
new awPoint($x1 + $size, $y1 + $size),
new awPoint($x2 - $size, $y2 - $size)
)
);
}
protected function drawTriangle(awPoint $point, $inverted = FALSE) {
list($x, $y) = $point->getLocation();
$size = $this->size;
$triangle = new awPolygon;
// Set default style and thickness
$triangle->setStyle(awPolygon::SOLID);
$triangle->setThickness(1);
if($inverted === TRUE) {
// Bottom of the triangle
$triangle->append(new awPoint($x, $y + $size / sqrt(3)));
// Upper left corner
$triangle->append(new awPoint($x - $size / 2, $y - $size / (2 * sqrt(3))));
 
// Upper right corner
$triangle->append(new awPoint($x + $size / 2, $y - $size / (2 * sqrt(3))));
} else {
// Top of the triangle
$triangle->append(new awPoint($x, $y - $size / sqrt(3)));
// Lower left corner
$triangle->append(new awPoint($x - $size / 2, $y + $size / (2 * sqrt(3))));
// Lower right corner
$triangle->append(new awPoint($x + $size / 2, $y + $size / (2 * sqrt(3))));
}
 
$this->driver->filledPolygon($this->fill, $triangle);
if($this->border->visible()) {
$this->border->polygon($this->driver, $triangle);
}
}
protected function drawRhombus(awPoint $point) {
list($x, $y) = $point->getLocation();
 
$rhombus = new awPolygon;
// Set default style and thickness
$rhombus->setStyle(awPolygon::SOLID);
$rhombus->setThickness(1);
// Top of the rhombus
$rhombus->append(new awPoint($x, $y - $this->size / 2));
// Right of the rhombus
$rhombus->append(new awPoint($x + $this->size / 2, $y));
// Bottom of the rhombus
$rhombus->append(new awPoint($x, $y + $this->size / 2));
// Left of the rhombus
$rhombus->append(new awPoint($x - $this->size / 2, $y));
$this->driver->filledPolygon($this->fill, $rhombus);
if($this->border->visible()) {
$this->border->polygon($this->driver, $rhombus);
}
}
protected function drawCross(awPoint $point, $upright = FALSE) {
list($x, $y) = $point->getLocation();
 
if($upright === TRUE) {
$x11 = (int)($x);
$y11 = (int)($y - $this->size / 2);
$x12 = (int)($x);
$y12 = (int)($y + $this->size / 2);
$y21 = (int)($y);
$y22 = (int)($y);
} else {
$x11 = (int)($x - $this->size / 2);
$y11 = (int)($y + $this->size / 2);
$x12 = (int)($x + $this->size / 2);
$y12 = (int)($y - $this->size / 2);
 
$y21 = (int)($y - $this->size / 2);
$y22 = (int)($y + $this->size / 2);
}
$x21 = (int)($x - $this->size / 2);
$x22 = (int)($x + $this->size / 2);
$this->driver->line(
$this->fill,
new awLine(
new awPoint($x11, $y11),
new awPoint($x12, $y12)
)
);
$this->driver->line(
$this->fill,
new awLine(
new awPoint($x21, $y21),
new awPoint($x22, $y22)
)
);
}
 
protected function drawImage(awPoint $point) {
if($this->image instanceof awImage) {
$width = $this->image->width;
$height = $this->image->height;
list($x, $y) = $point->getLocation();
$x1 = (int)($x - $width / 2);
$x2 = $x1 + $width;
$y1 = (int)($y - $width / 2);
$y2 = $y1 + $height;
$this->border->rectangle($this->driver, new awPoint($x1 - 1, $y1 - 1), new awPoint($x2 + 1, $y2 + 1));
$this->driver->copyImage($this->image, new awPoint($x1, $y1), new awPoint($x2, $y2));
}
}
 
}
 
registerClass('Mark');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Tick.class.php
New file
0,0 → 1,344
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
 
/**
* Handle ticks
*
* @package Artichow
*/
class awTick {
 
/**
* Ticks style
*
* @var int
*/
protected $style = awTick::IN;
 
/**
* Ticks size
*
* @var int
*/
protected $size;
 
/**
* Ticks color
*
* @var Color
*/
protected $color;
 
/**
* Ticks number
*
* @var int
*/
protected $number;
 
/**
* Ticks number by other tick
*
* @var array
*/
protected $numberByTick;
 
/**
* Ticks interval
*
* @var int
*/
protected $interval = 1;
 
/**
* Hide ticks
*
* @var bool
*/
protected $hide = FALSE;
 
/**
* Hide first tick
*
* @var bool
*/
protected $hideFirst = FALSE;
 
/**
* Hide last tick
*
* @var bool
*/
protected $hideLast = FALSE;
/**
* In mode
*
* @param int
*/
const IN = 0;
/**
* Out mode
*
* @param int
*/
const OUT = 1;
/**
* In and out mode
*
* @param int
*/
const IN_OUT = 2;
/**
* Build the ticks
*
* @param int $number Number of ticks
* @param int $size Ticks size
*/
public function __construct($number, $size) {
$this->setSize($size);
$this->setNumber($number);
$this->setColor(new awBlack);
$this->style = awTick::IN;
}
/**
* Change ticks style
*
* @param int $style
*/
public function setStyle($style) {
$this->style = (int)$style;
}
/**
* Get ticks style
*
* @return int
*/
public function getStyle() {
return $this->style;
}
/**
* Change ticks color
*
* @param awColor $color
*/
public function setColor(awColor $color) {
$this->color = $color;
}
/**
* Change ticks size
*
* @param int $size
*/
public function setSize($size) {
$this->size = (int)$size;
}
/**
* Change interval of ticks
*
* @param int $interval
*/
public function setInterval($interval) {
$this->interval = (int)$interval;
}
/**
* Get interval between each tick
*
* @return int
*/
public function getInterval() {
return $this->interval;
}
/**
* Change number of ticks
*
* @param int $number
*/
public function setNumber($number) {
$this->number = (int)$number;
}
/**
* Get number of ticks
*
* @return int
*/
public function getNumber() {
return $this->number;
}
/**
* Change number of ticks relative to others ticks
*
* @param awTick $tick Ticks reference
* @param int $number Number of ticks
*/
public function setNumberByTick(awTick $tick, $number) {
$this->numberByTick = array($tick, (int)$number);
}
/**
* Hide ticks
*
* @param bool $hide
*/
public function hide($hide) {
$this->hide = (bool)$hide;
}
/**
* Hide first tick
*
* @param bool $hide
*/
public function hideFirst($hide) {
$this->hideFirst = (bool)$hide;
}
/**
* Hide last tick
*
* @param bool $hide
*/
public function hideLast($hide) {
$this->hideLast = (bool)$hide;
}
/**
* Draw ticks on a vector
*
* @param awDriver $driver A driver
* @param awVector $vector A vector
*/
public function draw(awDriver $driver, awVector $vector) {
if($this->numberByTick !== NULL) {
list($tick, $number) = $this->numberByTick;
$this->number = 1 + ($tick->getNumber() - 1) * ($number + 1);
$this->interval = $tick->getInterval();
}
if($this->number < 2 or $this->hide) {
return;
}
$angle = $vector->getAngle();
// echo "INIT:".$angle."<br>";
switch($this->style) {
case awTick::IN :
$this->drawTicks($driver, $vector, NULL, $angle + M_PI / 2);
break;
case awTick::OUT :
$this->drawTicks($driver, $vector, $angle + 3 * M_PI / 2, NULL);
break;
default :
$this->drawTicks($driver, $vector, $angle + M_PI / 2, $angle + 3 * M_PI / 2);
break;
}
}
protected function drawTicks(awDriver $driver, awVector $vector, $from, $to) {
// Draw last tick
if($this->hideLast === FALSE) {
//echo '<b>';
if(($this->number - 1) % $this->interval === 0) {
$this->drawTick($driver, $vector->p2, $from, $to);
}
//echo '</b>';
}
$number = $this->number - 1;
$size = $vector->getSize();
// Get tick increment in pixels
$inc = $size / $number;
// Check if we must hide the first tick
$start = $this->hideFirst ? $inc : 0;
$stop = $inc * $number;
$position = 0;
for($i = $start; round($i, 6) < $stop; $i += $inc) {
if($position % $this->interval === 0) {
$p = $vector->p1->move(
round($i * cos($vector->getAngle()), 6),
round($i * sin($vector->getAngle() * -1), 6)
);
$this->drawTick($driver, $p, $from, $to);
}
$position++;
}
//echo '<br><br>';
}
protected function drawTick(awDriver $driver, awPoint $p, $from, $to) {
// echo $this->size.':'.$angle.'|<b>'.cos($angle).'</b>/';
// The round avoid some errors in the calcul
// For example, 12.00000008575245 becomes 12
$p1 = $p;
$p2 = $p;
if($from !== NULL) {
$p1 = $p1->move(
round($this->size * cos($from), 6),
round($this->size * sin($from) * -1, 6)
);
}
if($to !== NULL) {
$p2 = $p2->move(
round($this->size * cos($to), 6),
round($this->size * sin($to) * -1, 6)
);
}
//echo $p1->x.':'.$p2->x.'('.$p1->y.':'.$p2->y.')'.'/';
$vector = new awVector(
$p1, $p2
);
$driver->line(
$this->color,
$vector
);
}
 
}
 
registerClass('Tick');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Driver.class.php
New file
0,0 → 1,725
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
require_once dirname(__FILE__)."/../Graph.class.php";
 
/**
* Draw your objects
*
* @package Artichow
*/
abstract class awDriver {
/**
* Image width
*
* @var int
*/
public $imageWidth;
/**
* Image height
*
* @var int
*/
public $imageHeight;
/**
* Driver X position
*
* @var int
*/
public $x;
/**
* Driver Y position
*
* @var int
*/
public $y;
/**
* Use anti-aliasing ?
*
* @var bool
*/
protected $antiAliasing = FALSE;
/**
* The FontDriver object that will be used to draw text
* with PHP fonts.
*
* @var awPHPFontDriver
*/
protected $phpFontDriver;
/**
* The FontDriver object that will be used to draw text
* with TTF or FDB fonts.
*
* @var awFileFontDriver
*/
protected $fileFontDriver;
/**
* A string representing the type of the driver
*
* @var string
*/
protected $driverString;
 
private $w;
private $h;
public function __construct() {
$this->phpFontDriver = new awPHPFontDriver();
$this->fileFontDriver = new awFileFontDriver();
}
 
/**
* Initialize the driver for a particular awImage object
*
* @param awImage $image
*/
abstract public function init(awImage $image);
/**
* Initialize the Driver for a particular FileImage object
*
* @param awFileImage $fileImage The FileImage object to work on
* @param string $file Image filename
*/
abstract public function initFromFile(awFileImage $fileImage, $file);
/**
* Change the image size
*
* @param int $width Image width
* @param int $height Image height
*/
abstract public function setImageSize($width, $height);
/**
* Inform the driver of the position of your image
*
* @param float $x Position on X axis of the center of the component
* @param float $y Position on Y axis of the center of the component
*/
abstract public function setPosition($x, $y);
/**
* Inform the driver of the position of your image
* This method need absolutes values
*
* @param int $x Left-top corner X position
* @param int $y Left-top corner Y position
*/
abstract public function setAbsPosition($x, $y);
/**
* Move the position of the image
*
* @param int $x Add this value to X axis
* @param int $y Add this value to Y axis
*/
abstract public function movePosition($x, $y);
/**
* Inform the driver of the size of your image
* Height and width must be between 0 and 1.
*
* @param int $w Image width
* @param int $h Image height
* @return array Absolute width and height of the image
*/
abstract public function setSize($w, $h);
/**
* Inform the driver of the size of your image
* You can set absolute size with this method.
*
* @param int $w Image width
* @param int $h Image height
*/
abstract public function setAbsSize($w, $h);
/**
* Get the size of the component handled by the driver
*
* @return array Absolute width and height of the component
*/
abstract public function getSize();
/**
* Turn antialiasing on or off
*
* @var bool $bool
*/
abstract public function setAntiAliasing($bool);
/**
* When passed a Color object, returns the corresponding
* color identifier (driver dependant).
*
* @param awColor $color A Color object
* @return int $rgb A color identifier representing the color composed of the given RGB components
*/
abstract public function getColor(awColor $color);
/**
* Draw an image here
*
* @param awImage $image Image
* @param int $p1 Image top-left point
* @param int $p2 Image bottom-right point
*/
abstract public function copyImage(awImage $image, awPoint $p1, awPoint $p2);
/**
* Draw an image here
*
* @param awImage $image Image
* @param int $d1 Destination top-left position
* @param int $d2 Destination bottom-right position
* @param int $s1 Source top-left position
* @param int $s2 Source bottom-right position
* @param bool $resample Resample image ? (default to TRUE)
*/
abstract public function copyResizeImage(awImage $image, awPoint $d1, awPoint $d2, awPoint $s1, awPoint $s2, $resample = TRUE);
/**
* Draw a string
*
* @var awText $text Text to print
* @param awPoint $point Draw the text at this point
* @param int $width Text max width
*/
abstract public function string(awText $text, awPoint $point, $width = NULL);
/**
* Draw a pixel
*
* @param awColor $color Pixel color
* @param awPoint $p
*/
abstract public function point(awColor $color, awPoint $p);
/**
* Draw a colored line
*
* @param awColor $color Line color
* @param awLine $line
* @param int $thickness Line tickness
*/
abstract public function line(awColor $color, awLine $line);
/**
* Draw a color arc
* @param awColor $color Arc color
* @param awPoint $center Point center
* @param int $width Ellipse width
* @param int $height Ellipse height
* @param int $from Start angle
* @param int $to End angle
*/
abstract public function arc(awColor $color, awPoint $center, $width, $height, $from, $to);
/**
* Draw an arc with a background color
*
* @param awColor $color Arc background color
* @param awPoint $center Point center
* @param int $width Ellipse width
* @param int $height Ellipse height
* @param int $from Start angle
* @param int $to End angle
*/
abstract public function filledArc(awColor $color, awPoint $center, $width, $height, $from, $to);
/**
* Draw a colored ellipse
*
* @param awColor $color Ellipse color
* @param awPoint $center Ellipse center
* @param int $width Ellipse width
* @param int $height Ellipse height
*/
abstract public function ellipse(awColor $color, awPoint $center, $width, $height);
/**
* Draw an ellipse with a background
*
* @param mixed $background Background (can be a color or a gradient)
* @param awPoint $center Ellipse center
* @param int $width Ellipse width
* @param int $height Ellipse height
*/
abstract public function filledEllipse($background, awPoint $center, $width, $height);
/**
* Draw a colored rectangle
*
* @param awColor $color Rectangle color
* @param awLine $line Rectangle diagonale
* @param awPoint $p2
*/
abstract public function rectangle(awColor $color, awLine $line);
/**
* Draw a rectangle with a background
*
* @param mixed $background Background (can be a color or a gradient)
* @param awLine $line Rectangle diagonale
*/
abstract public function filledRectangle($background, awLine $line);
/**
* Draw a polygon
*
* @param awColor $color Polygon color
* @param Polygon A polygon
*/
abstract public function polygon(awColor $color, awPolygon $polygon);
/**
* Draw a polygon with a background
*
* @param mixed $background Background (can be a color or a gradient)
* @param Polygon A polygon
*/
abstract public function filledPolygon($background, awPolygon $polygon);
 
/**
* Sends the image, as well as the correct HTTP headers, to the browser
*
* @param awImage $image The Image object to send
*/
abstract public function send(awImage $image);
/**
* Get the image as binary data
*
* @param awImage $image
*/
abstract public function get(awImage $image);
/**
* Return the width of some text
*
* @param awText $text
*/
abstract public function getTextWidth(awText $text);
/**
* Return the height of some text
*
* @param awText $text
*/
abstract public function getTextHeight(awText $text);
/**
* Return the string representing the type of driver
*
* @return string
*/
public function getDriverString() {
return $this->driverString;
}
/**
* Returns whether or not the driver is compatible with the given font type
*
* @param awFont $font
* @return bool
*/
abstract protected function isCompatibleWithFont(awFont $font);
// abstract private function drawImage(awImage $image, $return = FALSE, $header = TRUE);
}
 
registerClass('Driver', TRUE);
 
/**
* Abstract class for font drivers.
* Those are used to do all the grunt work on fonts.
*
* @package Artichow
*/
 
abstract class awFontDriver {
public function __construct() {
}
/**
* Draw the actual text.
*
* @param awDriver $driver The Driver object to draw upon
* @param awText $text The Text object
* @param awPoint $point Where to draw the text
* @param float $width The width of the area containing the text
*/
abstract public function string(awDriver $driver, awText $text, awPoint $point, $width = NULL);
/**
* Calculate the width of a given Text.
*
* @param awText $text The Text object
* @param awDriver $driver The awDriver object used to draw the graph
*/
abstract public function getTextWidth(awText $text, awDriver $driver);
 
/**
* Calculate the height of a given Text.
*
* @param awText $text The Text object
* @param awDriver $driver The awDriver object used to draw the graph
*/
abstract public function getTextHeight(awText $text, awDriver $driver);
}
 
registerClass('FontDriver', TRUE);
 
/**
* Class to handle calculations on PHPFont objects
*
* @package Artichow
*/
class awPHPFontDriver extends awFontDriver {
public function __construct() {
parent::__construct();
}
public function string(awDriver $driver, awText $text, awPoint $point, $width = NULL) {
 
switch ($driver->getDriverString()) {
case 'gd':
$this->gdString($driver, $text, $point, $width);
break;
default:
awImage::drawError('Class PHPFontDriver: Incompatibility between driver and font - You should never see this error message: have you called awDriver::isCompatibleWithFont() properly?');
break;
}
}
/**
* Draw a string onto a GDDriver object
*
* @param awGDDriver $driver The GDDriver to draw the text upon
* @param awText $text The awText object containing the string to draw
* @param awPoint $point Where to draw the text
* @param float $width The width of the text
*/
private function gdString(awGDDriver $driver, awText $text, awPoint $point, $width = NULL) {
$angle = $text->getAngle();
if($angle !== 90 and $angle !== 0) {
awImage::drawError("Class PHPFontDriver: You can only use 0° and 90° angles.");
}
 
if($angle === 90) {
$function = 'imagestringup';
$addAngle = $this->getGDTextHeight($text);
} else {
$function = 'imagestring';
$addAngle = 0;
}
 
$color = $text->getColor();
$rgb = $driver->getColor($color);
 
$textString = $text->getText();
$textString = str_replace("\r", "", $textString);
$textHeight = $this->getGDTextHeight($text);
// Split text if needed
if($width !== NULL) {
 
$characters = floor($width / ($this->getGDTextWidth($text) / strlen($textString)));
 
if($characters > 0) {
$textString = wordwrap($textString, $characters, "\n", TRUE);
}
 
}
$font = $text->getFont();
$lines = explode("\n", $textString);
 
foreach($lines as $i => $line) {
 
// Line position handling
if($angle === 90) {
$addX = $i * $textHeight;
$addY = 0;
} else {
$addX = 0;
$addY = $i * $textHeight;
}
 
$function(
$driver->resource,
$font->font,
$driver->x + $point->x + $addX,
$driver->y + $point->y + $addY + $addAngle,
$line,
$rgb
);
 
}
}
public function getTextWidth(awText $text, awDriver $driver) {
switch ($driver->getDriverString()) {
case 'gd':
return $this->getGDTextWidth($text);
default:
awImage::drawError('Class PHPFontDriver: Cannot get text width - incompatibility between driver and font');
break;
}
}
public function getTextHeight(awText $text, awDriver $driver) {
switch ($driver->getDriverString()) {
case 'gd':
return $this->getGDTextHeight($text);
default:
awImage::drawError('Class PHPFontDriver: Cannot get text height - incompatibility between driver and font');
break;
}
}
/**
* Return the width of a text for a GDDriver
*
* @param awText $text
* @return int $fontWidth
*/
private function getGDTextWidth(awText $text) {
$font = $text->getFont();
if($text->getAngle() === 90) {
$text->setAngle(45);
return $this->getGDTextHeight($text);
} else if($text->getAngle() === 45) {
$text->setAngle(90);
}
 
$fontWidth = imagefontwidth($font->font);
 
if($fontWidth === FALSE) {
awImage::drawError("Class PHPFontDriver: Unable to get font size.");
}
 
return (int)$fontWidth * strlen($text->getText());
}
/**
* Return the height of a text for a GDDriver
*
* @param awText $text
* @return int $fontHeight
*/
private function getGDTextHeight(awText $text) {
$font = $text->getFont();
if($text->getAngle() === 90) {
$text->setAngle(45);
return $this->getGDTextWidth($text);
} else if($text->getAngle() === 45) {
$text->setAngle(90);
}
 
$fontHeight = imagefontheight($font->font);
 
if($fontHeight === FALSE) {
awImage::drawError("Class PHPFontDriver: Unable to get font size.");
}
 
return (int)$fontHeight;
}
}
 
registerClass('PHPFontDriver');
 
/**
* Class to handle calculations on FileFont objects
*
* @package Artichow
*/
class awFileFontDriver extends awFontDriver {
public function __construct() {
parent::__construct();
}
public function string(awDriver $driver, awText $text, awPoint $point, $width = NULL) {
switch ($driver->getDriverString()) {
case 'gd':
$this->gdString($driver, $text, $point, $width);
break;
default:
awImage::drawError('Class fileFontDriver: Incompatibility between driver and font - You should never see this error message: have you called awDriver::isCompatibleWithFont() properly?');
break;
}
}
/**
* Draw an awFileFont object on a GD ressource
*
* @param awGDDriver $driver The awGDDriver object containing the ressource to draw upon
* @param awText $text The awText object containing the string to draw
* @param awPoint $point Where to draw the string from
* @param float $width The width of the area containing the text
*/
private function gdString(awGDDriver $driver, awText $text, awPoint $point, $width = NULL) {
// Make easier font positionment
$text->setText($text->getText()." ");
 
$font = $text->getFont();
if($font instanceof awTTFFont === FALSE and $font->getExtension() === NULL) {
$font->setExtension('ttf');
}
$filePath = $font->getName().'.'.$font->getExtension();
 
$box = imagettfbbox($font->getSize(), $text->getAngle(), $filePath, $text->getText());
$textHeight = - $box[5];
 
$box = imagettfbbox($font->getSize(), 90, $filePath, $text->getText());
$textWidth = abs($box[6] - $box[2]);
 
// Restore old text
$text->setText(substr($text->getText(), 0, strlen($text->getText()) - 1));
 
$textString = $text->getText();
 
// Split text if needed
if($width !== NULL) {
 
$characters = floor($width / $this->getGDAverageWidth($font));
$textString = wordwrap($textString, $characters, "\n", TRUE);
 
}
$color = $text->getColor();
$rgb = $driver->getColor($color);
imagettftext(
$driver->resource,
$font->getSize(),
$text->getAngle(),
$driver->x + $point->x + $textWidth * sin($text->getAngle() / 180 * M_PI),
$driver->y + $point->y + $textHeight,
$rgb,
$filePath,
$textString
);
}
public function getTextWidth(awText $text, awDriver $driver) {
switch ($driver->getDriverString()) {
case 'gd':
return $this->getGDTextWidth($text);
default:
awImage::drawError('Class FileFontDriver: Cannot get text width - incompatibility between driver and font');
break;
}
}
public function getTextHeight(awText $text, awDriver $driver) {
switch ($driver->getDriverString()) {
case 'gd':
return $this->getGDTextHeight($text);
default:
awImage::drawError('Class FileFontDriver: Cannot get text height - incompatibility between driver and font');
break;
}
}
private function getGDTextWidth(awText $text) {
$font = $text->getFont();
if($font->getExtension() === NULL) {
$font->setExtension('ttf');
}
$filePath = $font->getName().'.'.$font->getExtension();
$box = imagettfbbox($font->getSize(), $text->getAngle(), $filePath, $text->getText());
 
if($box === FALSE) {
awImage::drawError("Class FileFontDriver: Unable to get font width (GD).");
}
 
list(, , $x2, , , , $x1, ) = $box;
 
return abs($x2 - $x1);
}
private function getGDTextHeight(awText $text) {
$font = $text->getFont();
if($font->getExtension() === NULL) {
$font->setExtension('ttf');
}
$filePath = $font->getName().'.'.$font->getExtension();
$box = imagettfbbox($font->getSize(), $text->getAngle(), $filePath, $text->getText());
 
if($box === FALSE) {
awImage::drawError("Class FileFontDriver: Unable to get font height (GD).");
}
 
list(, , , $y2, , , , $y1) = $box;
 
return abs($y2 - $y1);
}
private function getGDAverageWidth(awFileFont $font) {
 
$text = "azertyuiopqsdfghjklmmmmmmmwxcvbbbn,;:!?.";
 
$box = imagettfbbox($font->getSize(), 0, $font->getName().'.'.$font->getExtension(), $text);
 
if($box === FALSE) {
awImage::drawError("Class FileFontDriver: Unable to get font average width.");
}
 
list(, , $x2, $y2, , , $x1, $y1) = $box;
 
return abs($x2 - $x1) / strlen($text);
 
}
}
 
registerClass('FileFontDriver');
 
// Include ARTICHOW_DRIVER by default to preserve backward compatibility.
require_once dirname(__FILE__).'/drivers/'.ARTICHOW_DRIVER.'.class.php';
 
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Gradient.class.php
New file
0,0 → 1,135
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/../Graph.class.php";
 
 
/**
* Create your gradients
*
* @package Artichow
*/
abstract class awGradient {
 
/**
* From color
*
* @var Color
*/
public $from;
 
/**
* To color
*
* @var Color
*/
public $to;
/**
* Build the gradient
*
* @param awColor $from From color
* @param awColor $to To color
*/
public function __construct(awColor $from, awColor $to) {
$this->from = $from;
$this->to = $to;
}
 
}
 
registerClass('Gradient', TRUE);
 
 
/**
* Create a linear gradient
*
* @package Artichow
*/
class awLinearGradient extends awGradient {
 
/**
* Gradient angle
*
* @var int
*/
public $angle;
/**
* Build the linear gradient
*
* @param awColor $from From color
* @param awColor $to To color
* @param int $angle Gradient angle
*/
public function __construct($from, $to, $angle) {
parent::__construct(
$from, $to
);
$this->angle = (int)$angle;
}
 
}
 
registerClass('LinearGradient');
 
 
/**
* Create a bilinear gradient
*
* @package Artichow
*/
class awBilinearGradient extends awLinearGradient {
 
/**
* Gradient center
*
* @var float Center between 0 and 1
*/
public $center;
/**
* Build the bilinear gradient
*
* @param awColor $from From color
* @param awColor $to To color
* @param int $angle Gradient angle
* @param int $center Gradient center
*/
public function __construct($from, $to, $angle, $center = 0.5) {
parent::__construct(
$from, $to, $angle
);
$this->center = (float)$center;
}
 
}
 
registerClass('BilinearGradient');
 
/**
* Create a radial gradient
*
* @package Artichow
*/
class awRadialGradient extends awGradient {
 
}
 
registerClass('RadialGradient');
?>
/tags/v1.0-Homere/bibliotheque/artichow/inc/Legend.class.php
New file
0,0 → 1,710
<?php
/*
* This work is hereby released into the Public Domain.
* To view a copy of the public domain dedication,
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
 
require_once dirname(__FILE__)."/../Graph.class.php";
 
/**
* Some legends
*
* @package Artichow
*/
class awLegend implements awPositionable {
 
/**
* Legends added
*
* @var array
*/
protected $legends = array();
 
/**
* The current component
*
* @var Component
*/
protected $component;
/**
* Background color or gradient
*
* @var Color, Gradient
*/
protected $background;
/**
* Text color
*
* @var Color
*/
protected $textColor;
/**
* Text font
*
* @var Font
*/
protected $textFont;
/**
* Text margin
*
* @var Side
*/
protected $textMargin;
/**
* Number of columns
*
* @var int
*/
protected $columns = NULL;
/**
* Number of rows
*
* @var int
*/
protected $rows = NULL;
/**
* Legend position
*
* @var Point
*/
protected $position;
/**
* Hide legend ?
*
* @var bool
*/
protected $hide = FALSE;
/**
* Space between each legend
*
* @var int
*/
protected $space = 4;
/**
* Horizontal alignment
*
* @var int
*/
protected $hAlign;
/**
* Vertical alignment
*
* @var int
*/
protected $vAlign;
 
/**
* Margin
*
* @var array Array for left, right, top and bottom margins
*/
private $margin;
/**
* Legend shadow
*
* @var Shadow
*/
public $shadow;
/**
* Legend border
*
* @var Border
*/
public $border;
/**
* Line legend
*
* @var int
*/
const LINE = 1;
/**
* Color/Gradient background legend
*
* @var int
*/
const BACKGROUND = 2;
/**
* Use marks and line as legend
*
* @var int
*/
const MARK = 3;
/**
* Use marks as legend
*
* @var int
*/
const MARKONLY = 4;
/**
* Right side model
*
* @var int
*/
const MODEL_RIGHT = 1;
/**
* Bottom side model
*
* @var int
*/
const MODEL_BOTTOM = 2;
 
/**
* Build the legend
*
* @param int $model Legend model
*/
public function __construct($model = awLegend::MODEL_RIGHT) {
$this->shadow = new awShadow(awShadow::LEFT_BOTTOM);
$this->border = new awBorder;
$this->textMargin = new awSide(4);
$this->setModel($model);
}
/**
* Set a predefined model for the legend
*
* @param int $model
*/
public function setModel($model) {
$this->setBackgroundColor(new awColor(255, 255, 255, 15));
$this->setPadding(8, 8, 8, 8);
$this->setTextFont(new awFont2);
$this->shadow->setSize(3);
switch($model) {
case awLegend::MODEL_RIGHT :
$this->setColumns(1);
$this->setAlign(awLegend::RIGHT, awLegend::MIDDLE);
$this->setPosition(0.96, 0.50);
break;
case awLegend::MODEL_BOTTOM :
$this->setRows(1);
$this->setAlign(awLegend::CENTER, awLegend::TOP);
$this->setPosition(0.50, 0.92);
break;
default :
$this->setPosition(0.5, 0.5);
break;
}
}
/**
* Hide legend ?
*
* @param bool $hide TRUE to hide legend, FALSE otherwise
*/
public function hide($hide = TRUE) {
$this->hide = (bool)$hide;
}
/**
* Show legend ?
*
* @param bool $show
*/
public function show($show = TRUE) {
$this->hide = (bool)!$show;
}
/**
* Add a Legendable object to the legend
*
* @param awLegendable $legendable
* @param string $title Legend title
* @param int $type Legend type (default to awLegend::LINE)
*/
public function add(awLegendable $legendable, $title, $type = awLegend::LINE) {
$legend = array($legendable, $title, $type);
$this->legends[] = $legend;
}
/**
* Change legend padding
*
* @param int $left
* @param int $right
* @param int $top
* @param int $bottom
*/
public function setPadding($left, $right, $top, $bottom) {
$this->padding = array((int)$left, (int)$right, (int)$top, (int)$bottom);
}
/**
* Change space between each legend
*
* @param int $space
*/
public function setSpace($space) {
$this->space = (int)$space;
}
/**
* Change alignment
*
* @param int $h Horizontal alignment
* @param int $v Vertical alignment
*/
public function setAlign($h = NULL, $v = NULL) {
if($h !== NULL) {
$this->hAlign = (int)$h;
}
if($v !== NULL) {
$this->vAlign = (int)$v;
}
}
/**
* Change number of columns
*
* @param int $columns
*/
public function setColumns($columns) {
$this->rows = NULL;
$this->columns = (int)$columns;
}
/**
* Change number of rows
*
* @param int $rows
*/
public function setRows($rows) {
$this->columns = NULL;
$this->rows = (int)$rows;
}
/**
* Change legend position
* X and Y positions must be between 0 and 1.
*
* @param float $x
* @param float $y
*/
public function setPosition($x = NULL, $y = NULL) {
$x = (is_null($x) and !is_null($this->position)) ? $this->position->x : $x;
$y = (is_null($y) and !is_null($this->position)) ? $this->position->y : $y;
$this->position = new awPoint($x, $y);
}
/**
* Get legend position
*
* @return Point
*/
public function getPosition() {
return $this->position;
}
/**
* Change text font
*
* @param awFont $font
*/
public function setTextFont(awFont $font) {
$this->textFont = $font;
}
/**
* Change text margin
*
* @param int $left
* @param int $right
*/
public function setTextMargin($left, $right) {
$this->textMargin->set($left, $right);
}
/**
* Change text color
*
* @param awColor $color
*/
public function setTextColor(awColor $color) {
$this->textColor = $color;
}
/**
* Change background
*
* @param mixed $background
*/
public function setBackground($background) {
$this->background = $background;
}
/**
* Change background color
*
* @param awColor $color
*/
public function setBackgroundColor(awColor $color) {
$this->background = $color;
}
/**
* Change background gradient
*
* @param awGradient $gradient
*/
public function setBackgroundGradient(awGradient $gradient) {
$this->background = $gradient;
}
/**
* Count the number of Legendable objects in the legend
*
* @return int
*/
public function count() {
return count($this->legends);
}
public function draw(awDriver $driver) {
if($this->hide) {
return;
}
$count = $this->count();
// No legend to print
if($count === 0) {
return;
}
// Get text widths and heights of each element of the legend
$widths = array();
$heights = array();
$texts = array();
for($i = 0; $i < $count; $i++) {
list(, $title, ) = $this->legends[$i];
$text = new awText(
$title,
$this->textFont,
$this->textColor,
0
);
// $font = $text->getFont();
$widths[$i] = $driver->getTextWidth($text) + $this->textMargin->left + $this->textMargin->right;
$heights[$i] = $driver->getTextHeight($text);
$texts[$i] = $text;
}
// Maximum height of the font used
$heightMax = array_max($heights);
// Get number of columns
if($this->columns !== NULL) {
$columns = $this->columns;
} else if($this->rows !== NULL) {
$columns = ceil($count / $this->rows);
} else {
$columns = $count;
}
// Number of rows
$rows = (int)ceil($count / $columns);
// Get maximum with of each column
$widthMax = array();
for($i = 0; $i < $count; $i++) {
// Get column width
$column = $i % $columns;
if(array_key_exists($column, $widthMax) === FALSE) {
$widthMax[$column] = $widths[$i];
} else {
$widthMax[$column] = max($widthMax[$column], $widths[$i]);
}
}
$width = $this->padding[0] + $this->padding[1] - $this->space;
for($i = 0; $i < $columns; $i++) {
$width += $this->space + 5 + 10 + $widthMax[$i];
}
$height = ($heightMax + $this->space) * $rows - $this->space + $this->padding[2] + $this->padding[3];
// Look for legends position
list($x, $y) = $driver->getSize();
$p = new awPoint(
$this->position->x * $x,
$this->position->y * $y
);
switch($this->hAlign) {
case awLegend::CENTER :
$p->x -= $width / 2;
break;
case awLegend::RIGHT :
$p->x -= $width;
break;
}
switch($this->vAlign) {
case awLegend::MIDDLE :
$p->y -= $height / 2;
break;
case awLegend::BOTTOM :
$p->y -= $height;
break;
}
// Draw legend shadow
$this->shadow->draw(
$driver,
$p,
$p->move($width, $height),
awShadow::OUT
);
// Draw legends base
$this->drawBase($driver, $p, $width, $height);
// Draw each legend
for($i = 0; $i < $count; $i++) {
list($component, $title, $type) = $this->legends[$i];
$column = $i % $columns;
$row = (int)floor($i / $columns);
// Get width of all previous columns
$previousColumns = 0;
for($j = 0; $j < $column; $j++) {
$previousColumns += $this->space + 10 + 5 + $widthMax[$j];
}
// Draw legend text
$driver->string(
$texts[$i],
$p->move(
$this->padding[0] + $previousColumns + 10 + 5 + $this->textMargin->left,
$this->padding[2] + $row * ($heightMax + $this->space) + $heightMax / 2 - $heights[$i] / 2
)
);
// Draw legend icon
switch($type) {
case awLegend::LINE :
case awLegend::MARK :
case awLegend::MARKONLY :
// Get vertical position
$x = $this->padding[0] + $previousColumns;
$y = $this->padding[2] + $row * ($heightMax + $this->space) + $heightMax / 2 - $component->getLegendLineThickness();
// Draw two lines
if($component->getLegendLineColor() !== NULL) {
$color = $component->getLegendLineColor();
if($color instanceof awColor and $type !== awLegend::MARKONLY) {
$driver->line(
$color,
new awLine(
$p->move(
$x, // YaPB ??
$y + $component->getLegendLineThickness() / 2
),
$p->move(
$x + 10,
$y + $component->getLegendLineThickness() / 2
),
$component->getLegendLineStyle(),
$component->getLegendLineThickness()
)
);
unset($color);
}
}
if($type === awLegend::MARK or $type === awLegend::MARKONLY) {
$mark = $component->getLegendMark();
if($mark !== NULL) {
$mark->draw(
$driver,
$p->move(
$x + 5.5,
$y + $component->getLegendLineThickness() / 2
)
);
}
unset($mark);
}
break;
case awLegend::BACKGROUND :
// Get vertical position
$x = $this->padding[0] + $previousColumns;
$y = $this->padding[2] + $row * ($heightMax + $this->space) + $heightMax / 2 - 5;
$from = $p->move(
$x,
$y
);
$to = $p->move(
$x + 10,
$y + 10
);
$background = $component->getLegendBackground();
if($background !== NULL) {
$driver->filledRectangle(
$component->getLegendBackground(),
new awLine($from, $to)
);
// Draw rectangle border
$this->border->rectangle(
$driver,
$from->move(0, 0),
$to->move(0, 0)
);
}
unset($background, $from, $to);
break;
}
}
}
private function drawBase(awDriver $driver, awPoint $p, $width, $height) {
 
$this->border->rectangle(
$driver,
$p,
$p->move($width, $height)
);
$size = $this->border->visible() ? 1 : 0;
$driver->filledRectangle(
$this->background,
new awLine(
$p->move($size, $size),
$p->move($width - $size, $height - $size)
)
);
}
 
}
 
registerClass('Legend');
 
/**
* You can add a legend to components which implements this interface
*
* @package Artichow
*/
interface awLegendable {
 
/**
* Get the line type
*
* @return int
*/
public function getLegendLineStyle();
 
/**
* Get the line thickness
*
* @return int
*/
public function getLegendLineThickness();
 
/**
* Get the color of line
*
* @return Color
*/
public function getLegendLineColor();
 
/**
* Get the background color or gradient of an element of the component
*
* @return Color, Gradient
*/
public function getLegendBackground();
 
/**
* Get a Mark object
*
* @return Mark
*/
public function getLegendMark();
 
}
 
registerInterface('Legendable');
?>
/tags/v1.0-Homere/bibliotheque/metier/NoteFraisLigne.class.php
New file
0,0 → 1,174
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe NoteFraisLigne
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class NoteFraisLigne : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class NoteFraisLigne extends aGttSql {
/*** Constantes : */
const GNFL_ID = 'NOTEFRAISLIGNE_ID';
const GNFL_ID_MAX = 'NOTEFRAISLIGNE_ID_MAX';
 
/*** Attributs : */
private $id_note_frais_ligne;
private $ce_note_frais;
private $date;
private $montant_ht;
private $taux_tva;
private $montant_ttc;
 
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_note_frais_ligne';
$this->dao_correspondance = array(
'gnfl_id_note_frais_ligne' => 'id_note_frais_ligne',
'gnfl_ce_note_frais' => 'ce_note_frais',
'gnfl_date' => 'date',
'gnfl_montant_ht' => 'montant_ht',
'gnfl_taux_tva' => 'taux_tva',
'gnfl_montant_ttc' => 'montant_ttc');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Note Frais Ligne
public function getIdNoteFraisLigne()
{
return $this->id_note_frais_ligne;
}
public function setIdNoteFraisLigne( $infl )
{
$this->id_note_frais_ligne = $infl;
}
 
// Ce Note Frais
public function getCeNoteFrais()
{
return $this->ce_note_frais;
}
public function setCeNoteFrais( $cnf )
{
$this->ce_note_frais = $cnf;
}
 
// Date
public function getDate()
{
return $this->date;
}
public function setDate( $d )
{
$this->date = $d;
}
 
// Montant Ht
public function getMontantHt()
{
return $this->montant_ht;
}
public function setMontantHt( $mh )
{
$this->montant_ht = $mh;
}
 
// Taux Tva
public function getTauxTva()
{
return $this->taux_tva;
}
public function setTauxTva( $tt )
{
$this->taux_tva = $tt;
}
 
// Montant Ttc
public function getMontantTtc()
{
return $this->montant_ttc;
}
public function setMontantTtc( $mt )
{
$this->montant_ttc = $mt;
}
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_note_frais_ligne.
* @return mixed un tableau d'objets NoteFraisLigne s'il y en a plusieurs, l'objet NoteFraisLigne s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case NoteFraisLigne::GNFL_ID:
$requete = 'SELECT * '.
'FROM gestion_note_frais_ligne '.
'WHERE gnfl_id_note_frais_ligne = #0 ';
break;
case NoteFraisLigne::GNFL_ID_MAX:
$requete = 'SELECT MAX(gnfl_id_note_frais_ligne) '.
'FROM gestion_note_frais_ligne ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/NoteFrais.class.php
New file
0,0 → 1,138
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe NoteFrais
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class NoteFrais : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class NoteFrais extends aGttSql {
/*** Constantes : */
const GNF_ID = 'NOTEFRAIS_ID';
const GNF_ID_MAX = 'NOTEFRAIS_ID_MAX';
 
/*** Attributs : */
private $id_note_frais;
private $ce_utilisateur;
private $libelle;
 
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_note_frais';
$this->dao_correspondance = array(
'gnf_id_note_frais' => 'id_note_frais',
'gnf_ce_utilisateur' => 'ce_utilisateur',
'gnf_libelle' => 'libelle');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Note Frais
public function getIdNoteFrais()
{
return $this->id_note_frais;
}
public function setIdNoteFrais( $inf )
{
$this->id_note_frais = $inf;
}
 
// Ce Utilisateur
public function getCeUtilisateur()
{
return $this->ce_utilisateur;
}
public function setCeUtilisateur( $cu )
{
$this->ce_utilisateur = $cu;
}
 
// Libelle
public function getLibelle()
{
return $this->libelle;
}
public function setLibelle( $l )
{
$this->libelle = $l;
}
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_note_frais.
* @return mixed un tableau d'objets NoteFrais s'il y en a plusieurs, l'objet NoteFrais s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case NoteFrais::GNF_ID:
$requete = 'SELECT * '.
'FROM gestion_note_frais '.
'WHERE gnf_id_note_frais = #0 ';
break;
case NoteFrais::GNF_ID_MAX:
$requete = 'SELECT MAX(gnf_id_note_frais) '.
'FROM gestion_note_frais ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/Utilisateur.class.php
New file
0,0 → 1,471
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe Utilisateur
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class Utilisateur : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class Utilisateur extends aGttSql {
/*** Constantes : */
const GU_TOUS = 'UTILISATEUR_TOUS';
const GU_ID = 'UTILISATEUR_ID';
const GU_ID_MAX = 'UTILISATEUR_ID_MAX';
const GU_CE_STATUT = 'UTILISATEUR_CE_STATUT';
const GU_MAIL = 'UTILISATEUR_MAIL';
const GU_TOUS_AFFICHABLE = 'UTILISATEUR_TOUS_AFFICHABLE';
const GU_ADMIN = 'UTILISATEUR_ADMIN';
 
/*** Attributs : */
private $id_utilisateur;
private $ce_statut = 0;
private $nom;
private $prenom;
private $password;
private $email;
private $telephone;
private $adresse;
private $code_postal;
private $ville;
private $quota_heures_supp = 0;
private $conges_payes = 0;
private $temps_de_travail_jour = 7;
private $temps_de_travail_mois = 0;
private $tdt_lundi = 0;
private $tdt_mardi = 0;
private $tdt_mercredi = 0;
private $tdt_jeudi = 0;
private $tdt_vendredi = 0;
private $tdt_samedi = 0;
private $tdt_dimanche = 0;
private $mark_admin = 0;
private $mark_recapitulatif = 1;
private $notes;
 
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_utilisateur';
$this->dao_correspondance = array(
'gu_id_utilisateur' => 'id_utilisateur',
'gu_ce_statut' => 'ce_statut',
'gu_nom' => 'nom',
'gu_prenom' => 'prenom',
'gu_password' => 'password',
'gu_email' => 'email',
'gu_telephone' => 'telephone',
'gu_adresse' => 'adresse',
'gu_code_postal' => 'code_postal',
'gu_ville' => 'ville',
'gu_quota_heures_supp' => 'quota_heures_supp',
'gu_conges_payes' => 'conges_payes',
'gu_temps_de_travail_jour' => 'temps_de_travail_jour',
'gu_temps_de_travail_mois' => 'temps_de_travail_mois',
'gu_tdt_lundi' => 'tdt_lundi',
'gu_tdt_mardi' => 'tdt_mardi',
'gu_tdt_mercredi' => 'tdt_mercredi',
'gu_tdt_jeudi' => 'tdt_jeudi',
'gu_tdt_vendredi' => 'tdt_vendredi',
'gu_tdt_samedi' => 'tdt_samedi',
'gu_tdt_dimanche' => 'tdt_dimanche',
'gu_mark_admin' => 'mark_admin',
'gu_mark_recapitulatif' => 'mark_recapitulatif',
'gu_notes' => 'notes');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Utilisateur
public function getIdUtilisateur()
{
return $this->id_utilisateur;
}
public function setIdUtilisateur( $iu )
{
$this->id_utilisateur = $iu;
}
 
// Gus Id Utilisateur Statut
public function getCeStatut()
{
return $this->ce_statut;
}
public function setCeStatut( $cs )
{
$this->ce_statut = $cs;
}
 
// Nom
public function getNom()
{
return $this->nom;
}
public function setNom( $n )
{
if (!is_null($n)) {
$this->nom = strtoupper($n);
} else {
$this->nom = $n;
}
}
 
// Prenom
public function getPrenom()
{
return $this->prenom;
}
public function setPrenom( $p )
{
$this->prenom = $p;
}
 
// Password
public function getPassword()
{
return $this->password;
}
public function setPassword( $p )
{
if (!is_null($p)) {
$this->password = md5($p);
} else {
$this->password = $p;
}
}
 
// Email
public function getEmail()
{
return $this->email;
}
public function setEmail( $e )
{
$this->email = $e;
}
 
// Telephone
public function getTelephone()
{
return $this->telephone;
}
public function setTelephone( $t )
{
$this->telephone = (string) $t;
}
 
// Adresse
public function getAdresse()
{
return $this->adresse;
}
public function setAdresse( $a )
{
$this->adresse = $a;
}
 
// Code Postal
public function getCodePostal()
{
return $this->code_postal;
}
public function setCodePostal( $cp )
{
$this->code_postal = $cp;
}
 
// Ville
public function getVille()
{
return $this->ville;
}
public function setVille( $v )
{
$this->ville = $v;
}
 
// Quota Heures Supp
public function getQuotaHeuresSupp()
{
return $this->quota_heures_supp;
}
public function setQuotaHeuresSupp( $qhs )
{
$this->quota_heures_supp = $qhs;
}
 
// Conges Payes
public function getCongesPayes()
{
return $this->conges_payes;
}
public function setCongesPayes( $cp )
{
$this->conges_payes = $cp;
}
 
// Temps De Travail Jour
public function getTempsDeTravailJour()
{
return $this->temps_de_travail_jour;
}
public function setTempsDeTravailJour( $tdt )
{
$this->temps_de_travail_jour = $tdt;
}
 
// Temps De Travail Mois
public function getTempsDeTravailMois()
{
return $this->temps_de_travail_mois;
}
public function setTempsDeTravailMois( $tdt )
{
$this->temps_de_travail_mois = $tdt;
}
 
// Tdt Lundi
public function getTdtLundi()
{
return $this->tdt_lundi;
}
public function setTdtLundi( $tdt )
{
$this->tdt_lundi = $tdt;
}
 
// Tdt Mardi
public function getTdtMardi()
{
return $this->tdt_mardi;
}
public function setTdtMardi( $tdt )
{
$this->tdt_mardi = $tdt;
}
// Tdt Mercredi
public function getTdtMercredi()
{
return $this->tdt_mercredi;
}
public function setTdtMercredi( $tdt )
{
$this->tdt_mercredi = $tdt;
}
// Tdt Jeudi
public function getTdtJeudi()
{
return $this->tdt_jeudi;
}
public function setTdtJeudi( $tdt )
{
$this->tdt_jeudi = $tdt;
}
 
// Tdt Vendredi
public function getTdtVendredi()
{
return $this->tdt_vendredi;
}
public function setTdtVendredi( $tdt )
{
$this->tdt_vendredi = $tdt;
}
// Tdt Samedi
public function getTdtSamedi()
{
return $this->tdt_samedi;
}
public function setTdtSamedi( $tdt )
{
$this->tdt_samedi = $tdt;
}
 
// Tdt Dimanche
public function getTdtDimanche()
{
return $this->tdt_dimanche;
}
public function setTdtDimanche( $tdt )
{
$this->tdt_dimanche = $tdt;
}
 
// Mark Admin
public function getMarkAdmin()
{
return $this->mark_admin;
}
public function setMarkAdmin( $ma )
{
$this->mark_admin = $ma;
}
 
// Mark Recapitulatif
public function getMarkRecapitulatif()
{
return $this->mark_recapitulatif;
}
public function setMarkRecapitulatif( $mr )
{
$this->mark_recapitulatif = $mr;
}
 
// Notes
public function getNotes()
{
return $this->notes;
}
public function setNotes( $n )
{
$this->notes = $n;
}
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_utilisateur.
* @return mixed un tableau d'objets Utilisateur s'il y en a plusieurs, l'objet Utilisateur s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case Utilisateur::GU_TOUS:
$requete = 'SELECT * '.
'FROM gestion_utilisateur '.
'ORDER BY gu_nom, gu_prenom ASC';
break;
case Utilisateur::GU_ID:
$requete = 'SELECT * '.
'FROM gestion_utilisateur '.
'WHERE gu_id_utilisateur = #0 ';
break;
case Utilisateur::GU_ID_MAX:
$requete = 'SELECT MAX(gu_id_utilisateur) AS gu_id_utilisateur '.
'FROM gestion_utilisateur ';
break;
case Utilisateur::GU_CE_STATUT:
$requete = 'SELECT * '.
'FROM gestion_utilisateur '.
'WHERE gu_ce_statut = "#0" ';
break;
case Utilisateur::GU_MAIL:
$requete = 'SELECT * '.
'FROM gestion_utilisateur '.
'WHERE gu_email = "#0" ';
break;
case Utilisateur::GU_TOUS_AFFICHABLE:
$requete = 'SELECT * '.
'FROM gestion_utilisateur '.
'WHERE gu_mark_recapitulatif = 0 '.
'ORDER BY gu_nom, gu_prenom ASC';
break;
case Utilisateur::GU_ADMIN:
$requete = 'SELECT * '.
'FROM gestion_utilisateur '.
'WHERE gu_mark_admin = 1 ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
 
public function supprimer()
{
$requete = 'DELETE FROM gestion_utilisateur '.
'WHERE gu_id_utilisateur = '.$this->getIdUtilisateur();
$resultat = $GLOBALS['db']->query($requete);
(DB::isError($resultat)) ? die (GestionnaireErreur::retournerErreurSql(__FILE__, __LINE__, $resultat->getMessage(), $requete)) : '' ;
 
if ($GLOBALS['db']->affectedRows() == 1) {
return true;
} elseif ($GLOBALS['db']->affectedRows() == 0) {
return false;
}
}
 
/**augmenter le nombre d'heure sup
*un acces est fait a la bse de donnees pour enregistrer les changements en temps reel
*/
public function augmenterQuotaHeuresSup($nb)
{
$this->quota_heures_supp = $this->quota_heures_supp + abs($nb);
}
 
/**diminuer le nb d'heures sup*/
public function diminuerQuotaHeuresSup($nb)
{
$this->quota_heures_supp = $this->quota_heures_supp - abs($nb);
/*un quota heure supp negatif implique qu'il y a des heures a rattraper*/
}
 
/**augmenter le nombre de jours de conges */
public function augmenterCongesPayes($nb)
{
$this->conges_payes = $this->conges_payes + abs($nb);
}
 
/**diminuer le nombre de jour de conges */
public function diminuerCongesPayes($nb)
{
$this->conges_payes = $this->conges_payes - abs($nb);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/FraisKm.class.php
New file
0,0 → 1,198
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe FraisKm
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class FraisKm : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class FraisKm extends aGttSql {
/*** Constantes : */
const GFK_ID = 'FRAISKM_ID';
const GFK_ID_MAX = 'FRAISKM_ID_MAX';
 
/*** Attributs : */
private $id_frais_km;
private $gfkt_id_frais_km_taux;
private $ce_utilisateur;
private $date;
private $nbre_km;
private $objet;
private $trajet;
private $montant_total;
 
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_frais_km';
$this->dao_correspondance = array(
'gfk_id_frais_km' => 'id_frais_km',
'gfkt_id_frais_km_taux' => 'gfkt_id_frais_km_taux',
'gfk_ce_utilisateur' => 'ce_utilisateur',
'gfk_date' => 'date',
'gfk_nbre_km' => 'nbre_km',
'gfk_objet' => 'objet',
'gfk_trajet' => 'trajet',
'gfk_montant_total' => 'montant_total');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Frais Km
public function getIdFraisKm()
{
return $this->id_frais_km;
}
public function setIdFraisKm( $ifk )
{
$this->id_frais_km = $ifk;
}
 
// Gfkt Id Frais Km Taux
public function getGfktIdFraisKmTaux()
{
return $this->gfkt_id_frais_km_taux;
}
public function setGfktIdFraisKmTaux( $gifkt )
{
$this->gfkt_id_frais_km_taux = $gifkt;
}
 
// Ce Utilisateur
public function getCeUtilisateur()
{
return $this->ce_utilisateur;
}
public function setCeUtilisateur( $cu )
{
$this->ce_utilisateur = $cu;
}
 
// Date
public function getDate()
{
return $this->date;
}
public function setDate( $d )
{
$this->date = $d;
}
 
// Nbre Km
public function getNbreKm()
{
return $this->nbre_km;
}
public function setNbreKm( $nk )
{
$this->nbre_km = $nk;
}
 
// Objet
public function getObjet()
{
return $this->objet;
}
public function setObjet( $o )
{
$this->objet = $o;
}
 
// Trajet
public function getTrajet()
{
return $this->trajet;
}
public function setTrajet( $t )
{
$this->trajet = $t;
}
 
// Montant Total
public function getMontantTotal()
{
return $this->montant_total;
}
public function setMontantTotal( $mt )
{
$this->montant_total = $mt;
}
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_frais_km.
* @return mixed un tableau d'objets FraisKm s'il y en a plusieurs, l'objet FraisKm s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case FraisKm::GFK_ID:
$requete = 'SELECT * '.
'FROM gestion_frais_km '.
'WHERE gfk_id_frais_km = #0 ';
break;
case FraisKm::GFK_ID_MAX:
$requete = 'SELECT MAX(gfk_id_frais_km) '.
'FROM gestion_frais_km ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/FraisKmTaux.class.php
New file
0,0 → 1,126
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe FraisKmTaux
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class FraisKmTaux : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class FraisKmTaux extends aGttSql {
/*** Constantes : */
const GFKT_ID = 'FRAISKMTAUX_ID';
const GFKT_ID_MAX = 'FRAISKMTAUX_ID_MAX';
 
/*** Attributs : */
private $id_frais_km_taux;
private $taux;
 
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_frais_km_taux';
$this->dao_correspondance = array(
'gfkt_id_frais_km_taux' => 'id_frais_km_taux',
'gfkt_taux' => 'taux');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Frais Km Taux
public function getIdFraisKmTaux()
{
return $this->id_frais_km_taux;
}
public function setIdFraisKmTaux( $ifkt )
{
$this->id_frais_km_taux = $ifkt;
}
 
// Taux
public function getTaux()
{
return $this->taux;
}
public function setTaux( $t )
{
$this->taux = $t;
}
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_frais_km_taux.
* @return mixed un tableau d'objets FraisKmTaux s'il y en a plusieurs, l'objet FraisKmTaux s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case FraisKmTaux::GFKT_ID:
$requete = 'SELECT * '.
'FROM gestion_frais_km_taux '.
'WHERE gfkt_id_frais_km_taux = #0 ';
break;
case FraisKmTaux::GFKT_ID_MAX:
$requete = 'SELECT MAX(gfkt_id_frais_km_taux) '.
'FROM gestion_frais_km_taux ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/AbsenceMotif.class.php
New file
0,0 → 1,161
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe AbsenceMotif
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class AbsenceMotif : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class AbsenceMotif extends aGttSql {
/*** Constantes : */
const GAM_TOUS = 'ABSENCEMOTIF_TOUS';
const GAM_ID = 'ABSENCEMOTIF_ID';
const GAM_ID_MAX = 'ABSENCEMOTIF_ID_MAX';
const GAM_LIBELLE = 'ABSENCEMOTIF_LIBELLE';
 
/*** Attributs : */
private $id_absence_motif;
private $libelle;
private $mark_cp_diminuer;
private $mark_hs_diminuer;
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_absence_motif';
$this->dao_correspondance = array(
'gam_id_absence_motif' => 'id_absence_motif',
'gam_libelle' => 'libelle',
'gam_mark_cp_diminuer' => 'mark_cp_diminuer',
'gam_mark_hs_diminuer' => 'mark_hs_diminuer');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Absence Motif
public function getIdAbsenceMotif()
{
return $this->id_absence_motif;
}
public function setIdAbsenceMotif( $iam )
{
$this->id_absence_motif = $iam;
}
 
// Libelle
public function getLibelle()
{
return $this->libelle;
}
public function setLibelle( $l )
{
$this->libelle = $l;
}
 
// CP Diminuer
public function getMarkCpDiminuer()
{
return $this->mark_cp_diminuer;
}
public function setMarkCpDiminuer( $cd )
{
$this->mark_cp_diminuer = $cd;
}
 
// HS Diminuer
public function getMarkHsDiminuer()
{
return $this->mark_hs_diminuer;
}
public function setMarkHsDiminuer( $hd )
{
$this->mark_hs_diminuer = $hd;
}
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_absence_motif.
* @return mixed un tableau d'objets AbsenceMotif s'il y en a plusieurs, l'objet AbsenceMotif s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case AbsenceMotif::GAM_TOUS:
$requete = 'SELECT * '.
'FROM gestion_absence_motif ';
break;
case AbsenceMotif::GAM_ID:
$requete = 'SELECT * '.
'FROM gestion_absence_motif '.
'WHERE gam_id_absence_motif = #0 ';
break;
case AbsenceMotif::GAM_ID_MAX:
$requete = 'SELECT MAX(gam_id_absence_motif) AS gam_id_absence_motif '.
'FROM gestion_absence_motif ';
break;
case AbsenceMotif::GAM_LIBELLE:
$requete = 'SELECT * '.
'FROM gestion_absence_motif '.
'WHERE gam_libelle = "#0" ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/UtilisateurAProjet.class.php
New file
0,0 → 1,144
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe UtilisateurAProjet
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class UtilisateurAProjet : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class UtilisateurAProjet extends aGttSql {
/*** Constantes : */
const GUAP_ID = 'UTILISATEURAPROJET_ID';
const GUAP_ID_MAX_UTILISATEUR = 'UTILISATEURAPROJET_ID_MAX_UTILISATEUR';
const GUAP_ID_MAX_PROJET = 'UTILISATEURAPROJET_ID_MAX_PROJET';
const GUAP_UTILISATEUR = 'UTILISATEURAPROJET_ID_UTILISATEUR';
const GUAP_PROJET = 'UTILISATEURAPROJET_ID_PROJET';
/*** Attributs : */
private $id_utilisateur;
private $id_projet;
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_utilisateur_a_projet';
$this->dao_correspondance = array(
'guap_id_utilisateur' => 'id_utilisateur',
'guap_id_projet' => 'id_projet');
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
/*** Accesseurs : */
// Id Utilisateur
public function getIdUtilisateur()
{
return $this->id_utilisateur;
}
public function setIdUtilisateur( $iu )
{
$this->id_utilisateur = $iu;
}
// Id Projet
public function getIdProjet()
{
return $this->id_projet;
}
public function setIdProjet( $ip )
{
$this->id_projet = $ip;
}
/*** Méthodes : */
 
/**
* Consulter la table gestion_utilisateur_a_projet.
* @return mixed un tableau d'objets UtilisateurAProjet s'il y en a plusieurs, l'objet UtilisateurAProjet s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case UtilisateurAProjet::GUAP_ID:
$requete = 'SELECT * '.
'FROM gestion_utilisateur_a_projet '.
'WHERE guap_id_utilisateur = #0 '.
' AND guap_id_projet = #1 ';
break;
case UtilisateurAProjet::GUAP_ID_MAX_UTILISATEUR:
$requete = 'SELECT MAX(guap_id_utilisateur) '.
'FROM gestion_utilisateur_a_projet ';
break;
case UtilisateurAProjet::GUAP_ID_MAX_PROJET:
$requete = 'SELECT MAX(guap_id_projet) '.
'FROM gestion_utilisateur_a_projet ';
break;
case UtilisateurAProjet::GUAP_UTILISATEUR:
$requete = 'SELECT * '.
'FROM gestion_utilisateur_a_projet '.
'WHERE guap_id_utilisateur = #0 ';
break;
case UtilisateurAProjet::GUAP_PROJET:
$requete = 'SELECT * '.
'FROM gestion_utilisateur_a_projet '.
'WHERE guap_id_projet = #0 ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/UtilisateurStatut.class.php
New file
0,0 → 1,149
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe UtilisateurStatut
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class UtilisateurStatut : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class UtilisateurStatut extends aGttSql {
/*** Constantes : */
const GUS_TOUS = 'UTILISATEURSTATUT_TOUS';
const GUS_ID = 'UTILISATEURSTATUT_ID';
const GUS_ID_MAX = 'UTILISATEURSTATUT_ID_MAX';
const GUS_LIBELLE = 'UTILISATEURSTATUT_LIBELLE';
 
/*** Attributs : */
private $id_utilisateur_statut;
private $libelle;
private $mark_recapitulatif;
 
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_utilisateur_statut';
$this->dao_correspondance = array(
'gus_id_utilisateur_statut' => 'id_utilisateur_statut',
'gus_libelle' => 'libelle',
'gus_mark_recapitulatif' => 'mark_recapitulatif');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Utilisateur Statut
public function getIdUtilisateurStatut()
{
return $this->id_utilisateur_statut;
}
public function setIdUtilisateurStatut( $ius )
{
$this->id_utilisateur_statut = $ius;
}
 
// Libelle
public function getLibelle()
{
return $this->libelle;
}
public function setLibelle( $l )
{
$this->libelle = $l;
}
 
// Mark Recapitulatif
public function getMarkRecapitulatif()
{
return $this->mark_recapitulatif;
}
public function setMarkRecapitulatif( $mr )
{
$this->mark_recapitulatif = $mr;
}
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_utilisateur_statut.
* @return mixed un tableau d'objets UtilisateurStatut s'il y en a plusieurs, l'objet UtilisateurStatut s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case UtilisateurStatut::GUS_TOUS:
$requete = 'SELECT * '.
'FROM gestion_utilisateur_statut ';
break;
case UtilisateurStatut::GUS_ID:
$requete = 'SELECT * '.
'FROM gestion_utilisateur_statut '.
'WHERE gus_id_utilisateur_statut = #0 ';
break;
case UtilisateurStatut::GUS_ID_MAX:
$requete = 'SELECT MAX(gus_id_utilisateur_statut) AS gus_id_utilisateur_statut '.
'FROM gestion_utilisateur_statut ';
break;
case UtilisateurStatut::GUS_LIBELLE:
$requete = 'SELECT * '.
'FROM gestion_utilisateur_statut '.
'WHERE gus_libelle = "#0" ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/aGttSql.class.php
New file
0,0 → 1,274
<?php
 
abstract class aGttSql {
 
/*** Attributs : */
private $base_de_donnees = GTT_BDD_NOM;
protected $table_nom;
protected $correspondance;
/*** Accesseurs : */
 
// Base De Donnees
function getBaseDeDonnees()
{
return $this->base_de_donnees;
}
function setBaseDeDonnees($bdd)
{
$this->base_de_donnees = $bdd;
}
// TableNom
function getTableNom()
{
return $this->dao_table_nom;
}
function setTableNom($tn)
{
$this->dao_table_nom = $tn;
}
// Correspondance
function getCorrespondance($champ = null)
{
if (!is_null($champ)) {
return $this->dao_correspondance[$champ];
}
return $this->dao_correspondance;
}
function setCorrespondance($c)
{
$this->dao_correspondance = $c;
}
 
/*** Méthodes : */
 
/** Instancie un objet utilisateur à partir d'un enregistrement issu de la base de donnée ou l'inverse.
* Cette métohode permet de s'abstraire des noms des champs présent dans la base de donnée.
*/
protected function basculerEnregistrementObjet($donnees, $instancier = false)
{
$classe = get_class($this);
if (is_array($donnees)) {
if ($instancier) {
foreach ($this->getCorrespondance() as $champ => $attribut) {
if (isset($donnees[$champ]) && !is_null($donnees[$champ])) {
$methode = $this->donnerMethodeSetAvecAttribut($attribut);
$this->$methode($donnees[$champ]);
}
}
} else {
$Objet = new $classe;
foreach ($this->getCorrespondance() as $champ => $attribut) {
if (isset($donnees[$champ]) && !is_null($donnees[$champ])) {
$methode = $this->donnerMethodeSetAvecAttribut($attribut);
$Objet->$methode($donnees[$champ]);
}
}
return $Objet;
}
} else if ($donnees instanceof $classe) {
$enregistrement = array();
foreach ($this->getCorrespondance() as $champ => $attribut) {
$methode = $this->donnerMethodeGetAvecAttribut($attribut);
if (method_exists($donnees, $methode)) {
if (!is_null($donnees->$methode())) {
$enregistrement[$champ] = $donnees->$methode();
}
}
}
return $enregistrement;
}
}
private function donnerMethodeGetAvecAttribut($attribut)
{
return 'get'.str_replace(' ', '', ucwords(str_replace('_', ' ', $attribut)));
}
private function donnerMethodeGetAvecChamp($champ)
{
return 'get'.str_replace(' ', '', ucwords(str_replace('_', ' ', $this->getCorrespondance($champ))));
}
private function donnerMethodeSetAvecAttribut($attribut)
{
return 'set'.str_replace(' ', '', ucwords(str_replace('_', ' ', $attribut)));
}
private function donnerMethodeSetAvecChamp($champ)
{
return 'set'.str_replace(' ', '', ucwords(str_replace('_', ' ', $this->getCorrespondance($champ))));
}
 
/**
* Consulter un ou plusieurs enregistrements dans la base de données.
* Chaque requête comportant des paramêtre doivent les inclures sous la forme "#0" pour le paramêtre 0,
* puis "#1" pour le paramêtre 1 et ainsi de suite.
* Exemple : SELECT * FROM gestion_projet WHERE gp_id_projet = #0
* ou SELECT * FROM gestion_projet WHERE gp_nom_projet = "#0"
* @return mixed false, un objet, un tableau d'objet ou rien et instancie l'objet courant.
*/
public function consulter($requete, $parametres = null, $instancier = false)
{
// Formatage de la requête avec les paramêtres s'il y en a
if (!is_null($parametres)) {
if (!is_array($parametres)) {
$parametres = array('#0' => $parametres);
} else {
// Ajout d'un # devant chaque clé numérique
if (count($parametres) > 0) {
foreach ($parametres as $c => $v) {
$parametres['#'.$c] = $v;
}
}
}
// Remplacement dans la requete par les valeurs des paramêtres
$requete = strtr($requete, $parametres);
}
if (GTT_DEBOGAGE_SQL) {
trigger_error($requete, E_USER_NOTICE);
}
$tps = microtime(true);
$resultat = $GLOBALS['db']->query($requete);
$GLOBALS['_GTT_']['chrono']->setTempsSql($tps, microtime(true));
(DB::isError($resultat)) ? trigger_error(GestionnaireErreur::retournerErreurSql(__FILE__, __LINE__, $resultat->getMessage(), $requete), E_USER_ERROR) : '' ;
$tab_resultat = array();
while ($donnees =& $resultat->fetchRow(DB_FETCHMODE_ASSOC)) {
$tab_resultat[] = $this->basculerEnregistrementObjet($donnees, $instancier);
}
$resultat_nbre = count($tab_resultat);
if ($resultat_nbre >= 1) {
return $tab_resultat;
} else if ($resultat_nbre == 0) {
return false;
}
}
 
/**
* Ajouter un enregistrement dans la base de données.
* @return true si ok, false si aucun enregistrement effectué
*/
public function ajouter()
{
$enregistrement = $this->basculerEnregistrementObjet($this);
$sql_attributs = '';
$sql_valeurs = '';
foreach($enregistrement as $champ => $val) {
if (!is_numeric($val)) {
$val = '"'.$val.'"';
}
$sql_attributs .= $champ.', ';
$sql_valeurs .= $val.', ';
}
$sql_attributs = trim($sql_attributs, ', ');
$sql_valeurs = trim($sql_valeurs, ', ');
$requete = 'INSERT INTO '.$this->getBaseDeDonnees().'.'.$this->getTableNom().' '.
'( '.$sql_attributs.' ) '.
'VALUES '.
'( '.$sql_valeurs.' )';
if (GTT_DEBOGAGE_SQL) {
trigger_error($requete, E_USER_NOTICE);
}
$tps = microtime(true);
$resultat = $GLOBALS['db']->query($requete);
$GLOBALS['_GTT_']['chrono']->setTempsSql($tps, microtime(true));
(DB::isError($resultat)) ? die (GestionnaireErreur::retournerErreurSql(__FILE__, __LINE__, $resultat->getMessage(), $requete)) : '' ;
$nbre_enregistrement_ajoute = $GLOBALS['db']->affectedRows();
if ($nbre_enregistrement_ajoute == 1) {
return true;
} elseif ($nbre_enregistrement_ajoute == 0) {
return false;
}
}
 
/**
* Modifier un enregistrement dans la base de données.
* @param object l'ancien objet contenant les valeurs de clés primaires non modifiées. Laissé vide si on ne modifie pas les clés.
* @return true si ok, false si aucun enregistrement effectué.
*/
public function modifier($Ancien = null)
{
$enregistrement = $this->basculerEnregistrementObjet($this);
$sql_where = '';
$sql_set = '';
foreach($enregistrement as $champ => $val) {
if (!is_numeric($val)) {
$val = '"'.$val.'"';
}
$sql_set .= $champ.' = '.$val.', ';
$classe = get_class($this);
if ($Ancien instanceof $classe) {
$methode = $this->donnerMethodeGetAvecChamp($champ);
$val = $Ancien->$methode();
if (!is_numeric($val)) {
$val = '"'.$val.'"';
}
}
if (preg_match('/_id_/', $champ)) {
$sql_where .= $champ.' = '.$val.' AND ';
}
}
$sql_set = trim($sql_set, ', ').' ';
$sql_where = trim($sql_where, ' AND ').' ';
$requete = 'UPDATE '.$this->getBaseDeDonnees().'.'.$this->getTableNom().' SET '.$sql_set.'WHERE '.$sql_where;
if (GTT_DEBOGAGE_SQL) {
trigger_error($requete, E_USER_NOTICE);
}
$tps = microtime(true);
$resultat = $GLOBALS['db']->query($requete);
$GLOBALS['_GTT_']['chrono']->setTempsSql($tps, microtime(true));
(DB::isError($resultat)) ? die (GestionnaireErreur::retournerErreurSql(__FILE__, __LINE__, $resultat->getMessage(), $requete)) : '' ;
$nbre_enregistrement_ajoute = $GLOBALS['db']->affectedRows();
if ($nbre_enregistrement_ajoute == 1) {
return true;
} elseif ($nbre_enregistrement_ajoute == 0) {
return false;
}
}
 
/**
* Supprimer un enregistrement dans la base de données.
* @return true si ok, false si aucun enregistrement effectué
*/
public function supprimer()
{
$enregistrement = $this->basculerEnregistrementObjet($this);
$sql_where = '';
foreach($enregistrement as $champ => $val) {
if (!is_numeric($val)) {
$val = '"'.$val.'"';
}
//if (preg_match('/_id_/', $champ)) {
$sql_where .= $champ.' = '.$val.' AND ';
//}
}
$sql_where = trim($sql_where, ' AND ').' ';
$requete = 'DELETE FROM '.$this->getBaseDeDonnees().'.'.$this->getTableNom().' WHERE '.$sql_where ;
if (GTT_DEBOGAGE_SQL) {
trigger_error($requete, E_USER_NOTICE);
}
$tps = microtime(true);
$resultat = $GLOBALS['db']->query($requete);
$GLOBALS['_GTT_']['chrono']->setTempsSql($tps, microtime(true));
(DB::isError($resultat)) ? die (GestionnaireErreur::retournerErreurSql(__FILE__, __LINE__, $resultat->getMessage(), $requete)) : '' ;
 
$nbre_enregistrement_suppr = $GLOBALS['db']->affectedRows();
if ($nbre_enregistrement_suppr == 1) {
return true;
} elseif ($nbre_enregistrement_suppr == 0) {
return false;
}
}
/** Mettre à NULL les champs de l'objet*/
public function initialiser()
{
foreach ($this->getCorrespondance() as $champ => $attribut) {
$methode = $this->donnerMethodeSetAvecAttribut($attribut);
$this->$methode(null);
}
}
/** Afficher l'objet courrant. */
public function afficher()
{
echo '<pre>'.print_r($this, true).'</pre>';
}
}
?>
/tags/v1.0-Homere/bibliotheque/metier/Absence.class.php
New file
0,0 → 1,182
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe Absence
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class Absence : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class Absence extends aGttSql {
/*** Constantes : */
const GA_ID = 'ABSENCE_ID';
const GA_ID_ABSENCE_MOTIF = 'ABSENCE_ID_ABSENCE_MOTIF';
const GA_ID_UTILISATEUR = 'ABSENCE_ID_UTILISATEUR';
const GA_ID_UTILISATEUR_DATE_DEB_FIN = 'ABSENCE_ID_UTILISATEUR_DATE_DEB_FIN';
const GA_ID_MAX_UTILISATEUR = 'ABSENCE_ID_MAX_UTILISATEUR';
const GA_ID_MAX_ABSENCE_MOTIF = 'ABSENCE_ID_MAX_ABSENCE_MOTIF';
const GA_ID_MAX_DATE_ABSENCE = 'ABSENCE_ID_MAX_DATE_ABSENCE';
 
/*** Attributs : */
private $id_utilisateur;
private $id_absence_motif;
private $id_date_absence;
private $duree;
 
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_absence';
$this->dao_correspondance = array(
'ga_id_utilisateur' => 'id_utilisateur',
'ga_id_absence_motif' => 'id_absence_motif',
'ga_id_date_absence' => 'id_date_absence',
'ga_duree' => 'duree');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Utilisateur
public function getIdUtilisateur()
{
return $this->id_utilisateur;
}
public function setIdUtilisateur( $iu )
{
$this->id_utilisateur = $iu;
}
 
// Id Absence Motif
public function getIdAbsenceMotif()
{
return $this->id_absence_motif;
}
public function setIdAbsenceMotif( $iam )
{
$this->id_absence_motif = $iam;
}
 
// Id Date Absence
public function getIdDateAbsence()
{
return $this->id_date_absence;
}
public function setIdDateAbsence( $ida )
{
$this->id_date_absence = $ida;
}
 
// Duree
public function getDuree()
{
return $this->duree;
}
public function setDuree( $d )
{
$this->duree = $d;
}
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_absence.
* @return mixed un tableau d'objets Absence s'il y en a plusieurs, l'objet Absence s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case Absence::GA_ID:
$requete = 'SELECT * '.
'FROM gestion_absence '.
'WHERE ga_id_utilisateur = #0 '.
' AND ga_id_absence_motif = #1 '.
' AND ga_id_date_absence = #2 ';
break;
case Absence::GA_ID_ABSENCE_MOTIF:
$requete = 'SELECT * '.
'FROM gestion_absence '.
'WHERE ga_id_absence_motif = #0 ';
break;
case Absence::GA_ID_UTILISATEUR:
$requete = 'SELECT * '.
'FROM gestion_absence '.
'WHERE ga_id_utilisateur = #0 ';
break;
case Absence::GA_ID_UTILISATEUR_DATE_DEB_FIN:
$requete = 'SELECT * '.
'FROM gestion_absence '.
'WHERE ga_id_utilisateur = #0 '.
' AND ga_id_date_absence >= "#1" '.
' AND ga_id_date_absence <= "#2" ';
break;
case Absence::GA_ID_MAX_UTILISATEUR:
$requete = 'SELECT MAX(ga_id_utilisateur) '.
'FROM gestion_absence ';
break;
case Absence::GA_ID_MAX_ABSENCE_MOTIF:
$requete = 'SELECT MAX(ga_id_absence_motif) '.
'FROM gestion_absence ';
break;
case Absence::GA_ID_MAX_DATE_ABSENCE:
$requete = 'SELECT MAX(ga_id_date_absence) '.
'FROM gestion_absence ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/Nombre.class.php
New file
0,0 → 1,37
<?php
 
class Nombre {
 
public static function formaterNbre($tableau, $format = 'fr', $debog = false) {
if (is_array($tableau)) {
if ($debog) {
trigger_error('pt2='.print_r($tableau, true), E_USER_NOTICE);
}
foreach ($tableau as $c => $v) {
$tableau[$c] = Nombre::formaterNbre($v, $format, $debog);
if ($debog) {
trigger_error('pt3='.print_r($tableau[$c], true), E_USER_NOTICE);
}
}
} else if (is_float($tableau) || is_int($tableau) || preg_match('/^(?:\d+|\d+\.\d+)$/', $tableau)) {
if ($debog) {
trigger_error('pt1='.print_r($tableau, true), E_USER_NOTICE);
}
switch ($format) {
case 'fr' :
if (is_float($tableau) || preg_match('/^\d+\.\d+$/', $tableau)) {
// Nous supprimons les 0 après la virgule puis la virgule s'il n'y pas de chifre après
$tableau = rtrim(rtrim(number_format($tableau, 2, ',', ' '), '0'), ',');
}
if (is_int($tableau) || preg_match('/^\d+$/', $tableau)) {
$tableau = number_format($tableau, 0, ',', ' ');
}
break;
default:
trigger_error("Format pour les nombres non pris en charge : $format", E_USER_WARNING);
}
}
return $tableau;
}
}
?>
/tags/v1.0-Homere/bibliotheque/metier/Projet.class.php
New file
0,0 → 1,248
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe Projet
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class Projet : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class Projet extends aGttSql {
/*** Constantes : */
const GP_TOUS = 'PROJET_TOUS';
const GP_ID = 'PROJET_ID';
const GP_NOM = 'PROJET_NOM';
const GP_ID_MAX = 'PROJET_ID_MAX';
const GP_ID_LIST = 'PROJET_ID_LIST';
const GP_CE_CATEGORIE = 'PROJET_CE_CATEGORIE';
 
/*** Attributs : */
private $id_projet;
private $ce_projet_parent;
private $ce_categorie;
private $nom;
private $description;
private $date_debut;
private $date_fin;
private $duree_prevue;
private $duree_finance;
private $avancement;
 
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_projet';
$this->dao_correspondance = array(
'gp_id_projet' => 'id_projet',
'gp_ce_projet_parent' => 'ce_projet_parent',
'gp_ce_categorie' => 'ce_categorie',
'gp_nom' => 'nom',
'gp_description' => 'description',
'gp_date_debut' => 'date_debut',
'gp_date_fin' => 'date_fin',
'gp_duree_prevue' => 'duree_prevue',
'gp_duree_finance' => 'duree_finance',
'gp_avancement' => 'avancement');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Projet
public function getIdProjet()
{
return $this->id_projet;
}
public function setIdProjet( $ip )
{
$this->id_projet = $ip;
}
 
// Ce Projet Parent
public function getCeProjetParent()
{
return $this->ce_projet_parent;
}
public function setCeProjetParent( $cpp )
{
$this->ce_projet_parent = $cpp;
}
 
 
// Ce Categorie
public function getCeCategorie()
{
return $this->ce_categorie;
}
public function setCeCategorie( $cc )
{
$this->ce_categorie = $cc;
}
 
// Nom
public function getNom()
{
return $this->nom;
}
public function setNom( $n )
{
$this->nom = $n;
}
 
// Description
public function getDescription()
{
return $this->description;
}
public function setDescription( $d )
{
$this->description = $d;
}
 
// Date Debut
public function getDateDebut()
{
return $this->date_debut;
}
public function setDateDebut( $dd )
{
$this->date_debut = $dd;
}
// Date Fin
public function getDateFin()
{
return $this->date_fin;
}
public function setDateFin( $df )
{
$this->date_fin = $df;
}
 
// Duree Prevue
public function getDureePrevue()
{
return $this->duree_prevue;
}
public function setDureePrevue( $dp )
{
$this->duree_prevue = $dp;
}
 
// Duree Finance
public function getDureeFinance()
{
return $this->duree_finance;
}
public function setDureeFinance( $df )
{
$this->duree_finance = $df;
}
 
// Avancement
public function getAvancement()
{
return $this->avancement;
}
public function setAvancement( $a )
{
$this->avancement = $a;
}
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_projet.
* @return mixed un tableau d'objets Projet s'il y en a plusieurs, l'objet Projet s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case Projet::GP_TOUS:
$requete = 'SELECT * '.
'FROM gestion_projet LEFT JOIN gestion_projet_categorie ON (gp_ce_categorie = gpc_id_categorie) '.
'ORDER BY gpc_libelle, gp_nom ASC';
break;
case Projet::GP_ID:
$requete = 'SELECT * '.
'FROM gestion_projet '.
'WHERE gp_id_projet = #0 ';
break;
case Projet::GP_NOM:
$requete = 'SELECT * '.
'FROM gestion_projet '.
'WHERE gp_nom = "#0" ';
break;
case Projet::GP_ID_MAX:
$requete = 'SELECT MAX(gp_id_projet) AS gp_id_projet '.
'FROM gestion_projet ';
break;
case Projet::GP_ID_LIST:
$requete = 'SELECT * '.
'FROM gestion_projet LEFT JOIN gestion_projet_categorie ON (gp_ce_categorie = gpc_id_categorie) '.
'WHERE gp_id_projet IN (#0) '.
'ORDER BY gpc_libelle, gp_nom ASC';
break;
case Projet::GP_CE_CATEGORIE:
$requete = 'SELECT * '.
'FROM gestion_projet '.
'WHERE gp_ce_categorie = #0 ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/ProjetCategorie.class.php
New file
0,0 → 1,151
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe ProjetCategorie
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class ProjetCategorie : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class ProjetCategorie extends aGttSql {
/*** Constantes : */
const GPC_TOUS = 'PROJETCATEGORIE_TOUS';
const GPC_ID = 'PROJETCATEGORIE_ID';
const GPC_ID_MAX = 'PROJETCATEGORIE_ID_MAX';
const GPC_LIBELLE = 'PROJETCATEGORIE_LIBELLE';
 
/*** Attributs : */
private $id_categorie;
private $libelle;
private $abreviation;
 
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_projet_categorie';
$this->dao_correspondance = array(
'gpc_id_categorie' => 'id_categorie',
'gpc_libelle' => 'libelle',
'gpc_abreviation' => 'abreviation');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Categorie
public function getIdCategorie()
{
return $this->id_categorie;
}
public function setIdCategorie( $ic )
{
$this->id_categorie = $ic;
}
 
// Libelle
public function getLibelle()
{
return $this->libelle;
}
public function setLibelle( $l )
{
$this->libelle = $l;
}
 
// Abreviation
public function getAbreviation()
{
return $this->abreviation;
}
public function setAbreviation( $a )
{
$this->abreviation = $a;
}
 
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_projet_categorie.
* @return mixed un tableau d'objets ProjetCategorie s'il y en a plusieurs, l'objet ProjetCategorie s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case ProjetCategorie::GPC_TOUS:
$requete = 'SELECT * '.
'FROM gestion_projet_categorie '.
'ORDER BY gpc_libelle';
break;
case ProjetCategorie::GPC_ID:
$requete = 'SELECT * '.
'FROM gestion_projet_categorie '.
'WHERE gpc_id_categorie = #0 ';
break;
case ProjetCategorie::GPC_ID_MAX:
$requete = 'SELECT MAX(gpc_id_categorie) AS gpc_id_categorie '.
'FROM gestion_projet_categorie ';
break;
case ProjetCategorie::GPC_LIBELLE:
$requete = 'SELECT * '.
'FROM gestion_projet_categorie '.
'WHERE gpc_libelle = "#0" ';
break;
default :
$message = 'Commande '.$cmd.'inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/TravailProjet.class.php
New file
0,0 → 1,182
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe TravailProjet
*
* Description
*
*@package eFlore
*@subpackage modele
//Auteur original :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
//Autres auteurs :
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* class TravailProjet : est à la fois le DAO et le conteneur de la table gestion_utilisateur.
* classe métier
*/
class TravailProjet extends aGttSql {
/*** Constantes : */
const GTP_ID = 'TRAVAILPROJET_ID';
const GTP_ID_UTILISATEUR_DATE_DEB_FIN = 'TRAVAILPROJET_ID_UTILISATEUR_DATE';
const GTP_ID_MAX_UTILISATEUR = 'TRAVAILPROJET_ID_MAX_UTILISATEUR';
const GTP_ID_MAX_PROJET = 'TRAVAILPROJET_ID_MAX_PROJET';
const GTP_ID_MAX_DATE_TRAVAIL = 'TRAVAILPROJET_ID_MAX_DATE_TRAVAIL';
const GTP_PROJET = 'TRAVAILPROJET_ID_PROJET';
const GTP_UTILISATEUR = 'TRAVAILPROJET_ID_UTILISATEUR';
/*** Attributs : */
private $id_utilisateur;
private $id_projet;
private $id_date_travail;
private $duree;
 
/*** Aggregations : */
 
/*** Constructeur : */
public function __construct($cmd = null, $parametres = null)
{
$this->dao_table_nom = 'gestion_travail_projet';
$this->dao_correspondance = array(
'gtp_id_utilisateur' => 'id_utilisateur',
'gtp_id_projet' => 'id_projet',
'gtp_id_date_travail' => 'id_date_travail',
'gtp_duree' => 'duree');
 
// Si l'on veut remplir l'objet à la création on lance la requete correspondante
if (!is_null($cmd)) {
$this->consulter($cmd, $parametres, true);
}
}
 
/*** Accesseurs : */
// Id Utilisateur
public function getIdUtilisateur()
{
return $this->id_utilisateur;
}
public function setIdUtilisateur( $iu )
{
$this->id_utilisateur = $iu;
}
 
// Id Projet
public function getIdProjet()
{
return $this->id_projet;
}
public function setIdProjet( $ip )
{
$this->id_projet = $ip;
}
 
// Id Date Travail
public function getIdDateTravail()
{
return $this->id_date_travail;
}
public function setIdDateTravail( $idt )
{
$this->id_date_travail = $idt;
}
 
// Duree
public function getDuree()
{
return $this->duree;
}
public function setDuree( $d )
{
$this->duree = $d;
}
 
/*** Méthodes : */
 
/**
* Consulter la table gestion_travail_projet.
* @return mixed un tableau d'objets TravailProjet s'il y en a plusieurs, l'objet TravailProjet s'il y en a 1 seul sinon false.
*/
public function consulter($cmd = '', $parametres = array(), $instancier = false)
{
switch ($cmd) {
case TravailProjet::GTP_ID:
$requete = 'SELECT * '.
'FROM gestion_travail_projet '.
'WHERE gtp_id_utilisateur = #0 '.
' AND gtp_id_projet = #1 '.
' AND gtp_id_date_travail = "#2" ';
break;
case TravailProjet::GTP_ID_UTILISATEUR_DATE_DEB_FIN:
$requete = 'SELECT * '.
'FROM gestion_travail_projet '.
'WHERE gtp_id_utilisateur = #0 '.
' AND gtp_id_date_travail >= "#1" '.
' AND gtp_id_date_travail <= "#2" ';
break;
case TravailProjet::GTP_ID_MAX_UTILISATEUR:
$requete = 'SELECT MAX(gtp_id_utilisateur) '.
'FROM gestion_travail_projet ';
break;
case TravailProjet::GTP_ID_MAX_PROJET:
$requete = 'SELECT MAX(gtp_id_projet) '.
'FROM gestion_travail_projet ';
break;
case TravailProjet::GTP_ID_MAX_DATE_TRAVAIL:
$requete = 'SELECT MAX(gtp_id_date_travail) '.
'FROM gestion_travail_projet ';
break;
case TravailProjet::GTP_PROJET:
$requete = 'SELECT gtp_id_projet '.
'FROM gestion_travail_projet '.
'WHERE gtp_id_projet = #0 ';
break;
case TravailProjet::GTP_UTILISATEUR:
$requete = 'SELECT gtp_id_utilisateur '.
'FROM gestion_travail_projet '.
'WHERE gtp_id_utilisateur = #0 ';
break;
default :
$message = 'Commande '.$cmd.' inconnue!';
$e = GestionnaireErreur::formaterMessageErreur(__FILE__, __LINE__, $message);
trigger_error($e, E_USER_ERROR);
}
return parent::consulter($requete, $parametres, $instancier);
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/tags/v1.0-Homere/bibliotheque/metier/Calendrier.class.php
New file
0,0 → 1,242
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 5.1.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2006 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This file is part of eFlore. |
// | |
// | Foobar is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | Foobar is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with Foobar; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// CVS : $Id$
/**
* Classe Calendrier
*
* Description
*
*@package Calendrier
//Auteur original :
*@version 1
*@author Dorian BANNIER <dbannier@aol.com>
//Autres auteurs :
*@version 3
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
*@version 4
*@author Jean-Pascal MILCENT <jpm@clapas.org>
*@author aucun
*@copyright Tela-Botanica 2000-2006
*@version $Revision$ $Date$
// +------------------------------------------------------------------------------------------------------+
*/
 
/**
* Classe calendrier pour gerer le calendrier pour un mois et une annee
*
*@param annee
*@param mois
*@param premier jour du mois
*@param semaine
*@param l'url du resultat affiche
*@param liste de noms des jours
*@param liste de noms des mois
*@param liste des jours feries du mois
*/
class Calendrier
{
private $annee;
private $mois;
private $semaine;
private $jour;
private $nom_jours = array();
private $nom_mois = array();
private $liste_feries = array();
/**
*constructeur de la classe calendrier
*toutes les variables sont initialises avec les donnees
*de la date du jour si on ne passe aucune date en parametre
*sinon on initialise le calendrier avec
*@param semaine
*@param annee
*/
public function __construct($jour = null, $semaine = null, $mois = null, $annee = null)
{
if (is_null($jour)) {
$jour = date('d', time());
}
$this->jour = $jour;
if (is_null($semaine)) {
$semaine = date('W', time());
}
$this->semaine = $semaine;
if (is_null($mois)) {
$mois = date('m', time());
}
$this->mois = $mois;
if (is_null($annee)) {
// TODO : vérifier le standard ISO-8601
$annee = date('Y', time());
}
$this->annee = $annee;
$this->nom_jours = array (1 => GESTION_LUN_A, GESTION_MAR_A, GESTION_MER_A, GESTION_JEU_A, GESTION_VEN_A, GESTION_SAM_A ,GESTION_DIM_A);
$this->nom_jours_long = array (1 => GESTION_LUN_L, GESTION_MAR_L, GESTION_MER_L, GESTION_JEU_L, GESTION_VEN_L, GESTION_SAM_L ,GESTION_DIM_L);
$this->nom_mois = array(1 => "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre");
$this->liste_feries = $this->calculerJoursFeries($this->annee);
}
public function getAnnee()
{
return $this->annee;
}
public function getMois()
{
return $this->mois;
}
public function getSemaine()
{
return $this->semaine;
}
public function getJour()
{
return $this->jour;
}
public function getNomJours($j = null)
{
if (is_null($j)) {
return $this->nom_jours;
}
return $this->nom_jours[$j];
}
public function getNomJoursLong($j = null)
{
if (is_null($j)) {
return $this->nom_jours_long;
}
return $this->nom_jours_long[$j];
}
 
public function getNomMois($m = null)
{
if (is_null($m)) {
return $this->nom_mois;
}
return $this->nom_mois[$m];
}
public function getListeFeries()
{
return $this->liste_feries;
}
/**
*Calcule les dates des jours fériés pour la france.
*Renvoie un tableau contenant la liste de dates par mois.
*Les dates sont de la forme timestamp unix.
*
*@param integer l'année pour laquelle on veut les jours fériés.
*@return array tableau des dates fériées.
*/
public function calculerJoursFeries($annee)
{
$tab = array( mktime(0,0,0,1,1,$annee),
$this->donnerDatePaques($annee),
mktime(0,0,0,5,1,$annee),
mktime(0,0,0,5,8,$annee),
$this->donnerDateAscension($annee),
$this->donnerDatePentecote($annee),
mktime(0,0,0,7,14,$annee),
mktime(0,0,0,8,15,$annee),
mktime(0,0,0,11,1,$annee),
mktime(0,0,0,11,11,$annee),
mktime(0,0,0,12,25,$annee));
return $tab;
}
/**
*Calcule la date du lundi de Pâques.
*
*@param integer l'année pour laquelle on veut connaître la date de Pâques
*@return integer le timestamp du lundi de Pâques
*/
public function donnerDatePaques($annee)
{
$date_paques = easter_date($annee);
$lundi_paques = mktime( date("H", $date_paques),
date("i", $date_paques),
date("s", $date_paques),
date("m", $date_paques),
date("d", $date_paques) + 1,
date("Y", $date_paques));
return $lundi_paques;
}
/**
*Calcule la date de l'ascension.
*
*@param integer l'année pour laquelle on veut connaître la date de l'ascencion
*@return integer le timestamp de l'ascencion
*/
public function donnerDateAscension($annee)
{
$date_paques = easter_date($annee);
$date_ascension = mktime( date("H", $date_paques),
date("i", $date_paques),
date("s", $date_paques),
date("m", $date_paques),
date("d", $date_paques) + 39,
date("Y", $date_paques));
return $date_ascension;
}
 
/**
*Calcule la date du lundi de la pentecote
*Renvoie un timestamp
*renvoie cette derniere
*/
public function donnerDatePentecote($annee)
{
$date_paques = easter_date($annee);
$date_ascension = $this->donnerDateAscension($annee);
$date_pentecote = mktime( date("H", $date_ascension),
date("i", $date_ascension),
date("s", $date_ascension),
date("m", $date_ascension),
date("d", $date_ascension) + 11,
date("Y", $date_ascension));
return $date_pentecote;
}
 
/**
*Indique si une date est fériée ou non
*
*@param integer le timestamp de la date à vérifier
*@return boolean true si vrai, false si le jour n'est pas férié.
*/
function etreFerie($date)
{
if (in_array($date, $this->liste_feries)) {
return true;
} else {
return false;
}
}
}
?>
/tags/v1.0-Homere/index.php
New file
0,0 → 1,104
<?php
// +------------------------------------------------------------------------------------------------------+
// | PHP version 4.1 |
// +------------------------------------------------------------------------------------------------------+
// | Copyright (C) 2004 Tela Botanica (accueil@tela-botanica.org) |
// +------------------------------------------------------------------------------------------------------+
// | This library is free software; you can redistribute it and/or |
// | modify it under the terms of the GNU Lesser General Public |
// | License as published by the Free Software Foundation; either |
// | version 2.1 of the License, or (at your option) any later version. |
// | |
// | This library is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
// | Lesser General Public License for more details. |
// | |
// | You should have received a copy of the GNU Lesser General Public |
// | License along with this library; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +------------------------------------------------------------------------------------------------------+
// |@author ABDOOL RAHEEM shaheen shaheenar50@hotmail.com |
// |@version 3 |
 
// +------------------------------------------------------------------------------------------------------+
/*
*fichier contenant le menu principal de l'application de gestion du temps de travail
*@package gtt_general
//Auteur original :
*@author Dorian Bannier <dbannier@aol.com>
//Autres auteurs :
*@author Jean-Pascal MILCENT <jpm@tela-botanica.org>
*@copyright Copyright (C) 2003 Tela-Botanica
*/
// +------------------------------------------------------------------------------------------------------+
// | INCLUSION DE FICHIERS |
// +------------------------------------------------------------------------------------------------------+
 
// Fichiers de la bibliotheque PEAR
include 'gtt_config.inc.php';
if (!file_exists('config.inc.php')) {
die('Veuillez configurer la base de données de la Gestion du Temps de travail en complétant puis en renommant en config.inc.php le fichier config.inc.defaut.php.');
}
include 'config.inc.php';
include GTT_CHEMIN_LANGUE.'gtt_langue_'.GTT_LANGUE.'.inc.php';
 
// Gestion de l'action à executer par défaut
if (empty($_GET['action'])) {
$_GET['action'] = 'identification';
}
// Gestion du format du template
if (empty($_GET['format'])) {
$_GET['format'] = 'html';
}
// Gestion du type de sortie par défaut
if (empty($_GET['sortie'])) {
$_GET['sortie'] = $_GET['format'];
}
 
// Initialisation du Gestionnaire d'erreurs
$GLOBALS['_GTT_']['erreur'] = new GestionnaireErreur(GTT_DEBOGAGE_CONTEXTE);
$GLOBALS['_GTT_']['erreur']->setNiveauErreurCourrant(GTT_DEBOGAGE_NIVEAU);
 
// Initialisation du Chronomêtre
$GLOBALS['_GTT_']['chrono'] = new Chronometre();
 
// Connexion à la base de données
$GLOBALS['db'] = DB::connect(GTT_BDD_DSN);
if (PEAR::isError($GLOBALS['db'])) {
trigger_error("Échec connexion à la base de données : ".$GLOBALS['db']->getMessage(), E_USER_ERROR);
}
// Utilisation de l'utf-8
if (PEAR::isError($GLOBALS['db']->query('SET NAMES "utf8"'))) {
trigger_error("Échec de l'utilisation d'UTF-8 : ".$GLOBALS['db']->getMessage(), E_USER_WARNING);
}
 
// Utilisation du mécanisme MVC avec Squelette PHP et objet
$Controlleur = new ControlleurFrontal($_GET['action'], $_GET['format'], $_GET['sortie']);
$Controlleur->executer();
 
/**
* La fonction __autoload() charge dynamiquement les classes trouvées dans le code.
*
* Cette fonction est appelée par php5 quand il trouve une instanciation de classe dans le code.
*
*@param string le nom de la classe appelée.
*@return void le fichier contenant la classe doit être inclu par la fonction.
*/
function __autoload($classe)
{
$fichier_classe_pear = GTT_CHEMIN_PEAR.str_replace('_', '/', $classe).'.php';
if (file_exists($fichier_classe_pear)) {
require_once $fichier_classe_pear;
} else {
$nom_classe_gtt = $classe.'.class.php';
foreach ($GLOBALS['_GTT_']['tab_chemin_autoload'] as $chemin) {
$fichier = $chemin.$nom_classe_gtt;
if (file_exists($fichier)) {
require_once $fichier;
}
}
}
}
 
?>
Property changes:
Added: svn:executable
/tags/v1.0-Homere/langues/gtt_langue_fr.inc.php
New file
0,0 → 1,362
<?php
// +----------------------------------------------------------------------------+
// | gestion_lang_fr.php |
// +----------------------------------------------------------------------------+
// | Copyright (c) 2002 Tela Botanica |
// +----------------------------------------------------------------------------+
// | Gestion est une application permettant de gerer les heures de travail des |
// | employés sur chaque projet (taches), ainsi que leurs congés, et permet de |
// | générer des recapitulatif et graphiques. |
// | Chacun doit quotidiennement donner le temps passé sur chaque projet. |
// | |
// | Gestion demande l'identification des utilisateurs, et fait les traitements |
// | en fonction de ce parametre, de la date, et d'autres définie à chaque fois.|
// | Ce fichier contient toutes les expressions en francais du programme |
// | |
// +----------------------------------------------------------------------------+
// | Auteur : Dorian Bannier (dbannier@aol.com) |
// +----------------------------------------------------------------------------+
/**
* gestion_lang_fr.php - Fichier contenant les constantes des textes de Gestion.
*
*Ce fichier contient toutes les constantes servant à l'affichage des textes de l'application Gestion.
*
*@package gestion
//Auteur original :
*@author Dorian Bannier <dbannier@aol.com>
//Autres auteurs :
*@author Jean-Pascal MILCENT <jpm@tela-botanica.org>
*@copyright Copyright (C) 2003 Tela-Botanica
*@version $Date: 2005/02/22 12:07:13 $
*@author Shaheen ABDOOL RAHEEM <shaheenar50@hotmail.com>
*/
// +----------------------------------------------------------------------------+
//
// IDENTITE : $Id: gtt_langue_fr.inc.php,v 1.1 2005/02/22 12:07:13 jpm Exp $
// FICHIER : $RCSfile: gtt_langue_fr.inc.php,v $
// AUTEUR : $Author: jpm $
// VERSION : $Revision: 1.1 $
// DATE : $Date: 2005/02/22 12:07:13 $
//
// +----------------------------------------------------------------------------+
 
//Constante comprenant du texte de l'application Gestion Temps de Travail.
//Abréviation application : GTT
//Abréviation constantes de langue : L
//Les constantes de langues doivent donc commencer par l'abréviation : GTT_L_
 
// +----------------------------------------------------------------------------+
// GENERAL
//Abréviation : G
$G =& $GLOBALS['_GTT_']['i18n']['general'];
define ( 'GTT_L_G_NOM_APPLICATION' , 'Gestion du Temps de Travail' );
define ( 'GTT_L_G_OUI' , 'Oui' );//GESTION_OUI_L
define ( 'GTT_L_G_NON' , 'Non' );//GESTION_NON_L
define ( 'GTT_L_G_OK' , 'OK' );
$G['valider'] = 'Valider';
define ( 'GTT_L_G_VALIDER', 'Valider');
define ( 'GTT_L_G_MODIFIER', 'Modifier');
define ( 'GTT_L_G_SUPPRIMER', 'Supprimer');
define ( 'GTT_L_G_AUJOURDHUI' , 'Aujourd\'hui' );
define ( 'GTT_L_G_MAJ' , 'Mettre à jour' );//GESTION_MAJ_L
define ( 'GTT_L_G_RECOMMENCER' , 'Recommencer' );
define ( 'GTT_L_G_JOUR_SINGULIER' , 'jour' );
define ( 'GTT_L_G_JOURS_PLURIEL' , 'jours' );
 
// +----------------------------------------------------------------------------+
 
// +----------------------------------------------------------------------------+
// PAGE AUTHENTIFICATION
//Abréviation : AU
define ( 'GTT_L_AU_LOGIN' , 'Login' );//GESTION_LOGIN_L
define ( 'GTT_L_AU_MDP' , 'Mot de passe' );//GESTION_PASSWORD_L
// +----------------------------------------------------------------------------+
 
// +----------------------------------------------------------------------------+
// MENU
//Abréviation : ME
define ( 'GTT_L_ME_TRAVAIL', 'Gestion du travail' );//GESTION_TRAVAIL_L
define ( 'GTT_L_ME_NON_TRAVAIL', 'Gestion des absences' );//GESTION_NONTRAVAIL_L
define ( 'GTT_L_ME_GRAPH' , 'Graphiques récapitulatifs' );//GESTION_GRAPHIQUE_L
define ( 'GTT_L_ME_RECAPITULATIF_GENERAL' , 'Informations générales' );//GESTION_RECAPGENE_L
define ( 'GTT_L_ME_RECAPITULATIF_UTILISATEUR', 'Votre travail par projet' );//GESTION_RECAPITULATIF_L
define ( 'GTT_L_ME_FEUILLE_MOIS' , 'Votre travail par mois' );//GESTION_FEUILLEMOIS_L
define ( 'GTT_L_ME_UTILISATEURS' , 'Gestion des utilisateurs' );//GESTION_DONNEE_UTILISATEUR_L
define ( 'GTT_L_ME_ADMINISTRATION' , 'Administration' );//GESTION_ADMINISTRATEUR_L
define ( 'GTT_L_ME_DECONNECTION' , 'Déconnexion' );//GESTION_DECONNECTION_L
// +----------------------------------------------------------------------------+
 
// +----------------------------------------------------------------------------+
// FICHE UTILISATEUR
//Abréviation : FU
define ( 'GTT_L_FU_TITRE_INFOS', 'Informations personnelles' );
define ( 'GTT_L_FU_TITRE_NOTE', 'Note' );
define ( 'GTT_L_FU_ID' , 'Utilisateur n°' );//GESTION_ID_L
define ( 'GTT_L_FU_STATUT' , 'Statut' );//GESTION_STATUS_L
define ( 'GTT_L_FU_EMAIL' , 'Courriel' );//GESTION_EMAIL_L
define ( 'GTT_L_FU_TEL' , 'Téléphone' );//GESTION_TEL_L
define ( 'GTT_L_FU_HEURE_SUP' , 'Heures supplémentaires restantes' );//GESTION_HEURESUPP_L
define ( 'GTT_L_FU_CONGES_RESTE' , 'Congés payés restant' );//GESTION_CONGES_RESTANT_L
define ( 'GTT_L_FU_TEMPS_TRAVAIL' , 'Temps journalier de travail' );//GESTION_TEMPSTRAVAIL_L
define ( 'GTT_L_FU_ADRESSE' , 'Adresse' );//GESTION_ADDRESSE_L
define ( 'GTT_L_FU_VILLE' , 'Ville' );//GESTION_VILLE_L
define ( 'GTT_L_FU_CODE_POSTAL' , 'Code postal' );//GESTION_CODEPOSTAL_L
define ( 'GTT_L_FU_ADMIN' , 'Adminitrateur' );//GESTION_ADMINISTRATEUR_L
define ( 'GTT_L_FU_ADMIN_2' , 'Cet utilisateur ne doit pas apparaître dans les divers récapitulatif' );//GESTION_ADMINISTRATEUR2_L
define ( 'GTT_L_FU_TITRE_MODIF_UTILISATEUR' , 'Modification des données de' );//GESTION_MAJ_USER_L
define ( 'GTT_L_FU_TITRE_MODIF_UTILISATEUR_INFOS' , 'Modification des informations générales' );
define ( 'GTT_L_FU_TITRE_MODIF_UTILISATEUR_MDP' , 'Modification du mot de passe' );
define ( 'GTT_L_FU_MAJ_MDP' , 'Ne remplissez les deux champs ci-dessous que si vous voulez changer de mot de passe, sinon, laissez-les vides' );//GESTION_MAJ_PASS_L
define ( 'GTT_L_FU_MDP' , 'Mot de passe' );//GESTION_PASSWORD_L
define ( 'GTT_L_FU_CONFIRMATION_MDP' , 'Confirmer mot de passe' );//GESTION_CONFIRM_PASSWORD_L
define ( 'GTT_L_FU_NOTE', 'Note' );
define ( 'GTT_L_FU_MODIFIER_FICHE' , 'Modifier mes données' );//GESTION_MODIFIER_DONNEES_L
define ( 'GTT_L_FU_VOIR_FEUILLE_MOIS' , 'Voir la fiche mensuelle de cette utilisateur' );//GESTION_VOIR_FICHE_L
// +----------------------------------------------------------------------------+
 
// +----------------------------------------------------------------------------+
// MENU TRAVAIL
//Abréviation : TR
define ( 'GTT_L_TR_BIENVENUE', 'Bienvenue');
define ( 'GTT_L_TR_JOURS_RECUPERATION', 'Heures supp restantes');
define ( 'GTT_L_TR_JOURS_CONGES', 'Congés payés restants');
define ( 'GTT_L_TR_MOIS', 'Mois');
define ( 'GTT_L_TR_PROJET', 'Projets');
define ( 'GTT_L_TR_DUREE', 'Durées');
define ( 'GTT_L_TR_HEURES_L', 'heures ');
define ( 'GTT_L_TR_HEURE_L', 'heure ');
 
 
// +----------------------------------------------------------------------------+
// MESSAGES d'ERREUR
//Abréviation : ERREUR
define ( 'GTT_L_ERREUR_CONNECTION_BD', 'L\erreur sql provient de la demande de connection à la base de données.' );
define ( 'GTT_ERREUR_NOM', 'Vous devez rentrer un nom valide');
define ( 'GTT_ERREUR_PRENOM', 'Vous devez rentrer un prénom valide ');
define ( 'GTT_ERREUR_NOMBRE','Vous devez rentrer un nombre valide');
define ( 'GTT_ERREUR_VALEUR_NOMBRE', 'Valeur incorrecte ');
define ( 'GTT_ERREUR_TEL', 'Vous devez rentrer un numéro valide');
define ( 'GTT_ERREUR_MAIL', 'Vous devez rentrer un email valide ');
define ( 'GTT_ERREUR_PASSWD', 'Vous devez rentrer un mot de passe');
define ( 'GTT_DONNEES_INCORRECTES', 'Erreur : champs non conformes ');
define ( 'GTT_DONNEES_A_CORRIGER', 'Veuillez corriger les champs nécessaires');
define ( 'GTT_SUPPR_IMPOSSIBLE','Supression Interdite');
define ( 'GTT_IMPOSSIBLE_SUPPR_CAT',GTT_SUPPR_IMPOSSIBLE.' : '.'Supprimez d\'abord la liste des projets inclus');
define ( 'GTT_IMPOSSIBLE_SUPPR_PROJ',GTT_SUPPR_IMPOSSIBLE.' : '.'Supprimez d\'abord la liste de taches');
define ( 'GTT_IMPOSSIBLE_SUPPR_MOTIF', GTT_SUPPR_IMPOSSIBLE.' : '.'Motif d\'absence utilisé');
define ( 'GTT_IMPOSSIBLE_SUPPR_STATUT',GTT_SUPPR_IMPOSSIBLE.' : '.'Statut utilisé');
define ( 'GTT_ERREUR_CHANGEMENT_CONGES', 'Impossible de changer le type de congé pour la date du : ');
// +----------------------------------------------------------------------------+
 
// +----------------------------------------------------------------------------+
// Mise en forme formulaire
 
define ( 'GTT_CHAMPS_OBLIGATOIRE', 'champs obligatoires');
 
 
define ( 'GESTION_GESTIONDEPOSTE_L', 'Gestion de Poste' );
define ( 'GESTION_DATE_L', 'Date' );
define ( 'GESTION_BIENVENU_L', 'Bienvenu' );
 
define ( 'GESTION_DUREE_L', 'Durée' );
define ( 'GESTION_FAIT_TRAVAIL_L', ', vous avez entré comme donnée pour le' );
define ( 'GESTION_PROJET_L', 'Projet' );
define ( 'GESTION_PROJETS_L', 'Projets' );
define ( 'GESTION_UTILISATEUR_L' , 'Utilisateur' );
define ( 'GESTION_STATUT_L' , 'Statut' );
define ( 'GESTION_CATEGORIE_L' , 'Categorie' );
define ( 'GESTION_MOTIF_L' , 'Motif Absence' );
define ( 'GESTION_FRAIS_L', 'Frais' );
define ( 'GESTION_TACHES_L','Tâches');
define ( 'GESTION_RECOMMENCER_L', 'Recommencer' );
define ( 'GESTION_ACCEPTER_L', 'Accepter');
 
 
define ( 'GESTION_ERREUR_L', 'ERREUR DE SAISI' );
define ( 'GESTION_ERREUR2_L' , 'ERREUR DANS LE CHOIX DES JOURS. UNE DES DATES CHOISIT N\'EXISTE PAS!' );
define ( 'GESTION_ABSCENCE_L', 'Entrez votre période d\'absence et son motif &nbsp :' );
//define ( 'GESTION_MOTIF_L', 'motif :');
define ( 'GESTION_DU_L', 'Du' );
define ( 'GESTION_AU_L', 'au' );
define ( 'GESTION_RETOUR_L', 'Retour' );
define ( 'GESTION_AUJOURDHUI_L', 'Aujourd\'hui' );
define ( 'GESTION_MOISDU_L', 'Mois du' );
define ( 'GESTION_DIM_A', 'Dim' );
define ( 'GESTION_DIM_L', 'Dimanche' );
define ( 'GESTION_LUN_A', 'Lun' );
define ( 'GESTION_LUN_L', 'Lundi' );
define ( 'GESTION_MAR_A', 'Mar' );
define ( 'GESTION_MAR_L', 'Mardi' );
define ( 'GESTION_MER_A', 'Mer' );
define ( 'GESTION_MER_L', 'Mercredi' );
define ( 'GESTION_JEU_A', 'Jeu' );
define ( 'GESTION_JEU_L', 'Jeudi' );
define ( 'GESTION_VEN_A', 'Ven' );
define ( 'GESTION_VEN_L', 'Vendredi' );
define ( 'GESTION_SAM_A', 'Sam' );
define ( 'GESTION_SAM_L', 'Samedi' );
 
define ( 'GESTION_JOUR_L', 'Jour' );
define ( 'GESTION_MOIS_L', 'Mois' );
define ( 'GESTION_ANNEE_L', 'Annee' );
define ( 'GESTION_RECAPITULATIF_TEXTE_L', ', voici les données concernant le temps passé par projet pour la date indiqué. '."\n".'<br />Date : ' );
 
 
define ( 'GESTION_GRAPH_MOIS_L' , 'Temps par projet pour le mois du ' );
define ( 'GESTION_GRAPH_JOUR_L' , 'Temps par projet pour le ' );
define ( 'GESTION_GRAPH_ANNEE_L' , 'Temps par projet pour l\'annee ' );
define ( 'GESTION_FEUILLEMOIS_TEXTE_L' , 'Feuille recapitulative pour le mois du ' );
 
define ( 'GESTION_ACTIVITE_L' , 'Activité' );
define ( 'GESTION_NOM_L' , 'Nom' );
define ( 'GESTION_LIBELLE_L', 'Libelle');
define ( 'GESTION_PRENOM_L' , 'Prenom' );
 
define ( 'GESTION_ERREUR_PASSWORD_L' , 'ERREUR : vous n\'avez pas entré deux fois le même mot de passe' );
define ( 'GESTION_CONGES_INIT_L' , 'Congés payés initiaux' );
define ( 'GESTION_HEURESINIT_L' , 'Heures supplémentaires initiales' );
 
 
 
define ( 'GESTION_ADMIN_UTILISATEUR_L' , 'Administration des utilisateurs' );
define ( 'GESTION_ADMIN_STATUT_L' , 'Administration des statuts' );
define ( 'GESTION_ADMIN_PROJET_L' , 'Administration des projets' );
define ( 'GESTION_ADMIN_CATEGORIE_L' , 'Administration des catégorie' );
define ( 'GESTION_ADMIN_MOTIF_L' , 'Administration des motifs d\'absence' );
define ( 'GESTION_SUPPRIMER_STATUT_L' , 'Supprimer un statut' );
define ( 'GESTION_SUPPRIMER_UTILISATEUR_L' , 'Supprimer un utilisateur' );
define ( 'GESTION_AJOUTER_UTILISATEUR_L' , 'Ajouter un utilisateur' );
define ( 'GESTION_EDITER_UTILISATEUR_L', 'Editer Utilisateur');
define ( 'GESTION_MODIFIER_UTILISATEUR_L', 'Modifier données utilisateur ');
define ( 'GESTION_AJOUTER_STATUT_L' , 'Ajouter un statut' );
define ( 'GESTION_SUPPRIMER_PROJET_L' , 'Supprimer un projet' );
define ( 'GESTION_AJOUTER_PROJET_L' , 'Ajouter un projet' );
define ( 'GESTION_DESCRIPTION_L' , 'Description' );
define ( 'GESTION_DATE_DEB_PROJET_L', 'Date de début prévue');
define ( 'GESTION_DUREE_PROJET_L', 'Nombre de jours prévus');
define ( 'GESTION_AVANCEMENT_PROJET_L','Pourcentage d\'avancement');
define ( 'GESTION_SUPPRIMER_CATEGORIE_L' , 'Supprimer une catégorie' );
define ( 'GESTION_AJOUTER_CATEGORIE_L' , 'Ajouter une catégorie' );
define ( 'GESTION_SUPPRIMER_CONDITION_L' , 'Supprimer un motif d\'absence' );
define ( 'GESTION_AJOUTER_CONDITION_L' , 'Ajouter un motif d\'absence' );
define ( 'GESTION_QUESTION_RTT_L' , 'Ce motif d\'absence supprime des heures de travail?' );
define ( 'GESTION_EDITER_PREFERENCES_L','Editer Preferences');
define ( 'GESTION_MES_PROJETS_L','Mes Projets');
define ( 'GESTION_HEURES_RESTANTES_L' , 'Heures restantes' );
define ( 'GESTION_CONSEILS_PREFERENCES', 'Cochez/Decochez les projets que vous souhaitez appara&icirc;tre/enlever de votre liste de projets');
 
 
 
define ( 'GESTION_HEURES_TRAVAIL_L' , ' heures de travail' );
define ( 'GESTION_HEURE_TRAVAIL_L' , ' heure de travail' );
define ( 'GESTION_MOISPRECEDENT_L' , 'Mois précédent' );
define ( 'GESTION_MOISSUIVANT_L' , 'Mois suivant' );
define ( 'GESTION_LEGENDE_L' , 'Legende des graphiques' );
define ( 'GESTION_SEMAINE_DU', ' Semaine du ');
define ( 'A ', ' :&agrave;');
 
 
 
 
 
 
 
 
define ( 'GESTION_TRAVAIL_L' , 'Travail' );
define ( 'GESTION_NON_REMPLI_L' , 'Jour non rempli' );
define ( 'GESTION_RTTJOUR_L' , ' jour' );
define ( 'GESTION_RTTJOURS_L' , ' jours' );
define ( 'GESTION_DESTINATAIRE_L' , '<table><tr><td valign=top>Dest.</td><td><div align=left>Daniel MATHIEU, Président\n<br />
Tela Botanica\n<br />Institut de Botanique\n<br />163, rue Auguste Broussonnet\n<br />34090 Montpellier</div></td></tr></table>');
define ( 'GESTION_EXP_L' , 'Exp.' );
define ( 'GESTION_FICHE_ABSCENCE_L' , 'Fiche d\'Absence' );
define ( 'GESTION_TEXTE_ABS1_L' , 'Monsieur le Président,' );
define ( 'GESTION_TEXTE_ABS2_L' , 'Je vous informe par la présente lettre de mon abscence du ' );
define ( 'GESTION_TEXTE_ABS3_L' , ' (inclus) au ' );
define ( 'GESTION_TEXTE_ABS4_L' , ' (inclus), soit ' );
define ( 'GESTION_TEXTE_ABS5_L' , ' jours' );
define ( 'GESTION_TEXTE_ABS6_L' , ' pris pour cause de ' );
define ( 'GESTION_TEXTE_ABS_CP_L' , ' pris sur mes congés payés.' );
define ( 'GESTION_TEXTE_ABS_JR_L' , ' pris sur mes jours à récupérer' );
define ( 'GESTION_TEXTE_FAIT_L' , 'Fait à Montpellier le' );
define ( 'GESTION_VISA_L' , 'Visa Tela Botanica\n <br> &nbsp \n <br> &nbsp \n <br> &nbsp \n <br> &nbsp \n <br> &nbsp \n' );
define ( 'GESTION_LUNDI_L' , 'lundi' );
define ( 'GESTION_MARDI_L' , 'mardi' );
define ( 'GESTION_MERCREDI_L' , 'mercredi' );
define ( 'GESTION_JEUDI_L' , 'jeudi' );
define ( 'GESTION_VENDREDI_L' , 'vendredi' );
define ( 'GESTION_SAMEDI_L' , 'samedi' );
define ( 'GESTION_DIMANCHE_L' , 'dimanche' );
 
 
define ( 'GESTION_TOTAL_HEURE_L' , 'Total d\'heures de travail sur l\'année' );
 
//nom de la taceh par defaut
define ('GESTION_NOM_TACHE_DEFAUT_L','g&eacute;n&eacute;ral');
define ('GTT_NOM_WEEK_END','week-end');
define ('GTT_NOM_TRAVAIL','travail');
define ('GTT_NOM_RECUP_PART','Récup part:1/2j');
define ('GTT_NOM_CONGES_PAYES','Congés Payés');
define ('GTT_NOM_RECUPERATION','Récupération');
define ('GTT_NOM_MALADIE','Maladie');
define ('GTT_NOM_GREVE','Grêve');
define ('GTT_NOM_FERIE','Ferié');
 
// +----------------------------------------------------------------------------+
/*
* $Log: gtt_langue_fr.inc.php,v $
* Revision 1.1 2005/02/22 12:07:13 jpm
* Ajout des fichiers les plus aboutis.
*
* Revision 2.3 2004/07/07 15:10:43 shaheen
* modif 1
*
* Revision 2.2 2003/10/15 08:03:04 jpm
* Changement d'un intitulé de menu.
*
* Revision 2.1 2003/10/14 08:14:05 jpm
* Modification des noms des menus.
*
* Revision 2.0 2003/09/16 12:58:27 jpm
* *** empty log message ***
*
* Revision 1.15 2003/09/16 12:03:50 jpm
* Ajout de la constante GTT_L_G_RECOMMENCER.
*
* Revision 1.14 2003/09/15 07:55:06 jpm
* Ajout de nouvelles constantes générales.
*
* Revision 1.13 2003/09/08 07:37:12 jpm
* Modification des noms de constantes de langue pour respecter le format Tela-Botanica.
*
* Revision 1.12 2003/09/03 12:34:21 jpm
* Ajout de $Log: gtt_langue_fr.inc.php,v $
* Ajout de Revision 1.1 2005/02/22 12:07:13 jpm
* Ajout de Ajout des fichiers les plus aboutis.
* Ajout de
* Ajout de Revision 2.3 2004/07/07 15:10:43 shaheen
* Ajout de modif 1
* Ajout de
* Ajout de Revision 2.2 2003/10/15 08:03:04 jpm
* Ajout de Changement d'un intitulé de menu.
* Ajout de
* Ajout de Revision 2.1 2003/10/14 08:14:05 jpm
* Ajout de Modification des noms des menus.
* Ajout de
* Ajout de Revision 2.0 2003/09/16 12:58:27 jpm
* Ajout de *** empty log message ***
* Ajout de
* Ajout de Revision 1.15 2003/09/16 12:03:50 jpm
* Ajout de Ajout de la constante GTT_L_G_RECOMMENCER.
* Ajout de
* Ajout de Revision 1.14 2003/09/15 07:55:06 jpm
* Ajout de Ajout de nouvelles constantes générales.
* Ajout de
* Ajout de Revision 1.13 2003/09/08 07:37:12 jpm
* Ajout de Modification des noms de constantes de langue pour respecter le format Tela-Botanica.
* Ajout de.
*
*/
// +----------------------------------------------------------------------------+
?>
Property changes:
Added: svn:executable
/tags/v1.0-Homere
New file
Property changes:
Added: svn:ignore
+.cache
+.externalToolBuilders
+.settings
+.projectOptions
+config.inc.php