Subversion Repositories Applications.gtt

Compare Revisions

No changes between revisions

Ignore whitespace Rev 191 → Rev 192

/branches/v1.3-critias/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>
<?php 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>
<?php 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; ?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/presentation/preferences.tpl.html
New file
0,0 → 1,99
<?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 (j)</th>
<!--<th>Durée financée (j)</th>-->
<th>Temps perso. passé (j)</th>
<th>Avancement (j)</th>
<th>Avancement (%)</th>
</tr>
</thead>
<tbody>
<?php foreach ($preferences as $categorie => $projets):?>
<tr class="categories"><th colspan="9"><?=$categorie;?></th></tr>
<?php $ligne = "impair"; ?>
<?php 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>-->
 
<!-- colonne "avancement personnel en jours" -->
<td>
<?= ($projet['tpp'] === null ? '0' : ($projet['tpp'] == 0 ? 'moins de 1j' : $projet['tpp'])) ?>
<?php
// pourcentage de temps sur ce projet p/r au temps total passé par l'équipe
$ptp = floor((empty($projet['tpp']) ? 0 : (($projet['tpp'] * 100) / $projet['avc'])));
?>
(<?= $ptp ?> %)
</td>
 
<!-- colonne "avancement en jours" -->
<?php
// calculs utiles pour la suite
$pourcentageEffectue = 0;
$pourcentageEnTrop = 0;
$joursEnTrop = $projet['avc'] - $projet['dupr'];
if ($projet['dupr'] > 0) {
$pourcentageEffectue = round(($projet['avc'] / $projet['dupr']) * 100);
$pourcentageEnTrop = round((($joursEnTrop) / $projet['dupr']) * 100);
}
?>
<?php if ($projet['avc'] > ($projet['dupr'] * 1.05)): ?>
<!-- on dépasse de 5%, alerte ! -->
<td class="pr_av_j bg-alerte" title="<?= $joursEnTrop ?> jours ont été accordés au delà des prévisions">
<?php else: ?>
<td class="pr_av_j">
<?php endif; ?>
<?= $projet['avc'] ?> / <?= $projet['dupr'] ?>
</td>
 
<!-- colonne "avancement en %" -->
<td class="pr_av" title="<?= $pourcentageEffectue ?>%">
<div class="barre-avancement-ext">
<div class="barre-avancement-int" style="width:<?= min(100, $pourcentageEffectue) ?>px;">
</div>
</div>
<!--<?php if (!empty($projet['av'])) : ?>
<img height="10"
width="<?=min(100, $projet['av']);?>"
title="pipi <?=$projet['av'];?> %"
src="presentation/images/pixels/avancement.png"
style="cursor:help;padding-right:<?=(100 - $projet['av']);?>px;border:1px solid #DDD;"
alt="<?=$projet['av'];?> %" />
<?php else : ?>
<img height="10"
width="100"
style="cursor:help;border:1px solid #DDD;"
src="presentation/images/pixels/vide.png"
title="caca <?=$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; ?>
/branches/v1.3-critias/presentation/images/pixels/avancement.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/presentation/images/pixels/avancement.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/presentation/images/pixels/vide.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/presentation/images/pixels/vide.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/presentation/images/favicones/gtt.ico
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/presentation/images/favicones/gtt.ico
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/presentation/images/favicones/gtt.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/presentation/images/favicones/gtt.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/presentation/images/icones/lien_externe.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/presentation/images/icones/lien_externe.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/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; ?>
/branches/v1.3-critias/presentation/identite.tpl.html
New file
0,0 → 1,19
<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é par jour (pour un temps plein)">Temps travail</dt>
<dd><?=$tps_w;?> h. par j.</dd>
<!-- Nous ne l'affichons pas tant que nous ne le gérons pas mieux et automatiquement
<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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/presentation/gestion.tpl.html
New file
0,0 → 1,83
<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) : ?>
<?php foreach ($preferences as $categorie => $projets):?>
<tr>
<td class="categorie"><?=$categorie;?></td>
<?php foreach ($elements[$s] as $num => $jour) : ?>
<td class="categorie_total pr" data-num-jour="<?=$num;?>"><?=$categorie_totaux[$categorie][$num];?></td>
<?php endforeach; ?>
</tr>
<?php 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;?>" class="pr" name="pr:<?=$projet['id'];?>:<?=$num;?>"
value="<?=$projet['date'][$num];?>" type="text" data-num-jour="<?=$num;?>"/>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
<?php endif;?>
<tr>
<td class="categorie">Journées d'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'];?>">
<?php if ($tab_ab_jours[$num]['duree_defaut'] != 0) : ?>
<input id="ab:<?=$ab_id;?>:<?=$num;?>" class="ab" name="ab:<?=$num;?>"
value="<?=$ab_id;?>:<?=($tab_ab_jours[$num]['duree'] != '') ? $tab_ab_jours[$num]['duree'] : $tab_ab_jours[$num]['duree_defaut'];?>" type="checkbox"
<?=(!empty($tab_ab_jours[$num]['duree'])) ? 'checked="checked"' : '' ?>
data-num-jour="<?=$num;?>"
data-ab-id="<?=$ab_id;?>"
data-duree-defaut="<?=$tab_ab_jours[$num]['duree_defaut'];?>"/>
<?php endif; ?>
</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>
<?php endif;?>
</div>
/branches/v1.3-critias/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;?>
<?php 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'];?>
 
<?php 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; ?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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;?>
 
<?php 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'];?>
 
<?php 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;?>
/branches/v1.3-critias/presentation/principal.tpl.html
New file
0,0 → 1,52
<!DOCTYPE html>
 
<html lang="fr">
<head>
<title><?=$titre;?></title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<!-- 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="http://www.tela-botanica.org/commun/jquery/1.9.1/jquery-1.9.1.min.js"></script>
<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>
</div>
</div>
</body>
</html>
/branches/v1.3-critias/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>
<?php 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>
<?php 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; ?>
/branches/v1.3-critias/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">Administrateur :</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>
/branches/v1.3-critias/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;}
/branches/v1.3-critias/presentation/styles/emeraude/emeraude.css
New file
0,0 → 1,235
/*
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, .absence_titre {
font-weight:bold;
width:350px;
text-align:left !important;
padding-left:30px;}
.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%;
text-align:left;
padding-left:5px;}
#preferences .pr_de {
font-size:0.8em;
text-align:left;}
table#ut_tdt{width:50%;}
/branches/v1.3-critias/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
/branches/v1.3-critias/presentation/styles/emeraude/images/a1.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/presentation/styles/emeraude/images/a1.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/presentation/styles/emeraude/images/a2.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/presentation/styles/emeraude/images/a2.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/presentation/styles/emeraude/images/a3.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/presentation/styles/emeraude/images/a3.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/presentation/styles/emeraude/images/a4.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/presentation/styles/emeraude/images/a4.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/presentation/styles/emeraude/images/a5.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/presentation/styles/emeraude/images/a5.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/presentation/styles/emeraude/images/help_view_16x16.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/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
/branches/v1.3-critias/presentation/styles/disposition.css
New file
0,0 → 1,98
@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}
 
/* codes couleurs */
.bg-alerte {
background-color: #F3B04E;
}
 
/* barre d'avancement */
.barre-avancement-ext {
display: inline-block;
height: 10px;
width: 100px;
border: solid #ddd 1px;
background-color: white;
text-align: left;
}
 
.barre-avancement-int {
height: 10px;
background-color: #409F40;
}
/branches/v1.3-critias/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>
/branches/v1.3-critias/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="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="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>
/branches/v1.3-critias/presentation/scripts/commun.js
New file
0,0 → 1,78
// 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.
};
}
}
}
 
function caseACocherUnique() {
$('input.ab').on('click', function(){
var id = $(this).attr('id'),
name = $(this).attr('name'),
numJour = $(this).attr('data-num-jour'),
abId = $(this).attr('data-ab-id'),
dureeDefaut = $(this).attr('data-duree-defaut'),
checked = $(this).is(':checked');
if (checked) {
$(this).val(abId + ':' + dureeDefaut);
} else {
$(this).val(abId + ':0');
}
 
// Nous forçons une seul case cochable
$('input.ab[name="'+name+'"]:checked').each(function() {
if ($(this).attr('id') != id) {
$(this).removeAttr('checked');
}
});
// Mise à zéro des projets du jour
$('input.pr[data-num-jour="'+numJour+'"]').each(function() {
if (checked) {
if ($(this).attr('value') != '') {
$(this).attr('value', 0);
}
$(this).attr('disabled', 'disabled');
} else {
$(this).removeAttr('disabled');
}
});
// Mise à zéro des catégories du jour
$('td.categorie_total.pr[data-num-jour="'+numJour+'"]').each(function() {
if (checked) {
$(this).text('');
} else {
$(this).removeAttr('disabled');
}
});
});
$('form#gestion').bind('submit', function() {
$(this).find(':input').removeAttr('disabled');
});
 
// Nous rendons par défaut les champs projets inactifs pour chaque jour d'abscence
$('input.ab:checked').each(function() {
var numJour = $(this).attr('data-num-jour');
$('input.pr[data-num-jour="'+numJour+'"]').each(function() {
$(this).attr('disabled', 'disabled');
});
});
}
 
$(document).ready(function() {
ouvrirLienExterne();
caseACocherUnique();
});
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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)
{
}
}
?>
/branches/v1.3-critias/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);
}
}
?>
/branches/v1.3-critias/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;
}
}
}
}
}
?>
/branches/v1.3-critias/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.']';
}
}
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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;
}
}
}
}
}
?>
/branches/v1.3-critias/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);
}
 
}
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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);
}
}
?>
/branches/v1.3-critias/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;
}
}
}
?>
/branches/v1.3-critias/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();
}
}
}
?>
/branches/v1.3-critias/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();
}
}
}
}
}
?>
/branches/v1.3-critias/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;
}
}
}
}
}
?>
/branches/v1.3-critias/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;
}
}
}
}
}
?>
/branches/v1.3-critias/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);
}
}
?>
/branches/v1.3-critias/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.
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>'; ?>
/branches/v1.3-critias/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
}
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>' );
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>'; ?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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
}
?>
/branches/v1.3-critias/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>' );
?>
/branches/v1.3-critias/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;
}
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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()));
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>';
}
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>' );
?>
/branches/v1.3-critias/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>' );
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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 />';
}
?>
/branches/v1.3-critias/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;
}
?>
/branches/v1.3-critias/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>';
}
?>
/branches/v1.3-critias/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()));
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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 />';
}
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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));
}
}
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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();
}
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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
/branches/v1.3-critias/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());
}
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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());
}
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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;
}
}
}
}
}
?>
/branches/v1.3-critias/bibliotheque/pear/System.php
New file
0,0 → 1,622
<?php
/**
* File/Directory manipulation
*
* PHP versions 4 and 5
*
* @category pear
* @package System
* @author Tomas V.V.Cox <cox@idecnet.com>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* base class
*/
require_once 'PEAR.php';
require_once 'Console/Getopt.php';
 
$GLOBALS['_System_temp_files'] = array();
 
/**
* System offers cross plattform compatible system functions
*
* Static functions for different operations. Should work under
* Unix and Windows. The names and usage has been taken from its respectively
* GNU commands. The functions will return (bool) false on error and will
* trigger the error with the PHP trigger_error() function (you can silence
* the error by prefixing a '@' sign after the function call, but this
* is not recommended practice. Instead use an error handler with
* {@link set_error_handler()}).
*
* Documentation on this class you can find in:
* http://pear.php.net/manual/
*
* Example usage:
* if (!@System::rm('-r file1 dir1')) {
* print "could not delete file1 or dir1";
* }
*
* In case you need to to pass file names with spaces,
* pass the params as an array:
*
* System::rm(array('-r', $file1, $dir1));
*
* @category pear
* @package System
* @author Tomas V.V. Cox <cox@idecnet.com>
* @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
* @static
*/
class System
{
/**
* returns the commandline arguments of a function
*
* @param string $argv the commandline
* @param string $short_options the allowed option short-tags
* @param string $long_options the allowed option long-tags
* @return array the given options and there values
*/
public static function _parseArgs($argv, $short_options, $long_options = null)
{
if (!is_array($argv) && $argv !== null) {
/*
// Quote all items that are a short option
$av = preg_split('/(\A| )--?[a-z0-9]+[ =]?((?<!\\\\)((,\s*)|((?<!,)\s+))?)/i', $argv, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
$offset = 0;
foreach ($av as $a) {
$b = trim($a[0]);
if ($b{0} == '"' || $b{0} == "'") {
continue;
}
 
$escape = escapeshellarg($b);
$pos = $a[1] + $offset;
$argv = substr_replace($argv, $escape, $pos, strlen($b));
$offset += 2;
}
*/
 
// Find all items, quoted or otherwise
preg_match_all("/(?:[\"'])(.*?)(?:['\"])|([^\s]+)/", $argv, $av);
$argv = $av[1];
foreach ($av[2] as $k => $a) {
if (empty($a)) {
continue;
}
$argv[$k] = trim($a) ;
}
}
 
return Console_Getopt::getopt2($argv, $short_options, $long_options);
}
 
/**
* Output errors with PHP trigger_error(). You can silence the errors
* with prefixing a "@" sign to the function call: @System::mkdir(..);
*
* @param mixed $error a PEAR error or a string with the error message
* @return bool false
*/
protected static function raiseError($error)
{
if (PEAR::isError($error)) {
$error = $error->getMessage();
}
trigger_error($error, E_USER_WARNING);
return false;
}
 
/**
* Creates a nested array representing the structure of a directory
*
* System::_dirToStruct('dir1', 0) =>
* Array
* (
* [dirs] => Array
* (
* [0] => dir1
* )
*
* [files] => Array
* (
* [0] => dir1/file2
* [1] => dir1/file3
* )
* )
* @param string $sPath Name of the directory
* @param integer $maxinst max. deep of the lookup
* @param integer $aktinst starting deep of the lookup
* @param bool $silent if true, do not emit errors.
* @return array the structure of the dir
*/
protected static function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false)
{
$struct = array('dirs' => array(), 'files' => array());
if (($dir = @opendir($sPath)) === false) {
if (!$silent) {
System::raiseError("Could not open dir $sPath");
}
return $struct; // XXX could not open error
}
 
$struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ?
$list = array();
while (false !== ($file = readdir($dir))) {
if ($file != '.' && $file != '..') {
$list[] = $file;
}
}
 
closedir($dir);
natsort($list);
if ($aktinst < $maxinst || $maxinst == 0) {
foreach ($list as $val) {
$path = $sPath . DIRECTORY_SEPARATOR . $val;
if (is_dir($path) && !is_link($path)) {
$tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent);
$struct = array_merge_recursive($struct, $tmp);
} else {
$struct['files'][] = $path;
}
}
}
 
return $struct;
}
 
/**
* Creates a nested array representing the structure of a directory and files
*
* @param array $files Array listing files and dirs
* @return array
* @static
* @see System::_dirToStruct()
*/
protected static function _multipleToStruct($files)
{
$struct = array('dirs' => array(), 'files' => array());
settype($files, 'array');
foreach ($files as $file) {
if (is_dir($file) && !is_link($file)) {
$tmp = System::_dirToStruct($file, 0);
$struct = array_merge_recursive($tmp, $struct);
} else {
if (!in_array($file, $struct['files'])) {
$struct['files'][] = $file;
}
}
}
return $struct;
}
 
/**
* The rm command for removing files.
* Supports multiple files and dirs and also recursive deletes
*
* @param string $args the arguments for rm
* @return mixed PEAR_Error or true for success
* @static
* @access public
*/
public static function rm($args)
{
$opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-)
if (PEAR::isError($opts)) {
return System::raiseError($opts);
}
foreach ($opts[0] as $opt) {
if ($opt[0] == 'r') {
$do_recursive = true;
}
}
$ret = true;
if (isset($do_recursive)) {
$struct = System::_multipleToStruct($opts[1]);
foreach ($struct['files'] as $file) {
if (!@unlink($file)) {
$ret = false;
}
}
 
rsort($struct['dirs']);
foreach ($struct['dirs'] as $dir) {
if (!@rmdir($dir)) {
$ret = false;
}
}
} else {
foreach ($opts[1] as $file) {
$delete = (is_dir($file)) ? 'rmdir' : 'unlink';
if (!@$delete($file)) {
$ret = false;
}
}
}
return $ret;
}
 
/**
* Make directories.
*
* The -p option will create parent directories
* @param string $args the name of the director(y|ies) to create
* @return bool True for success
*/
public static function mkDir($args)
{
$opts = System::_parseArgs($args, 'pm:');
if (PEAR::isError($opts)) {
return System::raiseError($opts);
}
 
$mode = 0777; // default mode
foreach ($opts[0] as $opt) {
if ($opt[0] == 'p') {
$create_parents = true;
} elseif ($opt[0] == 'm') {
// if the mode is clearly an octal number (starts with 0)
// convert it to decimal
if (strlen($opt[1]) && $opt[1]{0} == '0') {
$opt[1] = octdec($opt[1]);
} else {
// convert to int
$opt[1] += 0;
}
$mode = $opt[1];
}
}
 
$ret = true;
if (isset($create_parents)) {
foreach ($opts[1] as $dir) {
$dirstack = array();
while ((!file_exists($dir) || !is_dir($dir)) &&
$dir != DIRECTORY_SEPARATOR) {
array_unshift($dirstack, $dir);
$dir = dirname($dir);
}
 
while ($newdir = array_shift($dirstack)) {
if (!is_writeable(dirname($newdir))) {
$ret = false;
break;
}
 
if (!mkdir($newdir, $mode)) {
$ret = false;
}
}
}
} else {
foreach($opts[1] as $dir) {
if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) {
$ret = false;
}
}
}
 
return $ret;
}
 
/**
* Concatenate files
*
* Usage:
* 1) $var = System::cat('sample.txt test.txt');
* 2) System::cat('sample.txt test.txt > final.txt');
* 3) System::cat('sample.txt test.txt >> final.txt');
*
* Note: as the class use fopen, urls should work also (test that)
*
* @param string $args the arguments
* @return boolean true on success
*/
public static function &cat($args)
{
$ret = null;
$files = array();
if (!is_array($args)) {
$args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
}
 
$count_args = count($args);
for ($i = 0; $i < $count_args; $i++) {
if ($args[$i] == '>') {
$mode = 'wb';
$outputfile = $args[$i+1];
break;
} elseif ($args[$i] == '>>') {
$mode = 'ab+';
$outputfile = $args[$i+1];
break;
} else {
$files[] = $args[$i];
}
}
$outputfd = false;
if (isset($mode)) {
if (!$outputfd = fopen($outputfile, $mode)) {
$err = System::raiseError("Could not open $outputfile");
return $err;
}
$ret = true;
}
foreach ($files as $file) {
if (!$fd = fopen($file, 'r')) {
System::raiseError("Could not open $file");
continue;
}
while ($cont = fread($fd, 2048)) {
if (is_resource($outputfd)) {
fwrite($outputfd, $cont);
} else {
$ret .= $cont;
}
}
fclose($fd);
}
if (is_resource($outputfd)) {
fclose($outputfd);
}
return $ret;
}
 
/**
* Creates temporary files or directories. This function will remove
* the created files when the scripts finish its execution.
*
* Usage:
* 1) $tempfile = System::mktemp("prefix");
* 2) $tempdir = System::mktemp("-d prefix");
* 3) $tempfile = System::mktemp();
* 4) $tempfile = System::mktemp("-t /var/tmp prefix");
*
* prefix -> The string that will be prepended to the temp name
* (defaults to "tmp").
* -d -> A temporary dir will be created instead of a file.
* -t -> The target dir where the temporary (file|dir) will be created. If
* this param is missing by default the env vars TMP on Windows or
* TMPDIR in Unix will be used. If these vars are also missing
* c:\windows\temp or /tmp will be used.
*
* @param string $args The arguments
* @return mixed the full path of the created (file|dir) or false
* @see System::tmpdir()
*/
public static function mktemp($args = null)
{
static $first_time = true;
$opts = System::_parseArgs($args, 't:d');
if (PEAR::isError($opts)) {
return System::raiseError($opts);
}
 
foreach ($opts[0] as $opt) {
if ($opt[0] == 'd') {
$tmp_is_dir = true;
} elseif ($opt[0] == 't') {
$tmpdir = $opt[1];
}
}
 
$prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp';
if (!isset($tmpdir)) {
$tmpdir = System::tmpdir();
}
 
if (!System::mkDir(array('-p', $tmpdir))) {
return false;
}
 
$tmp = tempnam($tmpdir, $prefix);
if (isset($tmp_is_dir)) {
unlink($tmp); // be careful possible race condition here
if (!mkdir($tmp, 0700)) {
return System::raiseError("Unable to create temporary directory $tmpdir");
}
}
 
$GLOBALS['_System_temp_files'][] = $tmp;
if (isset($tmp_is_dir)) {
//$GLOBALS['_System_temp_files'][] = dirname($tmp);
}
 
if ($first_time) {
PEAR::registerShutdownFunc(array('System', '_removeTmpFiles'));
$first_time = false;
}
 
return $tmp;
}
 
/**
* Remove temporary files created my mkTemp. This function is executed
* at script shutdown time
*/
public static function _removeTmpFiles()
{
if (count($GLOBALS['_System_temp_files'])) {
$delete = $GLOBALS['_System_temp_files'];
array_unshift($delete, '-r');
System::rm($delete);
$GLOBALS['_System_temp_files'] = array();
}
}
 
/**
* Get the path of the temporal directory set in the system
* by looking in its environments variables.
* Note: php.ini-recommended removes the "E" from the variables_order setting,
* making unavaible the $_ENV array, that s why we do tests with _ENV
*
* @return string The temporary directory on the system
*/
public static function tmpdir()
{
if (OS_WINDOWS) {
if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) {
return $var;
}
if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) {
return $var;
}
if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) {
return $var;
}
if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) {
return $var;
}
return getenv('SystemRoot') . '\temp';
}
if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
return $var;
}
return realpath('/tmp');
}
 
/**
* The "which" command (show the full path of a command)
*
* @param string $program The command to search for
* @param mixed $fallback Value to return if $program is not found
*
* @return mixed A string with the full path or false if not found
* @author Stig Bakken <ssb@php.net>
*/
public static function which($program, $fallback = false)
{
// enforce API
if (!is_string($program) || '' == $program) {
return $fallback;
}
 
// full path given
if (basename($program) != $program) {
$path_elements[] = dirname($program);
$program = basename($program);
} else {
$path = getenv('PATH');
if (!$path) {
$path = getenv('Path'); // some OSes are just stupid enough to do this
}
 
$path_elements = explode(PATH_SEPARATOR, $path);
}
 
if (OS_WINDOWS) {
$exe_suffixes = getenv('PATHEXT')
? explode(PATH_SEPARATOR, getenv('PATHEXT'))
: array('.exe','.bat','.cmd','.com');
// allow passing a command.exe param
if (strpos($program, '.') !== false) {
array_unshift($exe_suffixes, '');
}
} else {
$exe_suffixes = array('');
}
 
foreach ($exe_suffixes as $suff) {
foreach ($path_elements as $dir) {
$file = $dir . DIRECTORY_SEPARATOR . $program . $suff;
if (is_executable($file)) {
return $file;
}
}
}
return $fallback;
}
 
/**
* The "find" command
*
* Usage:
*
* System::find($dir);
* System::find("$dir -type d");
* System::find("$dir -type f");
* System::find("$dir -name *.php");
* System::find("$dir -name *.php -name *.htm*");
* System::find("$dir -maxdepth 1");
*
* Params implmented:
* $dir -> Start the search at this directory
* -type d -> return only directories
* -type f -> return only files
* -maxdepth <n> -> max depth of recursion
* -name <pattern> -> search pattern (bash style). Multiple -name param allowed
*
* @param mixed Either array or string with the command line
* @return array Array of found files
*/
public static function find($args)
{
if (!is_array($args)) {
$args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
}
$dir = realpath(array_shift($args));
if (!$dir) {
return array();
}
$patterns = array();
$depth = 0;
$do_files = $do_dirs = true;
$args_count = count($args);
for ($i = 0; $i < $args_count; $i++) {
switch ($args[$i]) {
case '-type':
if (in_array($args[$i+1], array('d', 'f'))) {
if ($args[$i+1] == 'd') {
$do_files = false;
} else {
$do_dirs = false;
}
}
$i++;
break;
case '-name':
$name = preg_quote($args[$i+1], '#');
// our magic characters ? and * have just been escaped,
// so now we change the escaped versions to PCRE operators
$name = strtr($name, array('\?' => '.', '\*' => '.*'));
$patterns[] = '('.$name.')';
$i++;
break;
case '-maxdepth':
$depth = $args[$i+1];
break;
}
}
$path = System::_dirToStruct($dir, $depth, 0, true);
if ($do_files && $do_dirs) {
$files = array_merge($path['files'], $path['dirs']);
} elseif ($do_dirs) {
$files = $path['dirs'];
} else {
$files = $path['files'];
}
if (count($patterns)) {
$dsq = preg_quote(DIRECTORY_SEPARATOR, '#');
$pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#';
$ret = array();
$files_count = count($files);
for ($i = 0; $i < $files_count; $i++) {
// only search in the part of the file below the current directory
$filepart = basename($files[$i]);
if (preg_match($pattern, $filepart)) {
$ret[] = $files[$i];
}
}
return $ret;
}
return $files;
}
}
/branches/v1.3-critias/bibliotheque/pear/DB.php
New file
0,0 → 1,1504
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Database independent query interface
*
* PHP version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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()
*/
public static 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()
*/
public static 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 '"
. DB::getDSNString($dsn, true) . "'",
'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)) {
if (is_array($dsn)) {
$err->addUserInfo(DB::getDSNString($dsn, true));
} else {
$err->addUserInfo($dsn);
}
return $err;
}
 
return $obj;
}
 
// }}}
// {{{ apiVersion()
 
/**
* Return the DB API version
*
* @return string the DB API version number
*/
function apiVersion()
{
return '1.9.2';
}
 
// }}}
// {{{ 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
*/
public static function isError($value)
{
return is_object($value) && 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
*/
public static 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
*/
public static function isManip($query)
{
$manips = 'INSERT|UPDATE|DELETE|REPLACE|'
. 'CREATE|DROP|'
. 'LOAD DATA|SELECT .* INTO .* FROM|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
*/
public static 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
*/
public static 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 (strpos($proto_opts, ':') !== false) {
list($proto_opts, $parsed['port']) = explode(':', $proto_opts);
}
if ($parsed['protocol'] == 'tcp') {
$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;
}
 
// }}}
// {{{ getDSNString()
 
/**
* Returns the given DSN in a string format suitable for output.
*
* @param array|string the DSN to parse and format
* @param boolean true to hide the password, false to include it
* @return string
*/
public static function getDSNString($dsn, $hidePassword) {
/* Calling parseDSN will ensure that we have all the array elements
* defined, and means that we deal with strings and array in the same
* manner. */
$dsnArray = DB::parseDSN($dsn);
if ($hidePassword) {
$dsnArray['password'] = 'PASSWORD';
}
 
/* Protocol is special-cased, as using the default "tcp" along with an
* Oracle TNS connection string fails. */
if (is_string($dsn) && strpos($dsn, 'tcp') === false && $dsnArray['protocol'] == 'tcp') {
$dsnArray['protocol'] = false;
}
// Now we just have to construct the actual string. This is ugly.
$dsnString = $dsnArray['phptype'];
if ($dsnArray['dbsyntax']) {
$dsnString .= '('.$dsnArray['dbsyntax'].')';
}
$dsnString .= '://'
.$dsnArray['username']
.':'
.$dsnArray['password']
.'@'
.$dsnArray['protocol'];
if ($dsnArray['socket']) {
$dsnString .= '('.$dsnArray['socket'].')';
}
if ($dsnArray['protocol'] && $dsnArray['hostspec']) {
$dsnString .= '+';
}
$dsnString .= $dsnArray['hostspec'];
if ($dsnArray['port']) {
$dsnString .= ':'.$dsnArray['port'];
}
$dsnString .= '/'.$dsnArray['database'];
/* Option handling. Unfortunately, parseDSN simply places options into
* the top-level array, so we'll first get rid of the fields defined by
* DB and see what's left. */
unset($dsnArray['phptype'],
$dsnArray['dbsyntax'],
$dsnArray['username'],
$dsnArray['password'],
$dsnArray['protocol'],
$dsnArray['socket'],
$dsnArray['hostspec'],
$dsnArray['port'],
$dsnArray['database']
);
if (count($dsnArray) > 0) {
$dsnString .= '?';
$i = 0;
foreach ($dsnArray as $key => $value) {
if (++$i > 1) {
$dsnString .= '&';
}
$dsnString .= $key.'='.$value;
}
}
 
return $dsnString;
}
// }}}
}
 
// }}}
// {{{ 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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 __construct($code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
$level = E_USER_NOTICE, $debuginfo = null)
{
if (is_int($code)) {
parent::__construct('DB Error: ' . DB::errorMessage($code), $code,
$mode, $level, $debuginfo);
} else {
parent::__construct("DB Error: $code", DB_ERROR,
$mode, $level, $debuginfo);
}
}
 
/**
* Workaround to both avoid the "Redefining already defined constructor"
* PHP error and provide backward compatibility in case someone is calling
* DB_Error() dynamically
*/
public function __call($method, $arguments)
{
if ($method == 'DB_Error') {
return call_user_func_array(array($this, '__construct'), $arguments);
}
trigger_error(
'Call to undefined method DB_Error::' . $method . '()', E_USER_ERROR
);
}
// }}}
}
 
// }}}
// {{{ 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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 __construct(&$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 (is_null($rownum) && $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 (is_null($rownum) && $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++;
}
$count = $i;
} else {
$count = $this->dbh->numRows($this->result);
}
 
/* fbsql is checked for here because limit queries are implemented
* using a TOP() function, which results in fbsql_num_rows still
* returning the total number of rows that would have been returned,
* rather than the real number. As a result, we'll just do the limit
* calculations for fbsql in the same way as a database with emulated
* limits. Unfortunately, we can't just do this in DB_fbsql::numRows()
* because that only gets the result resource, rather than the full
* DB_Result object. */
if (($this->dbh->features['limit'] === 'emulate'
&& $this->limit_from !== null)
|| $this->dbh->phptype == 'fbsql') {
$limit_count = is_null($this->limit_count) ? $count : $this->limit_count;
if ($count < $this->limit_from) {
$count = 0;
} elseif ($count < ($this->limit_from + $limit_count)) {
$count -= $this->limit_from;
} else {
$count = $limit_count;
}
}
 
return $count;
}
 
// }}}
// {{{ 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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 __construct(&$arr)
{
foreach ($arr as $key => $value) {
$this->$key = &$arr[$key];
}
}
 
// }}}
}
 
// }}}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR.php
New file
0,0 → 1,1112
<?php
/**
* PEAR, the PHP Extension and Application Repository
*
* PEAR class and PEAR_Error class
*
* PHP versions 4 and 5
*
* @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-2010 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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);
/**#@-*/
 
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
}
 
$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://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
{
/**
* 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();
 
/**
* List of methods that can be called both statically and non-statically.
* @var array
*/
protected static $bivalentMethods = array(
'setErrorHandling' => true,
'raiseError' => true,
'throwError' => true,
'pushErrorHandling' => true,
'popErrorHandling' => true,
);
 
/**
* 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 __construct($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);
}
}
}
 
/**
* Only here for backwards compatibility.
* E.g. Archive_Tar calls $this->PEAR() in its constructor.
*
* @param string $error_class Which class to use for error objects,
* defaults to PEAR_Error.
*/
public function PEAR($error_class = null)
{
self::__construct($error_class);
}
 
/**
* 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)));
}
}
 
public function __call($method, $arguments)
{
if (!isset(self::$bivalentMethods[$method])) {
trigger_error(
'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR
);
}
return call_user_func_array(
array(get_class(), '_' . $method),
array_merge(array($this), $arguments)
);
}
 
public static function __callStatic($method, $arguments)
{
if (!isset(self::$bivalentMethods[$method])) {
trigger_error(
'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR
);
}
return call_user_func_array(
array(get_class(), '_' . $method),
array_merge(array(null), $arguments)
);
}
 
/**
* 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!
*
* @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.
*/
public static 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];
}
 
/**
* Use this function to register a shutdown method for static
* classes.
*
* @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
*/
public static 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);
}
 
/**
* 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
*
* @return bool true if parameter is an error
*/
public static function isError($data, $code = null)
{
if (!is_a($data, 'PEAR_Error')) {
return false;
}
 
if (is_null($code)) {
return true;
} elseif (is_string($code)) {
return $data->getMessage() == $code;
}
 
return $data->getCode() == $code;
}
 
/**
* 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 object $object
* Object the method was called on (non-static mode)
*
* @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
*/
protected static function _setErrorHandling(
$object, $mode = null, $options = null
) {
if ($object !== null) {
$setmode = &$object->_default_error_mode;
$setoptions = &$object->_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;
}
}
 
/**
* 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 count($this->_expected_errors);
}
 
/**
* 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);
}
 
/**
* 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;
}
 
/**
* 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) {
$deleted = $this->_checkDelExpect($error) ? true : 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;
}
 
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
}
 
// $error_code is empty
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
}
 
/**
* 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.
*
* @return object a PEAR error object
* @see PEAR::setErrorHandling
* @since PHP 4.0.5
*/
protected static function _raiseError($object,
$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 (
$object !== null &&
isset($object->_expected_errors) &&
count($object->_expected_errors) > 0 &&
count($exp = end($object->_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 ($object !== null && isset($object->_default_error_mode)) {
$mode = $object->_default_error_mode;
$options = $object->_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 ($object !== null && isset($object->_error_class)) {
$ec = $object->_error_class;
} else {
$ec = 'PEAR_Error';
}
 
if ($skipmsg) {
$a = new $ec($code, $mode, $options, $userinfo);
} else {
$a = new $ec($message, $code, $mode, $options, $userinfo);
}
 
return $a;
}
 
/**
* Simpler form of raiseError with fewer options. In most cases
* message, code and userinfo are enough.
*
* @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 string $userinfo If you need to pass along for example debug
* information, this parameter is meant for that.
*
* @return object a PEAR error object
* @see PEAR::raiseError
*/
protected static function _throwError($object, $message = null, $code = null, $userinfo = null)
{
if ($object !== null) {
$a = &$object->raiseError($message, $code, null, null, $userinfo);
return $a;
}
 
$a = &PEAR::raiseError($message, $code, null, null, $userinfo);
return $a;
}
 
public static 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;
}
 
public static 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;
}
 
/**
* 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
*/
protected static function _pushErrorHandling($object, $mode, $options = null)
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
if ($object !== null) {
$def_mode = &$object->_default_error_mode;
$def_options = &$object->_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 ($object !== null) {
$object->setErrorHandling($mode, $options);
} else {
PEAR::setErrorHandling($mode, $options);
}
$stack[] = array($mode, $options);
return true;
}
 
/**
* Pop the last error handler used
*
* @return bool Always true
*
* @see PEAR::pushErrorHandling
*/
protected static function _popErrorHandling($object)
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
array_pop($stack);
list($mode, $options) = $stack[sizeof($stack) - 1];
array_pop($stack);
if ($object !== null) {
$object->setErrorHandling($mode, $options);
} else {
PEAR::setErrorHandling($mode, $options);
}
return true;
}
 
/**
* OS independent 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
*/
public static function loadExtension($ext)
{
if (extension_loaded($ext)) {
return true;
}
 
// if either returns true dl() will produce a FATAL error, stop that
if (
function_exists('dl') === false ||
ini_get('enable_dl') != 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);
}
}
 
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);
 
$destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
 
if ($destructLifoExists) {
$_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 (
isset($GLOBALS['_PEAR_shutdown_funcs']) &&
is_array($GLOBALS['_PEAR_shutdown_funcs']) &&
!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://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
{
var $error_message_prefix = '';
var $mode = PEAR_ERROR_RETURN;
var $level = E_USER_NOTICE;
var $code = -1;
var $message = '';
var $userinfo = '';
var $backtrace = null;
 
/**
* 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 __construct($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;
 
$skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
 
if (!$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 && 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);');
}
}
 
/**
* Only here for backwards compatibility.
*
* Class "Cache_Error" still uses it, among others.
*
* @param string $message Message
* @param int $code Error code
* @param int $mode Error mode
* @param mixed $options See __construct()
* @param string $userinfo Additional user/debug info
*/
public function PEAR_Error(
$message = 'unknown error', $code = null, $mode = null,
$options = null, $userinfo = null
) {
self::__construct($message, $code, $mode, $options, $userinfo);
}
 
/**
* Get the error mode from an error object.
*
* @return int error mode
* @access public
*/
function getMode()
{
return $this->mode;
}
 
/**
* Get the callback function/method from an error object.
*
* @return mixed callback function or object/method array
* @access public
*/
function getCallback()
{
return $this->callback;
}
 
/**
* Get the error message from an error object.
*
* @return string full error message
* @access public
*/
function getMessage()
{
return ($this->error_message_prefix . $this->message);
}
 
/**
* Get error code from an error object
*
* @return int error code
* @access public
*/
function getCode()
{
return $this->code;
}
 
/**
* Get the name of this error/exception.
*
* @return string error/exception name (type)
* @access public
*/
function getType()
{
return get_class($this);
}
 
/**
* Get additional user-supplied information.
*
* @return string user-supplied information
* @access public
*/
function getUserInfo()
{
return $this->userinfo;
}
 
/**
* Get additional debug information supplied by the application.
*
* @return string debug information
* @access public
*/
function getDebugInfo()
{
return $this->getUserInfo();
}
 
/**
* 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];
}
 
function addUserInfo($info)
{
if (empty($this->userinfo)) {
$this->userinfo = $info;
} else {
$this->userinfo .= " ** $info";
}
}
 
function __toString()
{
return $this->getMessage();
}
 
/**
* 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:
*/
/branches/v1.3-critias/bibliotheque/pear/Auth/Auth.php
New file
0,0 → 1,5
<?php
 
include_once('Auth.php');
 
?>
/branches/v1.3-critias/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;
}
 
// }}}
 
}
?>
/branches/v1.3-critias/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;
}
}
 
?>
/branches/v1.3-critias/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;
}
}
}
?>
/branches/v1.3-critias/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;
}
 
?>
/branches/v1.3-critias/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;
}
 
// }}}
}
?>
/branches/v1.3-critias/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 />");
}
}
}
 
?>
/branches/v1.3-critias/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;
}
 
// }}}
}
?>
/branches/v1.3-critias/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;
}
}
 
// }}}
}
?>
/branches/v1.3-critias/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;
}
}
}
?>
/branches/v1.3-critias/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;
}
 
// }}}
 
}
?>
/branches/v1.3-critias/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;
}
}
 
// }}}
}
?>
/branches/v1.3-critias/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;
}
}
}
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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;
}
 
// }}}
}
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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);
}
}
}
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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);
}
}
?>
/branches/v1.3-critias/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);
}
}
?>
/branches/v1.3-critias/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:
*/
?>
/branches/v1.3-critias/bibliotheque/pear/OS/Guess.php
New file
0,0 → 1,337
<?php
/**
* The OS_Guess class
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Gregory Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since PEAR 0.1
*/
 
// {{{ uname examples
 
// php_uname() without args returns the same as 'uname -a', or a PHP-custom
// string for Windows.
// PHP versions prior to 4.3 return the uname of the host where PHP was built,
// as of 4.3 it returns the uname of the host running the PHP code.
//
// PC RedHat Linux 7.1:
// Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
//
// PC Debian Potato:
// Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown
//
// PC FreeBSD 3.3:
// FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000 root@example.com:/usr/src/sys/compile/CONFIG i386
//
// PC FreeBSD 4.3:
// FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001 root@example.com:/usr/src/sys/compile/CONFIG i386
//
// PC FreeBSD 4.5:
// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb 6 23:59:23 CET 2002 root@example.com:/usr/src/sys/compile/CONFIG i386
//
// PC FreeBSD 4.5 w/uname from GNU shellutils:
// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown
//
// HP 9000/712 HP-UX 10:
// HP-UX iq B.10.10 A 9000/712 2008429113 two-user license
//
// HP 9000/712 HP-UX 10 w/uname from GNU shellutils:
// HP-UX host B.10.10 A 9000/712 unknown
//
// IBM RS6000/550 AIX 4.3:
// AIX host 3 4 000003531C00
//
// AIX 4.3 w/uname from GNU shellutils:
// AIX host 3 4 000003531C00 unknown
//
// SGI Onyx IRIX 6.5 w/uname from GNU shellutils:
// IRIX64 host 6.5 01091820 IP19 mips
//
// SGI Onyx IRIX 6.5:
// IRIX64 host 6.5 01091820 IP19
//
// SparcStation 20 Solaris 8 w/uname from GNU shellutils:
// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc
//
// SparcStation 20 Solaris 8:
// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20
//
// Mac OS X (Darwin)
// Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug 5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC Power Macintosh
//
// Mac OS X early versions
//
 
// }}}
 
/* TODO:
* - define endianness, to allow matchSignature("bigend") etc.
*/
 
/**
* Retrieves information about the current operating system
*
* This class uses php_uname() to grok information about the current OS
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Gregory Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class OS_Guess
{
var $sysname;
var $nodename;
var $cpu;
var $release;
var $extra;
 
function __construct($uname = null)
{
list($this->sysname,
$this->release,
$this->cpu,
$this->extra,
$this->nodename) = $this->parseSignature($uname);
}
 
function parseSignature($uname = null)
{
static $sysmap = array(
'HP-UX' => 'hpux',
'IRIX64' => 'irix',
);
static $cpumap = array(
'i586' => 'i386',
'i686' => 'i386',
'ppc' => 'powerpc',
);
if ($uname === null) {
$uname = php_uname();
}
$parts = preg_split('/\s+/', trim($uname));
$n = count($parts);
 
$release = $machine = $cpu = '';
$sysname = $parts[0];
$nodename = $parts[1];
$cpu = $parts[$n-1];
$extra = '';
if ($cpu == 'unknown') {
$cpu = $parts[$n - 2];
}
 
switch ($sysname) {
case 'AIX' :
$release = "$parts[3].$parts[2]";
break;
case 'Windows' :
switch ($parts[1]) {
case '95/98':
$release = '9x';
break;
default:
$release = $parts[1];
break;
}
$cpu = 'i386';
break;
case 'Linux' :
$extra = $this->_detectGlibcVersion();
// use only the first two digits from the kernel version
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
break;
case 'Mac' :
$sysname = 'darwin';
$nodename = $parts[2];
$release = $parts[3];
if ($cpu == 'Macintosh') {
if ($parts[$n - 2] == 'Power') {
$cpu = 'powerpc';
}
}
break;
case 'Darwin' :
if ($cpu == 'Macintosh') {
if ($parts[$n - 2] == 'Power') {
$cpu = 'powerpc';
}
}
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
break;
default:
$release = preg_replace('/-.*/', '', $parts[2]);
break;
}
 
if (isset($sysmap[$sysname])) {
$sysname = $sysmap[$sysname];
} else {
$sysname = strtolower($sysname);
}
if (isset($cpumap[$cpu])) {
$cpu = $cpumap[$cpu];
}
return array($sysname, $release, $cpu, $extra, $nodename);
}
 
function _detectGlibcVersion()
{
static $glibc = false;
if ($glibc !== false) {
return $glibc; // no need to run this multiple times
}
$major = $minor = 0;
include_once "System.php";
// Use glibc's <features.h> header file to
// get major and minor version number:
if (@file_exists('/usr/include/features.h') &&
@is_readable('/usr/include/features.h')) {
if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) {
$features_file = fopen('/usr/include/features.h', 'rb');
while (!feof($features_file)) {
$line = fgets($features_file, 8192);
if (!$line || (strpos($line, '#define') === false)) {
continue;
}
if (strpos($line, '__GLIBC__')) {
// major version number #define __GLIBC__ version
$line = preg_split('/\s+/', $line);
$glibc_major = trim($line[2]);
if (isset($glibc_minor)) {
break;
}
continue;
}
 
if (strpos($line, '__GLIBC_MINOR__')) {
// got the minor version number
// #define __GLIBC_MINOR__ version
$line = preg_split('/\s+/', $line);
$glibc_minor = trim($line[2]);
if (isset($glibc_major)) {
break;
}
continue;
}
}
fclose($features_file);
if (!isset($glibc_major) || !isset($glibc_minor)) {
return $glibc = '';
}
return $glibc = 'glibc' . trim($glibc_major) . "." . trim($glibc_minor) ;
} // no cpp
 
$tmpfile = System::mktemp("glibctest");
$fp = fopen($tmpfile, "w");
fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n");
fclose($fp);
$cpp = popen("/usr/bin/cpp $tmpfile", "r");
while ($line = fgets($cpp, 1024)) {
if ($line{0} == '#' || trim($line) == '') {
continue;
}
 
if (list($major, $minor) = explode(' ', trim($line))) {
break;
}
}
pclose($cpp);
unlink($tmpfile);
} // features.h
 
if (!($major && $minor) && @is_link('/lib/libc.so.6')) {
// Let's try reading the libc.so.6 symlink
if (preg_match('/^libc-(.*)\.so$/', basename(readlink('/lib/libc.so.6')), $matches)) {
list($major, $minor) = explode('.', $matches[1]);
}
}
 
if (!($major && $minor)) {
return $glibc = '';
}
 
return $glibc = "glibc{$major}.{$minor}";
}
 
function getSignature()
{
if (empty($this->extra)) {
return "{$this->sysname}-{$this->release}-{$this->cpu}";
}
return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}";
}
 
function getSysname()
{
return $this->sysname;
}
 
function getNodename()
{
return $this->nodename;
}
 
function getCpu()
{
return $this->cpu;
}
 
function getRelease()
{
return $this->release;
}
 
function getExtra()
{
return $this->extra;
}
 
function matchSignature($match)
{
$fragments = is_array($match) ? $match : explode('-', $match);
$n = count($fragments);
$matches = 0;
if ($n > 0) {
$matches += $this->_matchFragment($fragments[0], $this->sysname);
}
if ($n > 1) {
$matches += $this->_matchFragment($fragments[1], $this->release);
}
if ($n > 2) {
$matches += $this->_matchFragment($fragments[2], $this->cpu);
}
if ($n > 3) {
$matches += $this->_matchFragment($fragments[3], $this->extra);
}
return ($matches == $n);
}
 
function _matchFragment($fragment, $value)
{
if (strcspn($fragment, '*?') < strlen($fragment)) {
$reg = '/^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '\\z/';
return preg_match($reg, $value);
}
return ($fragment == '*' || !strcasecmp($fragment, $value));
}
 
}
/*
* Local Variables:
* indent-tabs-mode: nil
* c-basic-offset: 4
* End:
*/
/branches/v1.3-critias/bibliotheque/pear/DB/ibase.php
New file
0,0 → 1,1082
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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,
// -902 => // Covers too many errors, need to use regex on msg
-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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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 = $this->_checkManip($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 is_resource($result) ? ibase_free_result($result) : false;
}
 
// }}}
// {{{ freeQuery()
 
function freeQuery($query)
{
return is_resource($query) ? ibase_free_query($query) : 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 (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);
 
if ($stmt === false) {
$stmt = $this->ibaseRaiseError();
} else {
$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] || $this->_next_query_manip) {
$this->_last_query_manip = true;
$this->_next_query_manip = false;
$tmp = DB_OK;
} else {
$this->_last_query_manip = false;
$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()
'/violation of [\w ]+ constraint/i'
=> DB_ERROR_CONSTRAINT,
'/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,
'/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,
'/feature is not supported/i'
=> DB_ERROR_NOT_CAPABLE,
);
}
 
$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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/storage.php
New file
0,0 → 1,506
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Provides an object interface to a table row
*
* PHP version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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 __construct($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()
{
$params = array();
$vars = array();
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:
*/
 
?>
/branches/v1.3-critias/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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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,
1356 => DB_ERROR_DIVZERO,
1451 => DB_ERROR_CONSTRAINT,
1452 => 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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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 = $this->_checkManip($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 is_resource($result) ? mysql_free_result($result) : false;
}
 
// }}}
// {{{ 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 ($this->_last_query_manip) {
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
* (WARNING: using names that require this is a REALLY BAD IDEA)
*
* WARNING: Older versions of 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_replace('`', '``', $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) || $this->_next_query_manip) {
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)) {
// Fix for bug #11580.
if ($this->_db) {
if (!@mysql_select_db($this->_db, $this->connection)) {
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
}
}
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @mysql_query("SELECT * FROM $result LIMIT 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->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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/ifx.php
New file
0,0 → 1,683
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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,
'-268' => DB_ERROR_CONSTRAINT,
'-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,
'-1202' => DB_ERROR_DIVZERO,
'-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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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 = $this->_checkManip($query);
$this->last_query = $query;
$this->affected = null;
if (preg_match('/(SELECT|EXECUTE)/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|EXECUTE)/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 ($this->_last_query_manip) {
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 is_resource($result) ? ifx_free_result($result) : false;
}
 
// }}}
// {{{ 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 (preg_match('/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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/pgsql.php
New file
0,0 → 1,1123
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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 = $this->_checkManip($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 whether queries produce affected rows, result or nothing.
*
* This logic was introduced in version 1.1 of the file by ssb,
* though the regex has been modified slightly since then.
*
* 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, WITH
*/
if ($ismanip) {
$this->affected = @pg_affected_rows($result);
return DB_OK;
} elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|FETCH|SHOW|WITH)\s/si',
$query))
{
$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;
}
 
// }}}
// {{{ quoteBoolean()
 
/**
* Formats a boolean value for use within a query in a locale-independent
* manner.
*
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteBoolean($boolean) {
return $boolean ? 'TRUE' : 'FALSE';
}
// }}}
// {{{ 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.
*
* @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('pg_escape_string')) {
/* This fixes an undocumented BC break in PHP 5.2.0 which changed
* the prototype of pg_escape_string. I'm not thrilled about having
* to sniff the PHP version, quite frankly, but it's the only way
* to deal with the problem. Revision 1.331.2.13.2.10 on
* php-src/ext/pgsql/pgsql.c (PHP_5_2 branch) is to blame, for the
* record. */
if (version_compare(PHP_VERSION, '5.2.0', '>=')) {
return pg_escape_string($this->connection, $str);
} else {
return pg_escape_string($str);
}
} else {
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 (!$native) {
$native = 'Database connection has been lost.';
$errno = DB_ERROR_CONNECT_FAILED;
}
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(
'/column .* (of relation .*)?does not exist/i'
=> DB_ERROR_NOSUCHFIELD,
'/(relation|sequence|table).*does not exist|class .* not found/i'
=> DB_ERROR_NOSUCHTABLE,
'/index .* does not exist/'
=> DB_ERROR_NOT_FOUND,
'/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);
 
// Check if there's a schema in $table_name and update things
// accordingly.
$from = 'pg_attribute f, pg_class tab, pg_type typ';
if (strpos($table_name, '.') !== false) {
$from .= ', pg_namespace nsp';
list($schema, $table) = explode('.', $table_name);
$tableWhere = "tab.relname = '$table' AND tab.relnamespace = nsp.oid AND nsp.nspname = '$schema'";
} else {
$tableWhere = "tab.relname = '$table_name'";
}
 
$result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef
FROM $from
WHERE tab.relname = typ.typname
AND typ.typrelid = f.attrelid
AND f.attname = '$field_name'
AND $tableWhere");
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 $from, pg_attrdef a
WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid
AND f.attrelid = a.adrelid AND f.attname = '$field_name'
AND $tableWhere 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 $from, pg_index i
WHERE tab.relname = typ.typname
AND typ.typrelid = f.attrelid
AND f.attrelid = i.indrelid
AND f.attname = '$field_name'
AND $tableWhere");
$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 'schema.views':
return "SELECT schemaname || '.' || viewname from pg_views WHERE schemaname"
. " NOT IN ('information_schema', 'pg_catalog')";
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;
}
}
 
// }}}
// {{{ _checkManip()
 
/**
* Checks if the given query is a manipulation query. This also takes into
* account the _next_query_manip flag and sets the _last_query_manip flag
* (and resets _next_query_manip) according to the result.
*
* @param string The query to check.
*
* @return boolean true if the query is a manipulation query, false
* otherwise
*
* @access protected
*/
function _checkManip($query)
{
return (preg_match('/^\s*(SAVEPOINT|RELEASE)\s+/i', $query)
|| parent::_checkManip($query));
}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/sybase.php
New file
0,0 → 1,942
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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 = $this->_checkManip($query);
$this->last_query = $query;
if ($this->_db && !@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 is_resource($result) ? sybase_free_result($result) : false;
}
 
// }}}
// {{{ 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 ($this->_last_query_manip) {
$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 ($this->_db && !@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));
}
 
// }}}
// {{{ quoteFloat()
 
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ 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 && !@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 ($this->_db && !@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;
// PHP 5.2+ prepends the function name to $php_errormsg, so we need
// this hack to work around it, per bug #9599.
$errormsg = preg_replace('/^sybase[a-z_]+\(\): /', '', $errormsg);
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,
'/Divide by zero/i'
=> DB_ERROR_DIVZERO,
);
}
 
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 ($this->_db && !@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;
 
/* We're running sp_helpindex directly because it doesn't exist in
* older versions of ASE -- unfortunately, we can't just use
* DB::isError() because the user may be using callback error
* handling. */
$res = @sybase_query("sp_helpindex $table", $this->connection);
 
if ($res === false || $res === true) {
// Fake a valid response for BC reasons.
return '';
}
 
while (($val = sybase_fetch_assoc($res)) !== false) {
if (!isset($val['index_keys'])) {
/* No useful information returned. Break and be done with
* it, which preserves the pre-1.7.9 behaviour. */
break;
}
 
$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');
}
}
}
 
sybase_free_result($res);
 
}
 
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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/fbsql.php
New file
0,0 → 1,769
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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 ($this->_checkManip($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 is_resource($result) ? fbsql_free_result($result) : false;
}
 
// }}}
// {{{ 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($this->connection);
}
 
// }}}
// {{{ rollback()
 
/**
* Reverts the current transaction
*
* @return int DB_OK on success. A DB_Error object on failure.
*/
function rollback()
{
@fbsql_rollback($this->connection);
}
 
// }}}
// {{{ 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 ($this->_last_query_manip) {
$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) || $this->_next_query_manip) {
return preg_replace('/^([\s(])*SELECT/i',
"\\1SELECT TOP($count)", $query);
} else {
return preg_replace('/([\s(])*SELECT/i',
"\\1SELECT TOP($from, $count)", $query);
}
}
 
// }}}
// {{{ quoteBoolean()
 
/**
* Formats a boolean value for use within a query in a locale-independent
* manner.
*
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteBoolean($boolean) {
return $boolean ? 'TRUE' : 'FALSE';
}
// }}}
// {{{ quoteFloat()
 
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ 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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/odbc.php
New file
0,0 → 1,871
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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 ($this->_checkManip($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 is_resource($result) ? odbc_free_result($result) : false;
}
 
// }}}
// {{{ 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) . '"';
}
}
 
// }}}
// {{{ 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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/common.php
New file
0,0 → 1,2261
<?php
 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the DB_common base class
*
* PHP version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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();
 
/**
* Flag indicating that the last query was a manipulation query.
* @access protected
* @var boolean
*/
var $_last_query_manip = false;
 
/**
* Flag indicating that the next query <em>must</em> be a manipulation
* query.
* @access protected
* @var boolean
*/
var $_next_query_manip = false;
 
 
// }}}
// {{{ DB_common
 
/**
* This constructor calls <kbd>$this->PEAR('DB_Error')</kbd>
*
* @return void
*/
function __construct()
{
$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['persistent']);
}
}
 
// }}}
// {{{ __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->quoteSmart($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 $this->quoteSmart($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)) {
return $in;
} elseif (is_float($in)) {
return $this->quoteFloat($in);
} elseif (is_bool($in)) {
return $this->quoteBoolean($in);
} elseif (is_null($in)) {
return 'NULL';
} else {
if ($this->dbsyntax == 'access'
&& preg_match('/^#.+#$/', $in))
{
return $this->escapeSimple($in);
}
return "'" . $this->escapeSimple($in) . "'";
}
}
 
// }}}
// {{{ quoteBoolean()
 
/**
* Formats a boolean value for use within a query in a locale-independent
* manner.
*
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteBoolean($boolean) {
return $boolean ? '1' : '0';
}
// }}}
// {{{ quoteFloat()
 
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return "'".$this->escapeSimple(str_replace(',', '.', strval(floatval($float))))."'";
}
// }}}
// {{{ 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_object($result) && 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
* @param mixed dummy parameter for E_STRICT compatibility with
* PEAR::raiseError
* @param mixed dummy parameter for E_STRICT compatibility with
* PEAR::raiseError
*
* @return object the PEAR_Error object
*
* @see PEAR_Error
*/
function &raiseError($code = DB_ERROR, $mode = null, $options = null,
$userinfo = null, $nativecode = null, $dummy1 = null,
$dummy2 = 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);
}
 
// }}}
// {{{ nextQueryIsManip()
 
/**
* Sets (or unsets) a flag indicating that the next query will be a
* manipulation query, regardless of the usual DB::isManip() heuristics.
*
* @param boolean true to set the flag overriding the isManip() behaviour,
* false to clear it and fall back onto isManip()
*
* @return void
*
* @access public
*/
function nextQueryIsManip($manip)
{
$this->_next_query_manip = $manip;
}
 
// }}}
// {{{ _checkManip()
 
/**
* Checks if the given query is a manipulation query. This also takes into
* account the _next_query_manip flag and sets the _last_query_manip flag
* (and resets _next_query_manip) according to the result.
*
* @param string The query to check.
*
* @return boolean true if the query is a manipulation query, false
* otherwise
*
* @access protected
*/
function _checkManip($query)
{
if ($this->_next_query_manip || DB::isManip($query)) {
$this->_last_query_manip = true;
} else {
$this->_last_query_manip = false;
}
$this->_next_query_manip = false;
return $this->_last_query_manip;
$manip = $this->_next_query_manip;
}
 
// }}}
// {{{ _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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/msql.php
New file
0,0 → 1,831
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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 ($this->_checkManip($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 is_resource($result) ? msql_free_result($result) : false;
}
 
// }}}
// {{{ 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);
}
 
// }}}
// {{{ quoteFloat()
 
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ 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;
// PHP 5.2+ prepends the function name to $php_errormsg, so we need
// this hack to work around it, per bug #9599.
$errormsg = preg_replace('/^msql[a-z_]+\(\): /', '', $errormsg);
 
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:
*/
 
?>
/branches/v1.3-critias/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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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;
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set.
*
* This method is a no-op for dbase, as there aren't result resources in
* the same sense as most other database backends.
*
* @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 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($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);
}
 
// }}}
// {{{ quoteBoolean()
 
/**
* Formats a boolean value for use within a query in a locale-independent
* manner.
*
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteBoolean($boolean) {
return $boolean ? 'T' : 'F';
}
// }}}
// {{{ 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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/mysqli.php
New file
0,0 → 1,1100
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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,
1356 => DB_ERROR_DIVZERO,
1451 => DB_ERROR_CONSTRAINT,
1452 => 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',
/* These constants are conditionally compiled in ext/mysqli, so we'll
* define them by number rather than constant. */
16 => 'bit',
246 => 'decimal',
);
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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 (((int) $this->getOption('ssl')) === 1) {
$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 = $this->_checkManip($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)
{
if (! $result instanceof mysqli_result) {
return false;
}
mysqli_free_result($result);
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 = @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 ($this->_last_query_manip) {
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
* (WARNING: using names that require this is a REALLY BAD IDEA)
*
* WARNING: Older versions of 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_replace('`', '``', $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) || $this->_next_query_manip) {
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)) {
// Fix for bug #11580.
if ($this->_db) {
if (!@mysqli_select_db($this->connection, $this->_db)) {
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
}
}
 
/*
* 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_object($id) || !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',
// http://bugs.php.net/?id=36579
// Doc Bug #36579: mysqli_fetch_field length handling
// https://bugs.php.net/bug.php?id=62426
// Bug #62426: mysqli_fetch_field_direct returns incorrect
// length on UTF8 fields
'len' => $tmp->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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/mssql.php
New file
0,0 → 1,984
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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.
*
* DB's mssql driver is only for Microsfoft SQL Server databases.
*
* If you're connecting to a Sybase database, you MUST specify "sybase"
* as the "phptype" in the DSN.
*
* This class only works correctly if you have compiled PHP using
* --with-mssql=[dir_to_FreeTDS].
*
* @category Database
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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(
102 => DB_ERROR_SYNTAX,
110 => DB_ERROR_VALUE_COUNT_ON_ROW,
155 => DB_ERROR_NOSUCHFIELD,
156 => DB_ERROR_SYNTAX,
170 => DB_ERROR_SYNTAX,
207 => DB_ERROR_NOSUCHFIELD,
208 => DB_ERROR_NOSUCHTABLE,
245 => DB_ERROR_INVALID_NUMBER,
319 => DB_ERROR_SYNTAX,
321 => DB_ERROR_NOSUCHFIELD,
325 => DB_ERROR_SYNTAX,
336 => DB_ERROR_SYNTAX,
515 => DB_ERROR_CONSTRAINT_NOT_NULL,
547 => DB_ERROR_CONSTRAINT,
1018 => DB_ERROR_SYNTAX,
1035 => DB_ERROR_SYNTAX,
1913 => DB_ERROR_ALREADY_EXISTS,
2209 => DB_ERROR_SYNTAX,
2223 => DB_ERROR_SYNTAX,
2248 => DB_ERROR_SYNTAX,
2256 => DB_ERROR_SYNTAX,
2257 => DB_ERROR_SYNTAX,
2627 => DB_ERROR_CONSTRAINT,
2714 => DB_ERROR_ALREADY_EXISTS,
3607 => DB_ERROR_DIVZERO,
3701 => DB_ERROR_NOSUCHTABLE,
7630 => DB_ERROR_SYNTAX,
8134 => DB_ERROR_DIVZERO,
9303 => DB_ERROR_SYNTAX,
9317 => DB_ERROR_SYNTAX,
9318 => DB_ERROR_SYNTAX,
9331 => DB_ERROR_SYNTAX,
9332 => DB_ERROR_SYNTAX,
15253 => DB_ERROR_SYNTAX,
);
 
/**
* 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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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 = $this->_checkManip($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_assoc($result);
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 is_resource($result) ? mssql_free_result($result) : false;
}
 
// }}}
// {{{ 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 ($this->_last_query_manip) {
$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 IDENT_CURRENT('$seqname')");
if (DB::isError($result)) {
/* Fallback code for MS SQL Server 7.0, which doesn't have
* IDENT_CURRENT. This is *not* safe for concurrent
* requests, and really, if you're using it, you're in a
* world of hurt. Nevertheless, it's here to ensure BC. See
* bug #181 for the gory details.*/
$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));
}
 
// }}}
// {{{ escapeSimple()
 
/**
* Escapes a string in a manner suitable for SQL Server.
*
* @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(
array("'", "\\\r\n", "\\\n"),
array("''", "\\\\\r\n\r\n", "\\\\\n\n"),
$str
);
}
 
// }}}
// {{{ 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++) {
if ($got_string) {
$flags = $this->_mssql_field_flags($result,
@mssql_field_name($id, $i));
if (DB::isError($flags)) {
return $flags;
}
} else {
$flags = '';
}
 
$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),
'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) {
@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);
if (DB::isError($res)) {
return $res;
}
 
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);
if (DB::isError($res)) {
return $res;
}
 
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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/sqlite.php
New file
0,0 → 1,963
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
* @version Release: 1.9.2
* @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>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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']) {
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
}
 
if ($dsn['database'] !== ':memory:') {
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);
}
}
 
$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 = $this->_checkManip($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);
}
 
/* Remove extraneous " characters from the fields in the result.
* Fixes bug #11716. */
if (is_array($arr) && count($arr) > 0) {
$strippedArr = array();
foreach ($arr as $field => $value) {
$strippedArr[trim($field, '"')] = $value;
}
$arr = $strippedArr;
}
} 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;
// PHP 5.2+ prepends the function name to $php_errormsg, so we need
// this hack to work around it, per bug #9599.
$errormsg = preg_replace('/^sqlite[a-z_]+\(\): /', '', $errormsg);
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,
'/no column named/' => 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 (strtoupper($type) == 'INTEGER') {
$flags .= 'auto_increment ';
}
}
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:
*/
 
?>
/branches/v1.3-critias/bibliotheque/pear/DB/oci8.php
New file
0,0 → 1,1158
<?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 version 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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @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-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @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,
12899 => DB_ERROR_INVALID,
);
 
/**
* 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();
 
/**
* Store of prepared SQL queries.
* @var array
* @access private
*/
var $_prepared_queries = array();
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
*
* @return void
*/
function __construct()
{
parent::__construct();
}
 
// }}}
// {{{ 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'];
}
 
// Backwards compatibility with DB < 1.7.0
if (empty($dsn['database']) && !empty($dsn['hostspec'])) {
$db = $dsn['hostspec'];
} else {
$db = $dsn['database'];
}
 
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';
}
if (isset($this->dsn['port']) && $this->dsn['port']) {
$db = '//'.$db.':'.$this->dsn['port'];
}
 
$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 ($db) {
$this->connection = @$connect_function($dsn['username'],
$dsn['password'],
$db);
} 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 ($this->_checkManip($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 is_resource($result) ? OCIFreeStatement($result) : false;
}
 
/**
* 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]);
unset($this->_prepared_queries[(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;
 
$count = $this->query($countquery);
 
// Restore the last query and statement.
$this->last_query = $save_query;
$this->last_stmt = $save_stmt;
if (DB::isError($count) ||
DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED)))
{
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);
$this->_prepared_queries[(int)$stmt] = $newquery;
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->last_query = $this->_prepared_queries[(int)$stmt];
$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);
} elseif ($types[$i] == DB_PARAM_SCALAR) {
// Floats have to be converted to a locale-neutral
// representation.
if (is_float($data[$key])) {
$data[$key] = $this->quoteFloat($data[$key]);
}
}
if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) {
$tmp = $this->oci8RaiseError($stmt);
return $tmp;
}
$this->last_query = preg_replace("/:bind$i(?!\d)/",
$this->quoteSmart($data[$key]), $this->last_query, 1);
$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] || $this->_next_query_manip) {
$this->_last_query_manip = true;
$this->_next_query_manip = false;
$tmp = DB_OK;
} else {
$this->_last_query_manip = false;
@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';
case 'views':
return 'SELECT view_name FROM user_views';
default:
return null;
}
}
 
// }}}
// {{{ quoteFloat()
 
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
 
?>
/branches/v1.3-critias/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;
}
 
// }}}
}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Config.php
New file
0,0 → 1,414
<?php
/**
* PEAR_Command_Config (config-show, config-get, config-set, config-help, config-create commands)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Config extends PEAR_Command_Common
{
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).
',
),
);
 
/**
* PEAR_Command_Config constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
 
function doConfigShow($command, $options, $params)
{
$layer = null;
if (is_array($params)) {
$layer = isset($params[0]) ? $params[0] : 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');
}
 
$channel = $reg->channelName($channel);
$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;
}
 
function doConfigGet($command, $options, $params)
{
$args_cnt = is_array($params) ? count($params) : 0;
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");
}
 
$reg = &$this->config->getRegistry();
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
 
$channel = $reg->channelName($channel);
$this->ui->outputData($this->config->get($config_key, $layer, $channel), $command);
return true;
}
 
function doConfigSet($command, $options, $params)
{
// $param[0] -> a parameter to set
// $param[1] -> the value for the parameter
// $param[2] -> the layer
$failmsg = '';
if (count($params) < 2 || count($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');
}
 
$channel = $reg->channelName($channel);
if ($params[0] == 'default_channel' && !$reg->channelExists($params[1])) {
return $this->raiseError('Channel "' . $params[1] . '" does not exist');
}
 
if ($params[0] == 'preferred_mirror'
&& (
!$reg->mirrorExists($channel, $params[1]) &&
(!$reg->channelExists($params[1]) || $channel != $params[1])
)
) {
$msg = 'Channel Mirror "' . $params[1] . '" does not exist';
$msg .= ' in your registry for channel "' . $channel . '".';
$msg .= "\n" . 'Attempt to run "pear channel-update ' . $channel .'"';
$msg .= ' if you believe this mirror should exist as you may';
$msg .= ' have outdated channel information.';
return $this->raiseError($msg);
}
 
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;
}
 
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);
}
 
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'])) {
return PEAR::raiseError('Root directory must be an absolute path beginning ' .
'with "/", was: "' . $root . '"');
}
 
if (!preg_match('/^[A-Za-z]:/', $root)) {
return PEAR::raiseError('Root directory must be an absolute path beginning ' .
'with "\\" or "C:\\", was: "' . $root . '"');
}
}
 
$windows = isset($options['windows']);
if ($windows) {
$root = str_replace('/', '\\', $root);
}
 
if (!file_exists($params[1]) && !@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('www_dir', $windows ? "$root\\pear\\www" : "$root/pear/www");
$config->set('cfg_dir', $windows ? "$root\\pear\\cfg" : "$root/pear/cfg");
$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('download_dir', $windows ? "$root\\pear\\download" : "$root/pear/download");
$config->set('temp_dir', $windows ? "$root\\pear\\temp" : "$root/pear/temp");
$config->set('bin_dir', $windows ? "$root\\pear" : "$root/pear");
$config->set('man_dir', $windows ? "$root\\pear\\man" : "$root/pear/man");
$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;
}
 
/**
* 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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Install.php
New file
0,0 → 1,1269
<?php
/**
* PEAR_Command_Install (install, upgrade, upgrade-all, uninstall, bundle, run-scripts commands)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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(
'channel' => array(
'shortopt' => 'c',
'doc' => 'upgrade packages from a specific channel',
'arg' => 'CHAN',
),
'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)',
),
'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 [Deprecated in favor of calling upgrade with no parameters]',
'function' => 'doUpgradeAll',
'shortcut' => 'ua',
'options' => array(
'channel' => array(
'shortopt' => 'c',
'doc' => 'upgrade packages from a specific channel',
'arg' => 'CHAN',
),
'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' => '
WARNING: This function is deprecated in favor of using the upgrade command with no params
 
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 __construct(&$ui, &$config)
{
parent::__construct($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;
}
$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));
$fp = @fopen($phpini, 'wb');
if (!$fp) {
return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
}
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)) {
return PEAR::raiseError('php.ini "' . $filename . '" does not exist');
}
 
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 === false) {
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,
);
}
 
// {{{ doInstall()
 
function doInstall($command, $options, $params)
{
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
 
if (isset($options['installroot']) && isset($options['packagingroot'])) {
return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot');
}
 
$reg = &$this->config->getRegistry();
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
 
if (empty($this->installer)) {
$this->installer = &$this->getInstaller($this->ui);
}
 
if ($command == 'upgrade' || $command == 'upgrade-all') {
// If people run the upgrade command but pass nothing, emulate a upgrade-all
if ($command == 'upgrade' && empty($params)) {
return $this->doUpgradeAll($command, $options, $params);
}
$options['upgrade'] = true;
} else {
$packages = $params;
}
 
$instreg = &$reg; // instreg used to check if package is installed
if (isset($options['packagingroot']) && !isset($options['upgrade'])) {
$packrootphp_dir = $this->installer->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$options['packagingroot']);
$metadata_dir = $this->config->get('metadata_dir', null, 'pear.php.net');
if ($metadata_dir) {
$metadata_dir = $this->installer->_prependPath(
$metadata_dir,
$options['packagingroot']);
}
$instreg = new PEAR_Registry($packrootphp_dir, false, false, $metadata_dir); // other instreg!
 
if ($this->config->get('verbose') > 2) {
$this->ui->outputData('using package root: ' . $options['packagingroot']);
}
}
 
$abstractpackages = $otherpackages = array();
// parse params
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
 
foreach ($params as $param) {
if (strpos($param, 'http://') === 0) {
$otherpackages[] = $param;
continue;
}
 
if (strpos($param, 'channel://') === false && @file_exists($param)) {
if (isset($options['force'])) {
$otherpackages[] = $param;
continue;
}
 
$pkg = new PEAR_PackageFile($this->config);
$pf = $pkg->fromAnyFile($param, PEAR_VALIDATE_DOWNLOADING);
if (PEAR::isError($pf)) {
$otherpackages[] = $param;
continue;
}
 
$exists = $reg->packageExists($pf->getPackage(), $pf->getChannel());
$pversion = $reg->packageInfo($pf->getPackage(), 'version', $pf->getChannel());
$version_compare = version_compare($pf->getVersion(), $pversion, '<=');
if ($exists && $version_compare) {
if ($this->config->get('verbose')) {
$this->ui->outputData('Ignoring installed package ' .
$reg->parsedPackageNameToString(
array('package' => $pf->getPackage(),
'channel' => $pf->getChannel()), true));
}
continue;
}
$otherpackages[] = $param;
continue;
}
 
$e = $reg->parsePackageName($param, $channel);
if (PEAR::isError($e)) {
$otherpackages[] = $param;
} else {
$abstractpackages[] = $e;
}
}
PEAR::staticPopErrorHandling();
 
// if there are any local package .tgz or remote static url, we can't
// filter. The filter only works for abstract packages
if (count($abstractpackages) && !isset($options['force'])) {
// when not being forced, only do necessary upgrades/installs
if (isset($options['upgrade'])) {
$abstractpackages = $this->_filterUptodatePackages($abstractpackages, $command);
} else {
$count = count($abstractpackages);
foreach ($abstractpackages as $i => $package) {
if (isset($package['group'])) {
// do not filter out install groups
continue;
}
 
if ($instreg->packageExists($package['package'], $package['channel'])) {
if ($count > 1) {
if ($this->config->get('verbose')) {
$this->ui->outputData('Ignoring installed package ' .
$reg->parsedPackageNameToString($package, true));
}
unset($abstractpackages[$i]);
} elseif ($count === 1) {
// Lets try to upgrade it since it's already installed
$options['upgrade'] = true;
}
}
}
}
$abstractpackages =
array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages);
} elseif (count($abstractpackages)) {
$abstractpackages =
array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages);
}
 
$packages = array_merge($abstractpackages, $otherpackages);
if (!count($packages)) {
$c = '';
if (isset($options['channel'])){
$c .= ' in channel "' . $options['channel'] . '"';
}
$this->ui->outputData('Nothing to ' . $command . $c);
return true;
}
 
$this->downloader = &$this->getDownloader($this->ui, $options, $this->config);
$errors = $downloaded = $binaries = array();
$downloaded = &$this->downloader->download($packages);
if (PEAR::isError($downloaded)) {
return $this->raiseError($downloaded);
}
 
$errors = $this->downloader->getErrorMsgs();
if (count($errors)) {
$err = array();
$err['data'] = array();
foreach ($errors as $error) {
if ($error !== null) {
$err['data'][] = array($error);
}
}
 
if (!empty($err['data'])) {
$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;
}
 
$binaries = $extrainfo = array();
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)) {
return $this->raiseError("$command failed");
}
 
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;
}
}
 
if (count($binaries)) {
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';
$extpath = $pinfo[1]['basename'];
} else {
$exttype = 'zend_extension';
$extpath = $atts['installed_as'];
}
$extrainfo[] = 'You should add "' . $exttype . '=' .
$extpath . '" to php.ini';
} else {
$extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() .
' enabled in php.ini';
}
}
}
}
 
if ($this->config->get('verbose') > 0) {
$chan = $param->getChannel();
$label = $reg->parsedPackageNameToString(
array(
'channel' => $chan,
'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;
}
$extrainfo[] = $param->getPackage() . ': Optional feature ' .
$group['attribs']['name'] . ' available (' .
$group['attribs']['hint'] . ')';
}
 
$extrainfo[] = $param->getPackage() .
': To install optional features use "pear install ' .
$reg->parsedPackageNameToString(
array('package' => $param->getPackage(),
'channel' => $param->getChannel()), true) .
'#featurename"';
}
}
 
$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[] = $param->getPackage() .
': Use "pear run-scripts ' . $pn . '" to finish setup.';
$extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES';
}
}
}
 
if (count($extrainfo)) {
foreach ($extrainfo as $info) {
$this->ui->outputData($info);
}
}
 
return true;
}
 
// }}}
// {{{ doUpgradeAll()
 
function doUpgradeAll($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$upgrade = array();
 
if (isset($options['channel'])) {
$channels = array($options['channel']);
} else {
$channels = $reg->listChannels();
}
 
foreach ($channels as $channel) {
if ($channel == '__uri') {
continue;
}
 
// parse name with channel
foreach ($reg->listPackages($channel) as $name) {
$upgrade[] = $reg->parsedPackageNameToString(array(
'channel' => $channel,
'package' => $name
));
}
}
 
$err = $this->doInstall($command, $options, $upgrade);
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage(), $command);
}
}
 
// }}}
// {{{ doUninstall()
 
function doUninstall($command, $options, $params)
{
if (count($params) < 1) {
return $this->raiseError("Please supply the package(s) you want to uninstall");
}
 
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);
}
}
 
$reg = &$this->config->getRegistry();
$newparams = array();
$binaries = 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);
$binaries = array();
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;
}
}
if (count($binaries)) {
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)) {
return $this->raiseError("uninstall failed: $pkg");
}
$pkg = $reg->parsedPackageNameToString($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)
{
$opts = array(
'force' => true,
'nodeps' => true,
'soft' => true,
'downloadonly' => true
);
$downloader = &$this->getDownloader($this->ui, $opts, $this->config);
$reg = &$this->config->getRegistry();
if (count($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();
$dir = $pwd . DIRECTORY_SEPARATOR . 'ext';
$dest = is_dir($dir) ? $dir : $pwd;
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $downloader->setDownloadDir($dest);
PEAR::staticPopErrorHandling();
if (PEAR::isError($err)) {
return PEAR::raiseError('download directory "' . $dest .
'" is not writeable.');
}
$result = &$downloader->download(array($params[0]));
if (PEAR::isError($result)) {
return $result;
}
if (!isset($result[0])) {
return $this->raiseError('unable to unpack ' . $params[0]);
}
$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)) {
return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry');
}
 
$package->setConfig($this->config);
$package->runPostinstallScripts();
$this->ui->outputData('Install scripts complete', $command);
return true;
}
 
/**
* Given a list of packages, filter out those ones that are already up to date
*
* @param $packages: packages, in parsed array format !
* @return list of packages that can be upgraded
*/
function _filterUptodatePackages($packages, $command)
{
$reg = &$this->config->getRegistry();
$latestReleases = array();
 
$ret = array();
foreach ($packages as $package) {
if (isset($package['group'])) {
$ret[] = $package;
continue;
}
 
$channel = $package['channel'];
$name = $package['package'];
if (!$reg->packageExists($name, $channel)) {
$ret[] = $package;
continue;
}
 
if (!isset($latestReleases[$channel])) {
// fill in cache for this channel
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
 
$base2 = false;
$preferred_mirror = $this->config->get('preferred_mirror', null, $channel);
if ($chan->supportsREST($preferred_mirror) &&
(
//($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) ||
($base = $chan->getBaseURL('REST1.0', $preferred_mirror))
)
) {
$dorest = true;
}
 
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (!isset($package['state'])) {
$state = $this->config->get('preferred_state', null, $channel);
} else {
$state = $package['state'];
}
 
if ($dorest) {
if ($base2) {
$rest = &$this->config->getREST('1.4', array());
$base = $base2;
} else {
$rest = &$this->config->getREST('1.0', array());
}
 
$installed = array_flip($reg->listPackages($channel));
$latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg);
}
 
PEAR::staticPopErrorHandling();
if (PEAR::isError($latest)) {
$this->ui->outputData('Error getting channel info from ' . $channel .
': ' . $latest->getMessage());
continue;
}
 
$latestReleases[$channel] = array_change_key_case($latest);
}
 
// check package for latest release
$name_lower = strtolower($name);
if (isset($latestReleases[$channel][$name_lower])) {
// if not set, up to date
$inst_version = $reg->packageInfo($name, 'version', $channel);
$channel_version = $latestReleases[$channel][$name_lower]['version'];
if (version_compare($channel_version, $inst_version, 'le')) {
// installed version is up-to-date
continue;
}
 
// maintain BC
if ($command == 'upgrade-all') {
$this->ui->outputData(array('data' => 'Will upgrade ' .
$reg->parsedPackageNameToString($package)), $command);
}
$ret[] = $package;
}
}
 
return $ret;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Pickle.php
New file
0,0 → 1,420
<?php
/**
* PEAR_Command_Pickle (pickle command)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2005-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct(&$ui, &$config)
{
parent::__construct($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)
{
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
 
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
 
$a = new PEAR_PackageFile($config, $debug);
$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'
&& $dep['channel'] != 'doc.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'
&& $dep['channel'] != 'doc.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) {
$default = isset($option['default']) ? $option['default'] : false;
$pf->addConfigureOption($option['name'], $option['prompt'], $default);
}
}
 
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('.');
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Registry.php
New file
0,0 → 1,1144
<?php
/**
* PEAR_Command_Registry (list, list-files, shell-test, info commands)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Registry extends PEAR_Command_Common
{
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',
),
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'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.'
)
);
 
/**
* PEAR_Command_Registry constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
 
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)
{
$reg = &$this->config->getRegistry();
$channelinfo = isset($options['channelinfo']);
if (isset($options['allchannels']) && !$channelinfo) {
return $this->doListAll($command, array(), $params);
}
 
if (isset($options['allchannels']) && $channelinfo) {
// allchannels with $channelinfo
unset($options['allchannels']);
$channels = $reg->getChannels();
$errors = array();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
foreach ($channels as $channel) {
$options['channel'] = $channel->getName();
$ret = $this->doList($command, $options, $params);
 
if (PEAR::isError($ret)) {
$errors[] = $ret;
}
}
 
PEAR::staticPopErrorHandling();
if (count($errors)) {
// for now, only give first error
return PEAR::raiseError($errors[0]);
}
 
return true;
}
 
if (count($params) === 1) {
return $this->doFileList($command, $options, $params);
}
 
if (isset($options['channel'])) {
if (!$reg->channelExists($options['channel'])) {
return $this->raiseError('Channel "' . $options['channel'] .'" does not exist');
}
 
$channel = $reg->channelName($options['channel']);
} else {
$channel = $this->config->get('default_channel');
}
 
$installed = $reg->packageInfo(null, null, $channel);
usort($installed, array(&$this, '_sortinfo'));
 
$data = array(
'caption' => 'Installed packages, channel ' .
$channel . ':',
'border' => true,
'headline' => array('Package', 'Version', 'State'),
'channel' => $channel,
);
if ($channelinfo) {
$data['headline'] = array('Channel', 'Package', 'Version', 'State');
}
 
if (count($installed) && !isset($data['data'])) {
$data['data'] = array();
}
 
foreach ($installed as $package) {
$pobj = $reg->getPackage(isset($package['package']) ?
$package['package'] : $package['name'], $channel);
if ($channelinfo) {
$packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(),
$pobj->getState() ? $pobj->getState() : null);
} else {
$packageinfo = array($pobj->getPackage(), $pobj->getVersion(),
$pobj->getState() ? $pobj->getState() : null);
}
$data['data'][] = $packageinfo;
}
 
if (count($installed) === 0) {
if (!$channelinfo) {
$data = '(no packages installed from channel ' . $channel . ')';
} else {
$data = array(
'caption' => 'Installed packages, channel ' .
$channel . ':',
'border' => true,
'channel' => $channel,
'data' => array(array('(no packages installed)')),
);
}
}
 
$this->ui->outputData($data, $command);
return true;
}
 
function doListAll($command, $options, $params)
{
// This duplicate code is deprecated over
// list --channelinfo, which gives identical
// output for list and list --allchannels.
$reg = &$this->config->getRegistry();
$installed = $reg->packageInfo(null, null, null);
foreach ($installed as $channel => $packages) {
usort($packages, array($this, '_sortinfo'));
$data = array(
'caption' => 'Installed packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Version', 'State'),
'channel' => $channel
);
 
foreach ($packages as $package) {
$p = isset($package['package']) ? $package['package'] : $package['name'];
$pobj = $reg->getPackage($p, $channel);
$data['data'][] = array($pobj->getPackage(), $pobj->getVersion(),
$pobj->getState() ? $pobj->getState() : null);
}
 
// Adds a blank line after each section
$data['data'][] = array();
 
if (count($packages) === 0) {
$data = array(
'caption' => 'Installed packages, channel ' . $channel . ':',
'border' => true,
'data' => array(array('(no packages installed)'), array()),
'channel' => $channel
);
}
$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;
}
 
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 (count($params) === 1) {
if (!$reg->packageExists($package, $channel)) {
exit(1);
}
// "pear shell-test Foo 1.0"
} elseif (count($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 (count($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);
}
}
 
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 (is_file($params[0]) && !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);
$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') {
return $this->_doInfo2($command, $options, $params, $obj, false);
}
 
$info = $obj->toArray();
} 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";
}
 
$active = $lead['active'] == 'no' ? ', inactive' : '';
$info['Maintainers'] .= $lead['name'] . ' <';
$info['Maintainers'] .= $lead['email'] . "> ($role$active)";
}
}
 
$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()) {
if (!isset($compat[0])) {
$compat = array($compat);
}
 
$info['Compatible with'] = '';
foreach ($compat as $package) {
$info['Compatible with'] .= $package['channel'] . '/' . $package['name'] .
"\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['name'] . "\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');
}
}
/branches/v1.3-critias/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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Auth.xml
New file
0,0 → 1,30
<commands version="1.0">
<login>
<summary>Connects and authenticates to remote server [Deprecated in favor of channel-login]</summary>
<function>doLogin</function>
<shortcut>li</shortcut>
<options />
<doc>&lt;channel name&gt;
WARNING: This function is deprecated in favor of using channel-login
 
Log in to a remote channel server. If &lt;channel name&gt; is not supplied,
the default channel is used. 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 [Deprecated in favor of channel-logout]</summary>
<function>doLogout</function>
<shortcut>lo</shortcut>
<options />
<doc>
WARNING: This function is deprecated in favor of using channel-logout
 
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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Mirror.php
New file
0,0 → 1,138
<?php
/**
* PEAR_Command_Mirror (download-all command)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Alexander Merz <alexmerz@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.2.0
*/
class PEAR_Command_Mirror extends PEAR_Command_Common
{
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'
),
);
 
/**
* 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 __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
 
/**
* For unit-testing
*/
function &factory($a)
{
$a = &PEAR_Command::factory($a, $this->config);
return $a;
}
 
/**
* 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 successful
* @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, $channel));
}
 
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;
}
}
/branches/v1.3-critias/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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Test.php
New file
0,0 → 1,343
<?php
/**
* PEAR_Command_Test (run-tests)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
 
class PEAR_Command_Test extends PEAR_Command_Common
{
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
If none is found, all .phpt tests will be tried instead.',
),
'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',
),
'coverage' => array(
'shortopt' => 'x',
'doc' => 'Generate a code coverage report (requires Xdebug 2.0.0+)',
),
'showdiff' => array(
'shortopt' => 'd',
'doc' => 'Output diff on test failure',
),
),
'doc' => '[testfile|dir ...]
Run regression tests with PHP\'s regression testing script (run-tests.php).',
),
);
 
var $output;
 
/**
* PEAR_Command_Test constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
 
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 'System.php';
$log = new PEAR_Common;
$log->ui = &$this->ui; // slightly hacky, but it will work
$tests = array();
$depth = isset($options['recur']) ? 14 : 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']) && preg_match('/AllTests\.php\\z/i', $name)) {
$params[] = $atts['installed_as'];
continue;
} elseif (!preg_match('/\.phpt\\z/', $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'));
if (count($dir)) {
foreach ($dir as $p) {
$p = realpath($p);
if (!count($tests) ||
(count($tests) && strlen($p) < strlen($tests[0]))) {
// this is in a higher-level directory, use this one instead.
$tests = array($p);
}
}
}
continue;
}
 
$args = array($p, '-type', 'f', '-name', '*.phpt');
} else {
if (isset($options['phpunit'])) {
if (preg_match('/AllTests\.php\\z/i', $p)) {
$p = realpath($p);
if (!count($tests) ||
(count($tests) && strlen($p) < strlen($tests[0]))) {
// this is in a higher-level directory, use this one instead.
$tests = array($p);
}
}
continue;
}
 
if (file_exists($p) && preg_match('/\.phpt$/', $p)) {
$tests[] = $p;
continue;
}
 
if (!preg_match('/\.phpt\\z/', $p)) {
$p .= '.phpt';
}
 
$args = array(dirname($p), '-type', 'f', '-name', $p);
}
 
if (!isset($options['recur'])) {
$args[] = '-maxdepth';
$args[] = 1;
}
 
$dir = System::find($args);
$tests = array_merge($tests, $dir);
}
 
$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();
$tests_count = count($tests);
$this->ui->outputData('Running ' . $tests_count . ' tests', $command);
$start = time();
if (isset($options['realtimelog']) && file_exists('run-tests.log')) {
unlink('run-tests.log');
}
 
if (isset($options['tapoutput'])) {
$tap = '1..' . $tests_count . "\n";
}
 
require_once 'PEAR/RunTest.php';
$run = new PEAR_RunTest($log, $options);
$run->tests_count = $tests_count;
 
if (isset($options['coverage']) && extension_loaded('xdebug')){
$run->xdebug_loaded = true;
} else {
$run->xdebug_loaded = false;
}
 
$j = $i = 1;
foreach ($tests as $t) {
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
if ($fp) {
fwrite($fp, "Running test [$i / $tests_count] $t...");
fclose($fp);
}
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (isset($options['phpunit'])) {
$result = $run->runPHPUnit($t, $ini_settings);
} else {
$result = $run->run($t, $ini_settings, $j);
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($result)) {
$this->ui->log($result->getMessage());
continue;
}
 
if (isset($options['tapoutput'])) {
$tap .= $result[0] . ' ' . $i . $result[1] . "\n";
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;
}
 
$j++;
}
 
$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";
}
 
$mode = isset($options['realtimelog']) ? 'a' : 'w';
$fp = @fopen('run-tests.log', $mode);
 
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);
}
}
 
if (count($failed) == 0) {
return true;
}
return $this->raiseError('Some tests failed');
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Install.xml
New file
0,0 → 1,276
<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&#039;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
<doc>request uncompressed files when downloading</doc>
</nocompress>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT), use packagingroot for RPM</doc>
<arg>DIR</arg>
</installroot>
<packagingroot>
<shortopt>P</shortopt>
<doc>root directory used when packaging files, like RPM packaging</doc>
<arg>DIR</arg>
</packagingroot>
<ignore-errors>
<shortopt></shortopt>
<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&#039;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>
<channel>
<shortopt>c</shortopt>
<doc>upgrade packages from a specific channel</doc>
<arg>CHAN</arg>
</channel>
<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&#039;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
<doc>request uncompressed files when downloading</doc>
</nocompress>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT)</doc>
<arg>DIR</arg>
</installroot>
<ignore-errors>
<shortopt></shortopt>
<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 [Deprecated in favor of calling upgrade with no parameters]</summary>
<function>doUpgradeAll</function>
<shortcut>ua</shortcut>
<options>
<channel>
<shortopt>c</shortopt>
<doc>upgrade packages from a specific channel</doc>
<arg>CHAN</arg>
</channel>
<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&#039;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
<doc>request uncompressed files when downloading</doc>
</nocompress>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT), use packagingroot for RPM</doc>
<arg>DIR</arg>
</installroot>
<ignore-errors>
<shortopt></shortopt>
<doc>force install even if there were errors</doc>
</ignore-errors>
<loose>
<shortopt></shortopt>
<doc>do not check for recommended dependency version</doc>
</loose>
</options>
<doc>
WARNING: This function is deprecated in favor of using the upgrade command with no params
 
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>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT)</doc>
<arg>DIR</arg>
</installroot>
<ignore-errors>
<shortopt></shortopt>
<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>
<doc>Optional destination directory for unpacking (defaults to current path or &quot;ext&quot; if exists)</doc>
<arg>DIR</arg>
</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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Pickle.xml
New file
0,0 → 1,36
<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]
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 &quot;package.xml&quot;. 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.
</doc>
</pickle>
</commands>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Registry.xml
New file
0,0 → 1,58
<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>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Common.php
New file
0,0 → 1,272
<?php
/**
* PEAR_Command_Common base class
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Common extends PEAR
{
/**
* 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'
);
 
/**
* PEAR_Command_Common constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct();
$this->config = &$config;
$this->ui = &$ui;
}
 
/**
* 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;
}
 
/**
* 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;
}
 
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'];
}
 
return null;
}
 
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;
}
}
 
/**
* 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));
}
 
/**
* 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;
}
 
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;
 
//$command = $this->commands[$cmd]['function'];
break;
}
}
} else {
$func = $this->commands[$command]['function'];
}
 
return $this->$func($command, $options, $params);
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Test.xml
New file
0,0 → 1,54
<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
If none is found, all .phpt tests will be tried instead.</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>
<coverage>
<shortopt>x</shortopt>
<doc>Generate a code coverage report (requires Xdebug 2.0.0+)</doc>
</coverage>
</options>
<doc>[testfile|dir ...]
Run regression tests with PHP&#039;s regression testing script (run-tests.php).</doc>
</run-tests>
</commands>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Package.php
New file
0,0 → 1,1123
<?php
/**
* PEAR_Command_Package (package, package-validate, cvsdiff, cvstag, package-dependencies,
* sign, makerpm, convert commands)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: @package_version@
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
 
class PEAR_Command_Package extends PEAR_Command_Common
{
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.
',
),
'svntag' => array(
'summary' => 'Set SVN Release Tag',
'function' => 'doSvnTag',
'shortcut' => 'sv',
'options' => array(
'quiet' => array(
'shortopt' => 'q',
'doc' => 'Be 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 SVN 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 svntag 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.
',
),
'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' => '<package-file> or <package.xml> or <install-package-name>
List all dependencies the package has.
Can take a tgz / tar file, package.xml or a package name of an installed package.'
),
'sign' => array(
'summary' => 'Sign a package distribution file',
'function' => 'doSign',
'shortcut' => 'si',
'options' => array(
'verbose' => array(
'shortopt' => 'v',
'doc' => 'Display GnuPG output',
),
),
'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;
 
/**
* PEAR_Command_Package constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
 
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 && count($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)
{
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
$a = new PEAR_PackageFile($config, $debug);
$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] : 'package.xml';
$pkg2 = isset($params[1]) ? $params[1] : null;
if (!$pkg2 && !isset($params[0]) && 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;
}
 
function doPackageValidate($command, $options, $params)
{
$this->output = '';
if (count($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 = $warn = array();
if ($errors = $info->getValidationWarnings()) {
foreach ($errors 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;
}
 
function doSvnTag($command, $options, $params)
{
$this->output = '';
$_cmd = $command;
if (count($params) < 1) {
$help = $this->getHelp($command);
return $this->raiseError("$command: missing parameter: $help[0]");
}
 
$packageFile = realpath($params[0]);
$dir = dirname($packageFile);
$dir = substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1);
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($packageFile, 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('SVN tag failed');
}
 
$version = $info->getVersion();
$package = $info->getName();
$svntag = "$package-$version";
 
if (isset($options['delete'])) {
return $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options);
}
 
$path = $this->_svnFindPath($packageFile);
 
// Check if there are any modified files
$fp = popen('svn st --xml ' . dirname($packageFile), "r");
$out = '';
while ($line = fgets($fp, 1024)) {
$out .= rtrim($line)."\n";
}
pclose($fp);
 
if (!isset($options['quiet']) && strpos($out, 'item="modified"')) {
$params = array(array(
'name' => 'modified',
'type' => 'yesno',
'default' => 'no',
'prompt' => 'You have files in your SVN checkout (' . $path['from'] . ') that have been modified but not committed, do you still want to tag ' . $version . '?',
));
$answers = $this->ui->confirmDialog($params);
 
if (!in_array($answers['modified'], array('y', 'yes', 'on', '1'))) {
return true;
}
}
 
if (isset($options['slide'])) {
$this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options);
}
 
// Check if tag already exists
$releaseTag = $path['local']['base'] . 'tags' . DIRECTORY_SEPARATOR . $svntag;
$existsCommand = 'svn ls ' . $path['base'] . 'tags/';
 
$fp = popen($existsCommand, "r");
$out = '';
while ($line = fgets($fp, 1024)) {
$out .= rtrim($line)."\n";
}
pclose($fp);
 
if (in_array($svntag . DIRECTORY_SEPARATOR, explode("\n", $out))) {
$this->ui->outputData($this->output, $command);
return $this->raiseError('SVN tag ' . $svntag . ' for ' . $package . ' already exists.');
} elseif (file_exists($path['local']['base'] . 'tags') === false) {
return $this->raiseError('Can not locate the tags directory at ' . $path['local']['base'] . 'tags');
} elseif (is_writeable($path['local']['base'] . 'tags') === false) {
return $this->raiseError('Can not write to the tag directory at ' . $path['local']['base'] . 'tags');
} else {
$makeCommand = 'svn mkdir ' . $releaseTag;
$this->output .= "+ $makeCommand\n";
if (empty($options['dry-run'])) {
// We need to create the tag dir.
$fp = popen($makeCommand, "r");
$out = '';
while ($line = fgets($fp, 1024)) {
$out .= rtrim($line)."\n";
}
pclose($fp);
$this->output .= "$out\n";
}
}
 
$command = 'svn';
if (isset($options['quiet'])) {
$command .= ' -q';
}
 
$command .= ' copy --parents ';
 
$dir = dirname($packageFile);
$dir = substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1);
$files = array_keys($info->getFilelist());
if (!in_array(basename($packageFile), $files)) {
$files[] = basename($packageFile);
}
 
array_shift($params);
if (count($params)) {
// add in additional files to be tagged (package files and such)
$files = array_merge($files, $params);
}
 
$commands = array();
foreach ($files as $file) {
if (!file_exists($file)) {
$file = $dir . DIRECTORY_SEPARATOR . $file;
}
$commands[] = $command . ' ' . escapeshellarg($file) . ' ' .
escapeshellarg($releaseTag . DIRECTORY_SEPARATOR . $file);
}
 
$this->output .= implode("\n", $commands) . "\n";
if (empty($options['dry-run'])) {
foreach ($commands as $command) {
$fp = popen($command, "r");
while ($line = fgets($fp, 1024)) {
$this->output .= rtrim($line)."\n";
}
pclose($fp);
}
}
 
$command = 'svn ci -m "Tagging the ' . $version . ' release" ' . $releaseTag . "\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;
}
 
function _svnFindPath($file)
{
$xml = '';
$command = "svn info --xml $file";
$fp = popen($command, "r");
while ($line = fgets($fp, 1024)) {
$xml .= rtrim($line)."\n";
}
pclose($fp);
$url_tag = strpos($xml, '<url>');
$url = substr($xml, $url_tag + 5, strpos($xml, '</url>', $url_tag + 5) - ($url_tag + 5));
 
$path = array();
$path['from'] = substr($url, 0, strrpos($url, '/'));
$path['base'] = substr($path['from'], 0, strrpos($path['from'], '/') + 1);
 
// Figure out the local paths - see http://pear.php.net/bugs/17463
$pos = strpos($file, DIRECTORY_SEPARATOR . 'trunk' . DIRECTORY_SEPARATOR);
if ($pos === false) {
$pos = strpos($file, DIRECTORY_SEPARATOR . 'branches' . DIRECTORY_SEPARATOR);
}
$path['local']['base'] = substr($file, 0, $pos + 1);
 
return $path;
}
 
function _svnRemoveTag($version, $package, $tag, $packageFile, $options)
{
$command = 'svn';
 
if (isset($options['quiet'])) {
$command .= ' -q';
}
 
$command .= ' remove';
$command .= ' -m "Removing tag for the ' . $version . ' release."';
 
$path = $this->_svnFindPath($packageFile);
$command .= ' ' . $path['base'] . 'tags/' . $tag;
 
 
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, $command);
return true;
}
 
function doCvsTag($command, $options, $params)
{
$this->output = '';
$_cmd = $command;
if (count($params) < 1) {
$help = $this->getHelp($command);
return $this->raiseError("$command: missing parameter: $help[0]");
}
 
$packageFile = realpath($params[0]);
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($packageFile, 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);
}
 
$dir = dirname($packageFile);
$dir = substr($dir, strrpos($dir, '/') + 1);
foreach ($files as $file) {
if (!file_exists($file)) {
$file = $dir . DIRECTORY_SEPARATOR . $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;
}
 
function doCvsDiff($command, $options, $params)
{
$this->output = '';
if (sizeof($params) < 1) {
$help = $this->getHelp($command);
return $this->raiseError("$command: missing parameter: $help[0]");
}
 
$file = realpath($params[0]);
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($file, 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;
}
 
function doPackageDependencies($command, $options, $params)
{
// $params[0] -> the PEAR package to list its information
if (count($params) !== 1) {
return $this->raiseError("bad parameter(s), try \"help $command\"");
}
 
$obj = &$this->getPackageFile($this->config, $this->_debug);
if (is_file($params[0]) || strpos($params[0], '.xml') > 0) {
$info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
} else {
$reg = $this->config->getRegistry();
$info = $obj->fromArray($reg->packageInfo($params[0]));
}
 
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' && isset($subd['attribs']['name'])) {
$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);
}
 
function doSign($command, $options, $params)
{
// should move most of this code into PEAR_Packager
// so it'll be easy to implement "pear package --sign"
if (count($params) !== 1) {
return $this->raiseError("bad parameter(s), try \"help $command\"");
}
 
require_once 'System.php';
require_once 'Archive/Tar.php';
 
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 = $this->config->get('temp_dir');
$tmpdir = System::mktemp(' -t "' . $tmpdir . '" -d pearsign');
if (!$tar->extractList('package2.xml 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");
}
 
if (!file_exists("$tmpdir/$packagexml")) {
return $this->raiseError("Extracted file $tmpdir/$packagexml not found.");
}
 
$input = $this->ui->userDialog($command,
array('GnuPG Passphrase'),
array('password'));
if (!isset($input[0])) {
//use empty passphrase
$input[0] = '';
}
 
$devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null';
$gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "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");
}
 
if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) {
return $this->raiseError('failed adding signature to file');
}
 
$this->ui->outputData("Package signed.", $command);
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;
}
 
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);
}
 
$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_array($pf->getUserInfo())) {
foreach ($pf->getUserInfo() as $warning) {
$this->ui->outputData($warning['message']);
}
}
return $this->raiseError($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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Channels.php
New file
0,0 → 1,882
<?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
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Common.php';
 
define('PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS', -500);
 
/**
* PEAR commands for managing channels.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Command_Channels extends PEAR_Command_Common
{
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 create a local channel.xml.
If <channel name> is in the format "<username>:<password>@<channel>" then
<username> and <password> will be set as the login username/password for
<channel>. Use caution when passing the username/password in this way, as
it may allow other users on your computer to briefly view your username/
password via the system\'s process list.
'
),
'channel-login' => array(
'summary' => 'Connects and authenticates to remote channel server',
'shortcut' => 'cli',
'function' => 'doLogin',
'options' => array(),
'doc' => '<channel name>
Log in to a remote channel server. If <channel name> is not supplied,
the default channel is used. 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.',
),
'channel-logout' => array(
'summary' => 'Logs out from the remote channel server',
'shortcut' => 'clo',
'function' => 'doLogout',
'options' => array(),
'doc' => '<channel name>
Logs out from a remote channel server. If <channel name> is not supplied,
the default channel is used. This command does not actually connect to the
remote server, it only deletes the stored username and password from your user
configuration.',
),
);
 
/**
* PEAR_Command_Registry constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
 
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', 'Alias', 'Summary')
);
foreach ($registered as $channel) {
$data['data'][] = array($channel->getName(),
$channel->getAlias(),
$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();
$channels = $reg->getChannels();
 
$success = true;
foreach ($channels as $channel) {
if ($channel->getName() != '__uri') {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->doUpdate('channel-update',
$options,
array($channel->getName()));
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage(), $command);
$success = false;
} else {
$success &= $err;
}
}
}
return $success;
}
 
function doInfo($command, $options, $params)
{
if (count($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();
$tmpdir = $this->config->get('temp_dir');
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$loc = $downloader->downloadHttp($channel, $this->ui, $tmpdir);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError('Cannot open "' . $channel .
'" (' . $loc->getMessage() . ')');
} else {
$contents = implode('', file($loc));
}
} else {
if (!file_exists($params[0])) {
return $this->raiseError('Unknown channel "' . $channel . '"');
}
 
$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';
}
 
$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) {
return $this->raiseError('Serious error: Channel "' . $params[0] .
'" has a corrupted registry entry');
}
 
$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');
if ($chan->supportsREST()) {
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 $i => $mirror) {
$data['data'] = array();
$data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities';
$data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
if ($chan->supportsREST($mirror['attribs']['host'])) {
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' . $i] = $data;
}
}
$this->ui->outputData($d, 'channel-info');
}
 
// }}}
 
function doDelete($command, $options, $params)
{
if (count($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 == 'doc.php.net') {
return $this->raiseError('Cannot delete the doc.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 (count($params) !== 1) {
return $this->raiseError('channel-add: no channel file specified');
}
 
if (strpos($params[0], '://')) {
$downloader = &$this->getDownloader();
$tmpdir = $this->config->get('temp_dir');
if (!file_exists($tmpdir)) {
require_once 'System.php';
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = System::mkdir(array('-p', $tmpdir));
PEAR::staticPopErrorHandling();
if (PEAR::isError($err)) {
return $this->raiseError('channel-add: temp_dir does not exist: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
}
 
if (!is_writable($tmpdir)) {
return $this->raiseError('channel-add: temp_dir is not writable: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
 
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] .
'" (' . $loc->getMessage() . ')');
}
 
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', PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS);
}
 
$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 (count($params) !== 1) {
return $this->raiseError("No channel file specified");
}
 
$tmpdir = $this->config->get('temp_dir');
if (!file_exists($tmpdir)) {
require_once 'System.php';
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = System::mkdir(array('-p', $tmpdir));
PEAR::staticPopErrorHandling();
if (PEAR::isError($err)) {
return $this->raiseError('channel-add: temp_dir does not exist: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
}
 
if (!is_writable($tmpdir)) {
return $this->raiseError('channel-add: temp_dir is not writable: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
 
$reg = &$this->config->getRegistry();
$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("Updating channel \"$params[0]\"", $command);
$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)) {
// Attempt to fall back to https
$this->ui->outputData("Channel \"$params[0]\" is not responding over http://, failed with message: " . $contents->getMessage());
$this->ui->outputData("Trying channel \"$params[0]\" over https:// instead");
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$contents = $dl->downloadHttp('https://' . $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() . '" (' . $contents->getMessage() . ')');
}
}
 
list($contents, $lastmodified) = $contents;
if (!$contents) {
$this->ui->outputData("Channel \"$params[0]\" 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'])) {
return $this->raiseError('ERROR: downloaded channel definition file' .
' for channel "' . $channel->getName() . '" from channel "' .
strtolower($c->getName()) . '"');
}
 
$this->ui->log(0, 'WARNING: 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] .
' (' . $loc->getMessage() . ')');
}
 
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)
{
if (count($params) === 1) {
return $this->raiseError('No channel alias specified');
}
 
if (count($params) !== 2 || (!empty($params[1]) && $params[1]{0} == '-')) {
return $this->raiseError(
'Invalid format, correct is: channel-alias channel alias');
}
 
$reg = &$this->config->getRegistry();
if (!$reg->channelExists($params[0], true)) {
$extra = '';
if ($reg->isAlias($params[0])) {
$extra = ' (use "channel-alias ' . $reg->channelName($params[0]) . ' ' .
strtolower($params[1]) . '")';
}
 
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]) . '"');
}
 
/**
* The channel-discover command
*
* @param string $command command name
* @param array $options option_name => value
* @param array $params list of additional parameters.
* $params[0] should contain a string with either:
* - <channel name> or
* - <username>:<password>@<channel name>
* @return null|PEAR_Error
*/
function doDiscover($command, $options, $params)
{
if (count($params) !== 1) {
return $this->raiseError("No channel server specified");
}
 
// Look for the possible input format "<username>:<password>@<channel>"
if (preg_match('/^(.+):(.+)@(.+)\\z/', $params[0], $matches)) {
$username = $matches[1];
$password = $matches[2];
$channel = $matches[3];
} else {
$channel = $params[0];
}
 
$reg = &$this->config->getRegistry();
if ($reg->channelExists($channel)) {
if (!$reg->isAlias($channel)) {
return $this->raiseError("Channel \"$channel\" is already initialized", PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS);
}
 
return $this->raiseError("A channel alias named \"$channel\" " .
'already exists, aliasing channel "' . $reg->channelName($channel)
. '"');
}
 
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->doAdd($command, $options, array('http://' . $channel . '/channel.xml'));
$this->popErrorHandling();
if (PEAR::isError($err)) {
if ($err->getCode() === PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS) {
return $this->raiseError("Discovery of channel \"$channel\" failed (" .
$err->getMessage() . ')');
}
// Attempt fetch via https
$this->ui->outputData("Discovering channel $channel over http:// failed with message: " . $err->getMessage());
$this->ui->outputData("Trying to discover channel $channel over https:// instead");
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->doAdd($command, $options, array('https://' . $channel . '/channel.xml'));
$this->popErrorHandling();
if (PEAR::isError($err)) {
return $this->raiseError("Discovery of channel \"$channel\" failed (" .
$err->getMessage() . ')');
}
}
 
// Store username/password if they were given
// Arguably we should do a logintest on the channel here, but since
// that's awkward on a REST-based channel (even "pear login" doesn't
// do it for those), and XML-RPC is deprecated, it's fairly pointless.
if (isset($username)) {
$this->config->set('username', $username, 'user', $channel);
$this->config->set('password', $password, 'user', $channel);
$this->config->store();
$this->ui->outputData("Stored login for channel \"$channel\" using username \"$username\"", $command);
}
 
$this->ui->outputData("Discovery of channel \"$channel\" succeeded", $command);
}
 
/**
* 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();
 
// If a parameter is supplied, use that as the channel to log in to
$channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel');
 
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
 
$server = $this->config->get('preferred_mirror', null, $channel);
$username = $this->config->get('username', null, $channel);
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);
 
$ourfile = $this->config->getConfFile('user');
if (!$ourfile) {
$ourfile = $this->config->getConfFile('system');
}
 
$this->config->set('username', $username, 'user', $channel);
$this->config->set('password', $password, 'user', $channel);
 
if ($chan->supportsREST()) {
$ok = true;
}
 
if ($ok !== true) {
return $this->raiseError('Login failed!');
}
 
$this->ui->outputData("Logged in.", $command);
// avoid changing any temporary settings changed with -d
$ourconfig = new PEAR_Config($ourfile, $ourfile);
$ourconfig->set('username', $username, 'user', $channel);
$ourconfig->set('password', $password, 'user', $channel);
$ourconfig->store();
 
return true;
}
 
/**
* 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();
 
// If a parameter is supplied, use that as the channel to log in to
$channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel');
 
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
 
$server = $this->config->get('preferred_mirror', null, $channel);
$this->ui->outputData("Logging out from $server.", $command);
$this->config->remove('username', 'user', $channel);
$this->config->remove('password', 'user', $channel);
$this->config->store();
return true;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Remote.php
New file
0,0 → 1,809
<?php
/**
* PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download,
* clear-cache commands)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Remote extends PEAR_Command_Common
{
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(
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'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',
),
'allchannels' => array(
'shortopt' => 'a',
'doc' => 'search packages from all known channels',
),
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'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',
),
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'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 REST cache. See also the cache_ttl configuration
parameter.
',
),
);
 
/**
* PEAR_Command_Remote constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($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);
$mirror = $this->config->get('preferred_mirror', null,
$channel);
$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 "' . PEAR_RUNTYPE . ' channel-update ' . $channel .
'" to update');
}
}
 
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;
}
 
$mirror = $this->config->get('preferred_mirror');
if ($chan->supportsREST($mirror) && $base = $chan->getBaseURL('REST1.0', $mirror)) {
$rest = &$this->config->getREST('1.0', array());
$info = $rest->packageInfo($base, $parsed['package'], $channel);
}
 
if (!isset($info)) {
return $this->raiseError('No supported protocol was found');
}
 
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;
}
 
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)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
 
$this->config->set('default_channel', $channel);
}
 
$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;
}
 
$available = array();
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, true, false, false, $chan->getName());
} 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, true, false, false, $chan->getName());
}
 
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'),
'channel' => $channel
);
 
if (count($available) == 0) {
$data = '(no packages available yet)';
} else {
foreach ($available as $name => $info) {
$version = (isset($info['stable']) && $info['stable']) ? $info['stable'] : '-n/a-';
$data['data'][] = array($name, $version);
}
}
$this->ui->outputData($data, $command);
$this->config->set('default_channel', $savechannel);
return true;
}
 
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)) {
return $this->raiseError("Channel \"$channel\" does not exist");
}
 
$this->config->set('default_channel', $channel);
}
 
$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, false, false, $chan->getName());
} 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, false, false, $chan->getName());
}
 
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 [Channel ' . $channel . ']:',
'border' => true,
'headline' => array('Package', 'Latest', 'Local'),
'channel' => $channel,
);
 
if (isset($options['channelinfo'])) {
// add full channelinfo
$data['caption'] = 'Channel ' . $channel . ' All packages:';
$data['headline'] = array('Channel', 'Package', 'Latest', 'Local',
'Description', 'Dependencies');
}
$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;
}
 
if (isset($options['channelinfo'])) {
// add full channelinfo
if ($info['stable'] === $info['unstable']) {
$state = $info['state'];
} else {
$state = 'stable';
}
$latest = $info['stable'].' ('.$state.')';
$local = '';
if (isset($installed['version'])) {
$inst_state = $reg->packageInfo($name, 'release_state', $channel);
$local = $installed['version'].' ('.$inst_state.')';
}
 
$packageinfo = array(
$channel,
$name,
$latest,
$local,
isset($desc) ? $desc : null,
isset($info['deps']) ? $info['deps'] : null,
);
} else {
$packageinfo = 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,
);
}
$data['data'][$info['category']][] = $packageinfo;
}
 
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;
}
 
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');
}
 
$channelinfo = isset($options['channelinfo']);
$reg = &$this->config->getRegistry();
if (isset($options['allchannels'])) {
// search all channels
unset($options['allchannels']);
$channels = $reg->getChannels();
$errors = array();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
foreach ($channels as $channel) {
if ($channel->getName() != '__uri') {
$options['channel'] = $channel->getName();
$ret = $this->doSearch($command, $options, $params);
if (PEAR::isError($ret)) {
$errors[] = $ret;
}
}
}
 
PEAR::staticPopErrorHandling();
if (count($errors) !== 0) {
// for now, only give first error
return PEAR::raiseError($errors[0]);
}
 
return true;
}
 
$savechannel = $channel = $this->config->get('default_channel');
$package = strtolower($params[0]);
$summary = isset($params[1]) ? $params[1] : false;
if (isset($options['channel'])) {
$reg = &$this->config->getRegistry();
$channel = $options['channel'];
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
 
$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());
$available = $rest->listAll($base, false, false, $package, $summary, $chan->getName());
}
 
if (PEAR::isError($available)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError($available);
}
 
if (!$available && !$channelinfo) {
// clean exit when not found, no error !
$data = 'no packages found that match pattern "' . $package . '", for channel '.$channel.'.';
$this->ui->outputData($data);
$this->config->set('default_channel', $channel);
return true;
}
 
if ($channelinfo) {
$data = array(
'caption' => 'Matched packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Channel', 'Package', 'Stable/(Latest)', 'Local'),
'channel' => $channel
);
} else {
$data = array(
'caption' => 'Matched packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Stable/(Latest)', 'Local'),
'channel' => $channel
);
}
 
if (!$available && $channelinfo) {
unset($data['headline']);
$data['data'] = 'No packages found that match pattern "' . $package . '".';
$available = array();
}
 
foreach ($available as $name => $info) {
$installed = $reg->packageInfo($name, null, $channel);
$desc = $info['summary'];
if (isset($params[$name]))
$desc .= "\n\n".$info['description'];
 
if (!isset($info['stable']) || !$info['stable']) {
$version_remote = 'none';
} else {
if ($info['unstable']) {
$version_remote = $info['unstable'];
} else {
$version_remote = $info['stable'];
}
$version_remote .= ' ('.$info['state'].')';
}
$version = is_array($installed['version']) ? $installed['version']['release'] :
$installed['version'];
if ($channelinfo) {
$packageinfo = array(
$channel,
$name,
$version_remote,
$version,
$desc,
);
} else {
$packageinfo = array(
$name,
$version_remote,
$version,
$desc,
);
}
$data['data'][$info['category']][] = $packageinfo;
}
 
$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;
}
 
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);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$e = $downloader->setDownloadDir(getcwd());
PEAR::staticPopErrorHandling();
if (PEAR::isError($e)) {
return $this->raiseError('Current directory is not writeable, cannot download');
}
 
$errors = array();
$downloaded = array();
$err = $downloader->download($params);
if (PEAR::isError($err)) {
return $err;
}
 
$errors = $downloader->getErrorMsgs();
if (count($errors)) {
foreach ($errors as $error) {
if ($error !== null) {
$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;
}
}
 
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);
$state = empty($params[0]) ? $this->config->get('preferred_state') : $params[0];
 
$caption = $channel . ' Available Upgrades';
$chan = $reg->getChannel($channel);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
 
$latest = array();
$base2 = false;
$preferred_mirror = $this->config->get('preferred_mirror');
if ($chan->supportsREST($preferred_mirror) &&
(
($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror))
|| ($base = $chan->getBaseURL('REST1.0', $preferred_mirror))
)
 
) {
if ($base2) {
$rest = &$this->config->getREST('1.3', array());
$base = $base2;
} else {
$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();
}
 
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'),
'channel' => $channel
);
 
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 (isset($options['channelinfo'])) {
if (empty($data['data'])) {
unset($data['headline']);
if (count($inst) == 0) {
$data['data'] = '(no packages installed)';
} else {
$data['data'] = '(no upgrades available)';
}
}
$this->ui->outputData($data, $command);
} else {
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;
}
 
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('/rest.cache(file|id)\\z/', $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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Build.php
New file
0,0 → 1,84
<?php
/**
* PEAR_Command_Auth (build command)
*
* PHP versions 4 and 5
*
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Build extends PEAR_Command_Common
{
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.'
),
);
 
/**
* PEAR_Command_Build constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
 
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;
}
 
function buildCallback($what, $data)
{
if (($what == 'cmdoutput' && $this->debug > 1) ||
($what == 'output' && $this->debug > 0)) {
$this->ui->outputData(rtrim($data), 'build');
}
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Auth.php
New file
0,0 → 1,80
<?php
/**
* PEAR_Command_Auth (login, logout commands)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
* @deprecated since 1.8.0alpha1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Channels.php';
 
/**
* PEAR commands for login/logout
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
* @deprecated since 1.8.0alpha1
*/
class PEAR_Command_Auth extends PEAR_Command_Channels
{
var $commands = array(
'login' => array(
'summary' => 'Connects and authenticates to remote server [Deprecated in favor of channel-login]',
'shortcut' => 'li',
'function' => 'doLogin',
'options' => array(),
'doc' => '<channel name>
WARNING: This function is deprecated in favor of using channel-login
 
Log in to a remote channel server. If <channel name> is not supplied,
the default channel is used. 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 [Deprecated in favor of channel-logout]',
'shortcut' => 'lo',
'function' => 'doLogout',
'options' => array(),
'doc' => '
WARNING: This function is deprecated in favor of using channel-logout
 
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.',
)
 
);
 
/**
* PEAR_Command_Auth constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
{
parent::__construct($ui, $config);
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Remote.xml
New file
0,0 → 1,109
<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>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</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>
<allchannels>
<shortopt>a</shortopt>
<doc>search packages from all known channels</doc>
</allchannels>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</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>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Channels.xml
New file
0,0 → 1,123
<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>
<doc>will force download of new channel.xml if an existing channel name is used</doc>
<arg>CHANNEL</arg>
</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 a local channel.xml.
If &lt;channel name&gt; is in the format &quot;&lt;username&gt;:&lt;password&gt;@&lt;channel&gt;&quot; then
&lt;username&gt; and &lt;password&gt; will be set as the login username/password for
&lt;channel&gt;. Use caution when passing the username/password in this way, as
it may allow other users on your computer to briefly view your username/
password via the system&#039;s process list.
</doc>
</channel-discover>
<channel-login>
<summary>Connects and authenticates to remote channel server</summary>
<function>doLogin</function>
<shortcut>cli</shortcut>
<options />
<doc>&lt;channel name&gt;
Log in to a remote channel server. If &lt;channel name&gt; is not supplied,
the default channel is used. 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>
</channel-login>
<channel-logout>
<summary>Logs out from the remote channel server</summary>
<function>doLogout</function>
<shortcut>clo</shortcut>
<options />
<doc>&lt;channel name&gt;
Logs out from a remote channel server. If &lt;channel name&gt; is not supplied,
the default channel is used. This command does not actually connect to the
remote server, it only deletes the stored username and password from your user
configuration.</doc>
</channel-logout>
</commands>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command/Package.xml
New file
0,0 → 1,237
<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>
<shortopt></shortopt>
<doc>Report only whether the files differ, no details</doc>
</brief>
<dry-run>
<shortopt>n</shortopt>
<doc>Don&#039;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>
<svntag>
<summary>Set SVN Release Tag</summary>
<function>doSvnTag</function>
<shortcut>sv</shortcut>
<options>
<quiet>
<shortopt>q</shortopt>
<doc>Be quiet</doc>
</quiet>
<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&#039;t do anything, just pretend</doc>
</dry-run>
</options>
<doc>&lt;package.xml&gt; [files...]
Sets a SVN 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 svntag once, but before the tarball is released to the public,
use the &quot;slide&quot; 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.
</doc>
</svntag>
<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&#039;t do anything, just pretend</doc>
</dry-run>
</options>
<doc>&lt;package.xml&gt; [files...]
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.
 
to include files (such as a second package.xml, or tests not included in the
release), pass them as additional parameters.
</doc>
</cvstag>
<package-dependencies>
<summary>Show package dependencies</summary>
<function>doPackageDependencies</function>
<shortcut>pd</shortcut>
<options />
<doc>&lt;package-file&gt; or &lt;package.xml&gt; or &lt;install-package-name&gt;
List all dependencies the package has.
Can take a tgz / tar file, package.xml or a package name of an installed package.</doc>
</package-dependencies>
<sign>
<summary>Sign a package distribution file</summary>
<function>doSign</function>
<shortcut>si</shortcut>
<options>
<verbose>
<shortopt>v</shortopt>
<doc>Display GnuPG output</doc>
</verbose>
</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>
<doc>Use FILE as RPM spec file template</doc>
<arg>FILE</arg>
</spec-template>
<rpm-pkgname>
<shortopt>p</shortopt>
<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>
<arg>FORMAT</arg>
</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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Common.php
New file
0,0 → 1,838
<?php
/**
* PEAR_Common, the base class for the PEAR Installer
*
* PHP versions 4 and 5
*
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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';
 
/**
* 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 . '\\z/');
 
// 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 . '\\z/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 .
'\\z/');
 
define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+');
define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '\\z/');
 
// 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 . '\\z/i');
 
define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/('
. _PEAR_COMMON_PACKAGE_NAME_PREG . ')');
define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '\\z/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 . '\\z/');
 
/**
* 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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
{
/**
* User Interface object (PEAR_Frontend_* class). If null,
* the log() method uses print.
* @var object
*/
var $ui = null;
 
/**
* Configuration object (PEAR_Config).
* @var PEAR_Config
*/
var $config = null;
 
/** 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();
 
var $current_path = null;
 
/**
* Flag variable used to mark a valid package file
* @var boolean
* @access private
*/
var $_validPackageFile;
 
/**
* PEAR_Common constructor
*
* @access public
*/
function __construct()
{
parent::__construct();
$this->config = &PEAR_Config::singleton();
$this->debug = $this->config->get('verbose');
}
 
/**
* 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);
}
}
}
 
/**
* 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);
}
 
/**
* 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)
{
// Only used in Installer - move it there ?
$this->log(2, "+ create dir $dir");
if (!class_exists('System')) {
require_once 'System.php';
}
return System::mkDir(array('-p', $dir));
}
 
/**
* Logging method.
*
* @param int $level log level (0 is quiet, higher is noisier)
* @param string $msg message to write to the log
*
* @return void
*/
public 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";
}
}
}
 
/**
* 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 = '')
{
$topt = $tmpdir ? array('-t', $tmpdir) : 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;
}
 
/**
* 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;
}
 
/**
* 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);
}
 
/**
* Get the valid roles for a PEAR package maintainer
*
* @return array
*/
public static function getUserRoles()
{
return $GLOBALS['_PEAR_Common_maintainer_roles'];
}
 
/**
* Get the valid package release states of packages
*
* @return array
*/
public static function getReleaseStates()
{
return $GLOBALS['_PEAR_Common_release_states'];
}
 
/**
* Get the implemented dependency types (php, ext, pkg etc.)
*
* @return array
*/
public static function getDependencyTypes()
{
return $GLOBALS['_PEAR_Common_dependency_types'];
}
 
/**
* Get the implemented dependency relations (has, lt, ge etc.)
*
* @return array
*/
public static function getDependencyRelations()
{
return $GLOBALS['_PEAR_Common_dependency_relations'];
}
 
/**
* Get the implemented file roles
*
* @return array
*/
public static function getFileRoles()
{
return $GLOBALS['_PEAR_Common_file_roles'];
}
 
/**
* Get the implemented file replacement types in
*
* @return array
*/
public static function getReplacementTypes()
{
return $GLOBALS['_PEAR_Common_replacement_types'];
}
 
/**
* Get the implemented file replacement types in
*
* @return array
*/
public static function getProvideTypes()
{
return $GLOBALS['_PEAR_Common_provide_types'];
}
 
/**
* Get the implemented file replacement types in
*
* @return array
*/
public static function getScriptPhases()
{
return $GLOBALS['_PEAR_Common_script_phases'];
}
 
/**
* 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);
}
 
/**
* 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);
}
 
/**
* @param string $path relative or absolute include path
* @return boolean
*/
public 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;
}
 
function _postProcessChecks($pf)
{
if (!PEAR::isError($pf)) {
return $this->_postProcessValidPackagexml($pf);
}
 
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
 
return $pf;
}
 
/**
* 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);
return $this->_postProcessChecks($pf);
}
 
/**
* 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);
return $this->_postProcessChecks($pf);
}
 
/**
* 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);
return $this->_postProcessChecks($pf);
}
 
/**
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @return array
*/
function _postProcessValidPackagexml(&$pf)
{
if (!is_a($pf, 'PEAR_PackageFile_v2')) {
$this->pkginfo = $pf->toArray();
return $this->pkginfo;
}
 
// 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'], $arr['xsdversion'], $arr['contents'], $arr['compatible'],
$arr['channel'], $arr['uri'], $arr['dependencies'], $arr['phprelease'],
$arr['extsrcrelease'], $arr['zendextsrcrelease'], $arr['extbinrelease'],
$arr['zendextbinrelease'], $arr['bundle'], $arr['lead'], $arr['developer'],
$arr['helper'], $arr['contributor']);
$arr['filelist'] = $pf->getFilelist();
$this->pkginfo = $arr;
return $arr;
}
 
/**
* 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;
}
 
/**
* 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);
}
 
/**
* 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;
}
 
/**
* 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);
}
}
 
/**
* Analyze the source code of the given PHP file
*
* @param string Filename of the PHP file
* @return mixed
* @access public
*/
function analyzeSourceCode($file)
{
if (!class_exists('PEAR_PackageFile_v2_Validator')) {
require_once 'PEAR/PackageFile/v2/Validator.php';
}
 
$a = new PEAR_PackageFile_v2_Validator;
return $a->analyzeSourceCode($file);
}
 
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,
);
}
 
/**
* 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
* @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
* @param false|string $channel Channel to use for retrieving
* authentication
*
* @return mixed 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.
* If $lastmodified was given and the there are no changes,
* boolean false is returned.
*
* @access public
*/
function downloadHttp(
$url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null,
$accept = false, $channel = false
) {
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
return PEAR_Downloader::_downloadHttp(
$this, $url, $ui, $save_dir, $callback, $lastmodified,
$accept, $channel
);
}
}
 
require_once 'PEAR/Config.php';
require_once 'PEAR/PackageFile.php';
/branches/v1.3-critias/bibliotheque/pear/PEAR/Validate.php
New file
0,0 → 1,625
<?php
/**
* PEAR_Validate
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 . '\\z/', $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_]+)*\\z/', $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
*/
public static function validGroupName($name)
{
return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/', $name);
}
 
/**
* Determine whether $state represents a valid stability level
* @param string
* @return bool
* @final
*/
public static function validState($state)
{
return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable'));
}
 
/**
* Get a list of valid stability levels
* @return array
* @final
*/
public static 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
* @final
*/
public static 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();
$a = explode('.', $version);
$test = array_shift($a);
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;
}
 
$result = preg_match('|\d{2}\:\d{2}\:\d{2}|', $this->_packagexml->getTime(), $matches);
if ($result === false || empty($matches)) {
$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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Frontend/CLI.php
New file
0,0 → 1,750
<?php
/**
* PEAR_Frontend_CLI
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Frontend_CLI extends PEAR_Frontend
{
/**
* 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' => '',
);
 
function __construct()
{
parent::__construct();
$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) {
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
}
}
 
/**
* @param object PEAR_Error object
*/
function displayError($e)
{
return $this->_displayLine($e->getMessage());
}
 
/**
* @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();
exit(1);
}
 
$raised = false;
foreach (debug_backtrace() as $i => $frame) {
if (!$raised) {
if (isset($frame['class'])
&& strtolower($frame['class']) == 'pear'
&& strtolower($frame['function']) == 'raiseerror'
) {
$raised = true;
} else {
continue;
}
}
 
$frame['class'] = !isset($frame['class']) ? '' : $frame['class'];
$frame['type'] = !isset($frame['type']) ? '' : $frame['type'];
$frame['function'] = !isset($frame['function']) ? '' : $frame['function'];
$frame['line'] = !isset($frame['line']) ? '' : $frame['line'];
$this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]");
}
}
}
 
exit(1);
}
 
/**
* 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');
return;
}
 
$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)) {
return;
}
 
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;
}
}
}
 
$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 = $prompts = $types = array();
foreach ($params as $param) {
$prompts[$param['name']] = $param['prompt'];
$types[$param['name']] = $param['type'];
$answers[$param['name']] = isset($param['default']) ? $param['default'] : '';
}
 
$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;
}
 
function userDialog($command, $prompts, $types = array(), $defaults = array(), $screensize = 20)
{
if (!is_array($prompts)) {
return array();
}
 
$testprompts = array_keys($prompts);
$result = $defaults;
 
reset($prompts);
if (count($prompts) === 1) {
foreach ($prompts as $key => $prompt) {
$type = $types[$key];
$default = @$defaults[$key];
print "$prompt ";
if ($default) {
print "[$default] ";
}
print ": ";
 
$line = fgets(STDIN, 2048);
$result[$key] = ($default && trim($line) == '') ? $default : trim($line);
}
 
return $result;
}
 
$first_run = true;
while (true) {
$descLength = max(array_map('strlen', $prompts));
$descFormat = "%-{$descLength}s";
$last = count($prompts);
 
$i = 0;
foreach ($prompts as $n => $var) {
$res = isset($result[$n]) ? $result[$n] : null;
printf("%2d. $descFormat : %s\n", ++$i, $prompts[$n], $res);
}
print "\n1-$last, 'all', 'abort', or Enter to continue: ";
 
$tmp = trim(fgets(STDIN, 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(STDIN, 1024));
if ($tmp !== '') {
$result[$var] = $tmp;
}
} elseif ($tmp == 'all') {
foreach ($prompts as $var => $desc) {
$current = $result[$var];
print "$desc [$current] : ";
$tmp = trim(fgets(STDIN, 1024));
if (trim($tmp) !== '') {
$result[$var] = trim($tmp);
}
}
}
 
$first_run = false;
}
 
return $result;
}
 
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;
}
 
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 (is_array($data) && 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(is_array($data) ? $data['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)));
}
 
$packages = array();
foreach($data['data'] as $category) {
foreach($category as $name => $pkg) {
$packages[$pkg[0]] = $pkg;
}
}
 
$p = array_keys($packages);
natcasesort($p);
foreach ($p as $name) {
$this->_tableRow($packages[$name], null, array(1 => array('wrap' => 55)));
}
 
$this->_endTable();
break;
case 'list-all':
if (!isset($data['data'])) {
$this->_displayLine('No packages in channel');
break;
}
 
$this->_startTable($data);
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
}
 
$packages = array();
foreach($data['data'] as $category) {
foreach($category as $name => $pkg) {
$packages[$pkg[0]] = $pkg;
}
}
 
$p = array_keys($packages);
natcasesort($p);
foreach ($p as $name) {
$pkg = $packages[$name];
unset($pkg[4], $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);
}
 
if (is_array($data['data'])) {
foreach($data['data'] as $row) {
$this->_tableRow($row, null, $opts);
}
} else {
$this->_tableRow(array($data['data']), null, $opts);
}
$this->_endTable();
} else {
$this->_displayLine($data);
}
}
}
}
 
function log($text, $append_crlf = true)
{
if ($append_crlf) {
return $this->_displayLine($text);
}
 
return $this->_display($text);
}
 
function bold($text)
{
if (empty($this->term['bold'])) {
return strtoupper($text);
}
 
return $this->term['bold'] . $text . $this->term['normal'];
}
 
function _displayHeading($title)
{
print $this->lp.$this->bold($title)."\n";
print $this->lp.str_repeat("=", strlen($title))."\n";
}
 
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;
}
 
function _tableRow($columns, $rowparams = array(), $colparams = array())
{
$highest = 1;
for ($i = 0; $i < count($columns); $i++) {
$col = &$columns[$i];
if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) {
$col = wordwrap($col, $colparams[$i]['wrap']);
}
 
if (strpos($col, "\n") !== false) {
$multiline = explode("\n", $col);
$w = 0;
foreach ($multiline as $n => $line) {
$len = strlen($line);
if ($len > $w) {
$w = $len;
}
}
$lines = count($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 (count($columns) > $this->params['ncols']) {
$this->params['ncols'] = count($columns);
}
 
$new_row = array(
'data' => $columns,
'height' => $highest,
'rowparams' => $rowparams,
'colparams' => $colparams,
);
$this->params['table_data'][] = $new_row;
}
 
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 < count($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 < count($data); $c++) {
$rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]);
if (count($rowlines[$c]) < $height) {
$rowlines[$c] = array_pad($rowlines[$c], $height, '');
}
}
} else {
for ($c = 0; $c < count($data); $c++) {
$rowlines[$c] = array($data[$c]);
}
}
 
for ($r = 0; $r < $height; $r++) {
$rowtext = '';
for ($c = 0; $c < count($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);
}
}
 
function _displayLine($text)
{
print "$this->lp$text\n";
}
 
function _display($text)
{
print $text;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/PackageFile.php
New file
0,0 → 1,491
<?php
/**
* PEAR_PackageFile, package.xml parsing utility class
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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;
 
var $_logger = false;
/**
* @var boolean
*/
var $_rawReturn = false;
 
/**
* helper for extracting Archive_Tar errors
* @var array
* @access private
*/
var $_extractErrors = array();
 
/**
*
* @param PEAR_Config $config
* @param ? $debug
* @param string @tmpdir Optional temporary directory for uncompressing
* files
*/
function __construct(&$config, $debug = false)
{
$this->_config = $config;
$this->_debug = $debug;
}
 
/**
* 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;
}
 
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->_config->get('verbose') > 0
&& $this->_logger && $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;
}
 
if ($this->_logger && $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;
} 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)) {
$a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed',
2, null, null, $pf->getValidationWarnings());
return $a;
}
 
if ($this->_logger && $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;
}
}
 
/**
* 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;
}
 
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 (preg_match('/package.xml$/', $name, $match)) {
$xml = $name;
break;
}
}
 
$tmpdir = System::mktemp('-t "' . $this->_config->get('temp_dir') . '" -d pear');
if ($tmpdir === false) {
$ret = PEAR::raiseError("there was a problem with getting the configured temp directory");
return $ret;
}
 
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 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)
{
$fp = 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);
}
}
 
return $info;
}
 
$info = PEAR::raiseError("Cannot open '$info' for parsing");
return $info;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer.php
New file
0,0 → 1,1794
<?php
/**
* PEAR_Installer
*
* PHP versions 4 and 5
*
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct(&$ui)
{
parent::__construct($ui, array(), null);
$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 'src':
case 'extsrc':
$this->source_files++;
return;
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;
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 (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) {
return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED);
}
// }}}
 
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_]+\\z/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);
}
 
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'));
}
 
if ($atts['role'] != 'src') {
$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");
}
}
}
}
// }}}
 
if ($atts['role'] == 'src') {
rename($dest_file, $final_dest_file);
$this->log(2, "renamed source file $dest_file to $final_dest_file");
} else {
$this->addFileOperation("rename", array($dest_file, $final_dest_file,
$atts['role'] == 'ext'));
}
}
 
// Store the full path where the file was installed for easy unistall
if ($atts['role'] != 'script') {
$loc = $this->config->get($atts['role'] . '_dir');
} else {
$loc = $this->config->get('bin_dir');
}
 
if ($atts['role'] != 'src') {
$this->addFileOperation("installed_as", array($file, $installed_as,
$loc,
dirname(substr($installedas_dest_file, strlen($loc)))));
}
 
//$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, &$real_atts, $tmp_path, $options)
{
$atts = $real_atts;
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;
}
 
list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info;
if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) {
return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED);
}
 
$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)) {
// Make sure the original md5 sum matches with expected
if (strtolower($md5sum) === strtolower($attribs['md5sum'])) {
$this->log(2, "md5sum ok: $final_dest_file");
 
if (isset($contents)) {
// set md5 sum based on $content in case any tasks were run.
$real_atts['attribs']['md5sum'] = md5($contents);
}
} 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);
}
 
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");
}
}
}
} else {
$real_atts['attribs']['md5sum'] = md5_file($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'));
}
 
if ($attribs['role'] != 'src') {
$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");
}
}
}
}
// }}}
 
if ($attribs['role'] == 'src') {
rename($dest_file, $final_dest_file);
$this->log(2, "renamed source file $dest_file to $final_dest_file");
} else {
$this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension()));
}
}
 
// Store the full path where the file was installed for easy uninstall
if ($attribs['role'] != 'src') {
$loc = $this->config->get($role->getLocationConfig(), null, $channel);
$this->addFileOperation('installed_as', array($file, $installed_as,
$loc,
dirname(substr($installed_as, strlen($loc)))));
}
 
//$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()
{
// {{{ first, check permissions and such manually
$errors = array();
foreach ($this->file_operations as $key => $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);
}
}
 
/* Verify we are not deleting a file owned by another package
* This can happen when a file moves from package A to B in
* an upgrade ala http://pear.php.net/17986
*/
$info = array(
'package' => strtolower($this->pkginfo->getName()),
'channel' => strtolower($this->pkginfo->getChannel()),
);
$result = $this->_registry->checkFileMap($data[0], $info, '1.1');
if (is_array($result)) {
$res = array_diff($result, $info);
if (!empty($res)) {
$new = $this->_registry->getPackage($result[1], $result[0]);
$this->file_operations[$key] = false;
$pkginfoName = $this->pkginfo->getName();
$newChannel = $new->getChannel();
$newPackage = $new->getName();
$this->log(3, "file $data[0] was scheduled for removal from $pkginfoName but is owned by $newChannel/$newPackage, removal has been cancelled.");
}
}
}
break;
}
 
}
// }}}
 
$n = count($this->file_operations);
$this->log(2, "about to commit $n file operations for " . $this->pkginfo->getName());
 
$m = count($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':
$test = file_exists($data[1]) ? @unlink($data[1]) : 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]) && dirname($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);
}
 
// }}}
// {{{ _parsePackageXml()
 
function _parsePackageXml(&$descfile)
{
// Parse xml file -----------------------------------------------
$pkg = new PEAR_PackageFile($this->config, $this->debug);
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');
}
 
$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();
} else {
$descfile = $pkgfile;
$pkg = $this->_parsePackageXml($descfile);
if (PEAR::isError($pkg)) {
return $pkg;
}
}
 
$tmpdir = dirname($descfile);
if (realpath($descfile) != realpath($pkgfile)) {
// Use the temp_dir since $descfile can contain the download dir path
$tmpdir = $this->config->get('temp_dir', null, 'pear.php.net');
$tmpdir = System::mktemp('-d -t "' . $tmpdir . '"');
 
$tar = new Archive_Tar($pkgfile);
if (!$tar->extract($tmpdir)) {
return $this->raiseError("unable to unpack $pkgfile");
}
}
 
$pkgname = $pkg->getName();
$channel = $pkg->getChannel();
 
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'])) {
$regdir = $this->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$this->_options['packagingroot']);
 
$metadata_dir = $this->config->get('metadata_dir', null, 'pear.php.net');
if ($metadata_dir) {
$metadata_dir = $this->_prependPath(
$metadata_dir,
$this->_options['packagingroot']);
}
$packrootphp_dir = $this->_prependPath(
$this->config->get('php_dir', null, $channel),
$this->_options['packagingroot']);
 
$installregistry = new PEAR_Registry($regdir, false, false, $metadata_dir);
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())
) {
if (isset($parentreg['filelist'][$file])) {
unset($parentreg['filelist'][$file]);
} else{
$pos = strpos($file, '/');
$basedir = substr($file, 0, $pos);
$file2 = substr($file, $pos + 1);
if (isset($parentreg['filelist'][$file2]['baseinstalldir'])
&& $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir
) {
unset($parentreg['filelist'][$file2]);
}
}
 
unset($test[$file]);
}
} else {
if (strtolower($param->getChannel()) != 'pear.php.net') {
continue;
}
 
if (strtolower($info) == strtolower($param->getPackage())) {
if (isset($parentreg['filelist'][$file])) {
unset($parentreg['filelist'][$file]);
} else{
$pos = strpos($file, '/');
$basedir = substr($file, 0, $pos);
$file2 = substr($file, $pos + 1);
if (isset($parentreg['filelist'][$file2]['baseinstalldir'])
&& $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir
) {
unset($parentreg['filelist'][$file2]);
}
}
 
unset($test[$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 (count($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);
}
 
if (!isset($options['soft'])) {
$this->log(0, "WARNING: $msg");
}
}
}
}
// }}}
 
$this->startFileTransaction();
 
$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['upgrade']) && empty($options['soft'])) {
// checks to do only when installing new packages
if (empty($options['force']) && $test) {
return $this->raiseError("$channel/$pkgname is already installed");
}
} else {
// Upgrade
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)");
}
}
}
 
// Do cleanups for upgrade and install, remove old release's files first
if ($test && 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);
}
 
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");
}
}
 
if (substr($pkgfile, -4) != '.xml') {
$tmpdir .= 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;
}
 
$p = &$installregistry->getPackage($pkgname, $channel);
$dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false;
 
$pkg->resetFilelist();
$pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(),
'version', $pkg->getChannel()));
foreach ($filelist as $file => $atts) {
$this->expectError(PEAR_INSTALLER_FAILED);
if ($pkg->getPackagexmlVersion() == '1.0') {
$res = $this->_installFile($file, $atts, $tmpdir, $options);
} else {
$res = $this->_installFile2($pkg, $file, $atts, $tmpdir, $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);
}
 
if (!isset($options['soft'])) {
$this->log(0, "Warning: " . $res->getMessage());
}
}
 
$real = isset($atts['attribs']) ? $atts['attribs'] : $atts;
if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') {
// 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 {
if ($dirtree) {
$this->startFileTransaction();
// attempt to delete empty directories
uksort($dirtree, array($this, '_sortDirs'));
foreach($dirtree as $dir => $notused) {
$this->addFileOperation('rmdir', array($dir));
}
$this->commitFileTransaction();
}
 
$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);
$extra = $copyto != $dest ? " as '$copyto'" : '';
$this->log(1, "Installing '$dest'$extra");
 
$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)");
}
}
}
 
 
$data = 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'],
);
 
if ($filelist->getPackageXmlVersion() == '1.0') {
$filelist->installedFile($bn, $data);
} else {
$filelist->installedFile($bn, array('attribs' => $data));
}
}
}
 
// }}}
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())
{
$installRoot = isset($options['installroot']) ? $options['installroot'] : '';
$this->config->setInstallRoot($installRoot);
 
$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);
}
 
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);
}
 
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");
}
 
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: uninstall failed');
}
} else {
$this->startFileTransaction();
$dirtree = $pkg->getDirTree();
if ($dirtree === false) {
$this->configSet('default_channel', $savechannel);
return $this->_registry->deletePackage($package, $channel);
}
 
// attempt to delete empty directories
uksort($dirtree, array($this, '_sortDirs'));
foreach($dirtree as $dir => $notused) {
$this->addFileOperation('rmdir', array($dir));
}
 
if (!$this->commitFileTransaction()) {
$this->rollbackFileTransaction();
if (!isset($options['ignore-errors'])) {
return $this->raiseError("uninstall failed");
}
 
if (!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');
}
}
 
// }}}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Exception.php
New file
0,0 → 1,388
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
/**
* PEAR_Exception
*
* PHP versions 4 and 5
*
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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(),
'file' => 'unknown',
'line' => 'unknown');
} 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(),
'file' => 'unknown',
'line' => 'unknown');
} 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 style="border: 1px" cellspacing="0">' . "\n";
foreach ($causes as $i => $cause) {
$html .= '<tr><td colspan="3" style="background: #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" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n"
. '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
 
foreach ($trace as $k => $v) {
$html .= '<tr><td style="text-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 style="text-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();
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Downloader.php
New file
0,0 → 1,1788
<?php
/**
* PEAR_Downloader, the PEAR Installer's download utility class
*
* PHP versions 4 and 5
*
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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;
 
/**
* 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;
 
/**
* List of methods that can be called both statically and non-statically.
* @var array
*/
protected static $bivalentMethods = array(
'setErrorHandling' => true,
'raiseError' => true,
'throwError' => true,
'pushErrorHandling' => true,
'popErrorHandling' => true,
'downloadHttp' => true,
);
 
/**
* @param PEAR_Frontend_*
* @param array
* @param PEAR_Config
*/
function __construct($ui = null, $options = array(), $config = null)
{
parent::__construct();
$this->_options = $options;
if ($config !== null) {
$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 ($config !== null) {
if (isset($this->_options['installroot'])) {
$this->config->setInstallRoot($this->_options['installroot']);
}
$this->_registry = &$config->getRegistry();
}
 
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';
}
 
$tmpdir = $this->config->get('temp_dir');
$tmp = System::mktemp('-d -t "' . $tmpdir . '"');
$a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false);
PEAR::popErrorHandling();
if (PEAR::isError($a)) {
// Attempt to fallback to https automatically.
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$this->log(1, 'Attempting fallback to https instead of http on channel "' . $channel . '"...');
$a = $this->downloadHttp('https://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false);
PEAR::popErrorHandling();
if (PEAR::isError($a)) {
return false;
}
}
 
list($a, $lastmodified) = $a;
if (!class_exists('PEAR_ChannelFile')) {
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')) {
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();
}
 
$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']) && $err->getMessage() !== '') {
$this->log(0, $err->getMessage());
}
 
$params[$i] = false;
if (is_object($param)) {
$param = $param->getChannel() . '/' . $param->getPackage();
}
 
if (!isset($this->_options['soft'])) {
$this->log(2, 'Package "' . $param . '" is not valid');
}
 
// Message logged above in a specific verbose mode, passing null to not show up on CLI
$this->pushError(null, 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;
}
 
$mirror = $this->config->get('preferred_mirror', null, $params[$i]->getChannel());
$url = 'http://' . $mirror . '/channel.xml';
$a = $this->downloadHttp($url, $this->ui, $dir, null, $curchannel->lastModified());
 
PEAR::staticPopErrorHandling();
if ($a === false) {
//channel.xml not modified
break;
} else if (PEAR::isError($a)) {
// Attempt fallback to https automatically
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$a = $this->downloadHttp('https://' . $mirror .
'/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 "' . PEAR_RUNTYPE . ' 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) {
//PHP Bug 40768 / PEAR Bug #10944
//Nested foreaches fail in PHP 5.2.1
key($params);
$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);
$errorparams = array();
if (PEAR_Downloader_Package::detectStupidDuplicates($params, $errorparams)) {
if (count($errorparams)) {
foreach ($errorparams as $param) {
$name = $this->_registry->parsedPackageNameToString($param->getParsedPackage());
$this->pushError('Duplicate package ' . $name . ' found', PEAR_INSTALLER_FAILED);
}
$a = array();
return $a;
}
}
 
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;
}
 
$somefailed = false;
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) .
'"');
}
$somefailed = true;
continue;
}
 
$newparams[] = &$params[$i];
$ret[] = array(
'file' => $pf->getArchiveFile(),
'info' => &$pf,
'pkg' => $pf->getPackage()
);
}
 
if ($somefailed) {
// remove params that did not download successfully
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->analyzeDependencies($newparams, true);
PEAR::popErrorHandling();
if (!count($newparams)) {
$this->pushError('Download failed', PEAR_INSTALLER_FAILED);
$a = array();
return $a;
}
}
 
$this->_downloadedPackages = $ret;
return $newparams;
}
 
/**
* @param array all packages to be installed
*/
function analyzeDependencies(&$params, $force = false)
{
if (isset($this->_options['downloadonly'])) {
return;
}
 
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$redo = true;
$reset = $hasfailed = $failed = 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);
$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() && !$force) {
continue;
}
 
if (count($deps)) {
$depchecker = &$this->getDependency2Object($this->config, $this->getOptions(),
$param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING);
$send = $param->getPackageFile();
if ($send === null) {
$send = $param->getDownloadURL();
}
 
$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']) && is_array($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']) && is_array($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) || (is_dir($downloaddir) && !is_writable($downloaddir))) {
if (is_dir($downloaddir) && !is_writable($downloaddir)) {
$this->log(0, 'WARNING: configuration download directory "' . $downloaddir .
'" is not writeable. Change download_dir config variable to ' .
'a writeable dir to avoid this warning');
}
 
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))) ||
!is_writable($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)
{
if (!@is_writable($dir)) {
if (PEAR::isError(System::mkdir(array('-p', $dir)))) {
return PEAR::raiseError('download directory "' . $dir .
'" is not writeable. Change download_dir config variable to ' .
'a writeable dir');
}
}
$this->_downloadDir = $dir;
}
 
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;
}
}
 
function setOptions($options)
{
$this->_options = $options;
}
 
function getOptions()
{
return $this->_options;
}
 
 
/**
* @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') && $this->discover($parr['channel'])) {
break;
}
 
$this->configSet('default_channel', $curchannel);
return PEAR::raiseError('Unknown remote channel: ' . $parr['channel']);
} while (false);
}
 
$chan = $this->_registry->getChannel($parr['channel']);
if (PEAR::isError($chan)) {
return $chan;
}
 
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$version = $this->_registry->packageInfo($parr['package'], 'version', $parr['channel']);
$stability = $this->_registry->packageInfo($parr['package'], 'stability', $parr['channel']);
// package is installed - use the installed release stability level
if (!isset($parr['state']) && $stability !== null) {
$state = $stability['release'];
}
PEAR::staticPopErrorHandling();
$base2 = false;
 
$preferred_mirror = $this->config->get('preferred_mirror');
if (!$chan->supportsREST($preferred_mirror) ||
(
!($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror))
&&
!($base = $chan->getBaseURL('REST1.0', $preferred_mirror))
)
) {
return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.');
}
 
if ($base2) {
$rest = &$this->config->getREST('1.3', $this->_options);
$base = $base2;
} else {
$rest = &$this->config->getREST('1.0', $this->_options);
}
 
$downloadVersion = false;
if (!isset($parr['version']) && !isset($parr['state']) && $version
&& !PEAR::isError($version)
&& !isset($this->_options['downloadonly'])
) {
$downloadVersion = $version;
}
 
$url = $rest->getDownloadURL($base, $parr, $state, $downloadVersion, $chan->getName());
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');
}
 
if (!isset($this->_options['force']) &&
!isset($this->_options['downloadonly']) &&
$version &&
!PEAR::isError($version) &&
!isset($parr['group'])
) {
if (version_compare($version, $url['version'], '=')) {
return PEAR::raiseError($this->_registry->parsedPackageNameToString(
$parr, true) . ' is already installed and is the same as the ' .
'released version ' . $url['version'], -976);
}
 
if (version_compare($version, $url['version'], '>')) {
return PEAR::raiseError($this->_registry->parsedPackageNameToString(
$parr, true) . ' is already installed and is newer than detected ' .
'released 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) && isset($url['url'])) {
$url['url'] .= $ext;
}
 
return $url;
}
 
/**
* @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'))
&&
(
($base2 = $chan->getBaseURL('REST1.3', $this->config->get('preferred_mirror')))
||
($base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror')))
)
) {
if ($base2) {
$base = $base2;
$rest = &$this->config->getREST('1.3', $this->_options);
} else {
$rest = &$this->config->getREST('1.0', $this->_options);
}
 
$url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr,
$state, $version, $chan->getName());
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) && isset($url['url'])) {
$url['url'] .= $ext;
}
 
return $url;
}
 
return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.');
}
 
/**
* @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;
}
 
/**
* 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;
}
 
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);
}
 
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
* @param integer
*/
function pushError($errmsg, $code = -1)
{
array_push($this->_errorStack, array($errmsg, $code));
}
 
function getErrorMsgs()
{
$msgs = array();
$errs = $this->_errorStack;
foreach ($errs as $err) {
$msgs[] = $err[0];
}
$this->_errorStack = array();
return $msgs;
}
 
/**
* for BC
*
* @deprecated
*/
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, $count = count($installOrder); $i < $count; $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
* @param false|string $channel Channel to use for retrieving authentication
* @return mixed 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.
* If $lastmodified was given and the there are no changes,
* boolean false is returned.
*
* @access public
*/
public static function _downloadHttp(
$object, $url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null,
$accept = false, $channel = false
) {
static $redirect = 0;
// always 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 . '"');
}
 
$host = isset($info['host']) ? $info['host'] : null;
$port = isset($info['port']) ? $info['port'] : null;
$path = isset($info['path']) ? $info['path'] : null;
 
if ($object !== null) {
$config = $object->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)) {
$port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80;
}
 
$scheme = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http';
 
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";
$request .= "Host: $host\r\n";
} else {
$request = "GET $url HTTP/1.0\r\n";
$request .= "Host: $host\r\n";
}
} else {
$network_host = $host;
if (isset($info['scheme']) && $info['scheme'] == 'https') {
$network_host = 'ssl://' . $host;
}
 
$fp = @fsockopen($network_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\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.10.1/PHP/" . PHP_VERSION . "\r\n";
 
if ($object !== null) { // only pass in authentication for non-static calls
$username = $config->get('username', null, $channel);
$password = $config->get('password', null, $channel);
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*\\z/', $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 $scheme://$host:$port$path not valid (received: $line)");
}
}
}
 
if ($reply != 200) {
if (!isset($headers['location'])) {
return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirected but no location)");
}
 
if ($wasredirect > 4) {
return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirection looped more than 5 times)");
}
 
$redirect = $wasredirect + 1;
return static::_downloadHttp($object, $headers['location'],
$ui, $save_dir, $callback, $lastmodified, $accept);
}
 
if (isset($headers['content-disposition']) &&
preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|\\z)/', $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 (is_link($dest_file)) {
return PEAR::raiseError('SECURITY ERROR: Will not write to ' . $dest_file . ' as it is symlinked to ' . readlink($dest_file) . ' - Possible symlink attack');
}
 
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");
}
 
$length = isset($headers['content-length']) ? $headers['content-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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Autoloader.php
New file
0,0 → 1,217
<?php
/**
* Class auto-loader
*
* PHP versions 4
 
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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");
 
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Validator/PECL.php
New file
0,0 → 1,62
<?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://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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;
}
}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Dependency2.php
New file
0,0 → 1,1357
<?php
/**
* PEAR_Dependency2, advanced dependency validation
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct(&$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 ($dep['name'] == '*') {
return true;
}
 
$not = isset($dep['conflicts']) ? true : false;
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");
}
 
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");
}
 
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");
}
 
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");
}
 
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');
}
 
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']);
}
 
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;
}
 
$not = isset($dep['conflicts']) ? true : 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'] . '"');
}
 
return $this->warning('warning: %s Architecture dependency failed, does ' .
'not match "' . $dep['pattern'] . '"');
}
 
return true;
}
 
if ($not) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s Architecture dependency failed, required "' .
$dep['pattern'] . '"');
}
 
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);
}
 
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);
}
 
return $this->warning('warning: %s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra);
}
 
return true;
}
 
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);
}
 
return $this->warning('warning: %s requires PHP extension "' .
$dep['name'] . '"' . $extra);
}
 
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);
}
 
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']) && !version_compare($version, $dep['min'], '>=')) {
$fail = true;
}
 
if (isset($dep['max']) && !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);
}
 
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);
}
 
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);
}
 
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);
}
 
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;
}
 
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');
}
 
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);
}
 
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);
}
 
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);
}
 
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.10.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);
}
 
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);
}
 
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);
}
 
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 accommodate 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']) && !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'])) {
$rest = '';
if ($version) {
$rest = ", $installed version is " . $version;
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest);
}
 
return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest);
}
 
return true;
}
 
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);
}
 
return $this->warning('warning: %s requires package "' . $depname . '"' . $extra);
}
 
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);
}
 
return $this->warning('warning: %s requires package "' . $depname . '"' . $extra);
}
 
return $this->warning('%s can optionally use package "' . $depname . '"' . $extra);
}
 
$fail = false;
if (isset($dep['min']) && version_compare($version, $dep['min'], '<')) {
$fail = true;
}
 
if (isset($dep['max']) && 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);
}
 
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);
}
 
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);
}
 
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);
}
 
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;
}
 
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 && $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');
}
 
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) {
if (is_array($error)) {
$dl->log(0, $error[0]);
} else {
$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');
}
 
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) {
if (is_array($error)) {
$dl->log(0, $error[0]);
} else {
$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');
}
 
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']) && !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) {
return $this->warning('"' . $depname . '" can be optionally used by ' .
'installed package %s' . $extra);
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('"' . $depname . '" is required by ' .
'installed package %s' . $extra);
}
 
return $this->warning('warning: "' . $depname . '" is required by ' .
'installed package %s' . $extra);
}
 
$fail = false;
if (isset($dep['min']) && version_compare($version, $dep['min'], '>=')) {
$fail = true;
}
 
if (isset($dep['max']) && version_compare($version, $dep['max'], '<=')) {
$fail = true;
}
 
// we re-use this variable, preserve the original value
$saverequired = $required;
if (!$required) {
return $this->warning($depname . $extra . ' can be optionally used by installed package' .
' "%s"');
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError($depname . $extra . ' is required by installed package' .
' "%s"');
}
 
return $this->raiseError('warning: ' . $depname . $extra .
' is required by installed package "%s"');
}
 
/**
* 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']])) {
return array(false, false);
}
 
$type = $types[$dep['type']];
 
$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.4.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)));
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/RunTest.php
New file
0,0 → 1,972
<?php
/**
* PEAR_RunTest
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.3.3
*/
class PEAR_RunTest
{
var $_headers = array();
var $_logger;
var $_options;
var $_php;
var $tests_count;
var $xdebug_loaded;
/**
* Saved value of php executable, used to reset $_php when we
* have a test that uses cgi
*
* @var unknown_type
*/
var $_savephp;
var $ini_overwrites = array(
'output_handler=',
'open_basedir=',
'disable_functions=',
'output_buffering=Off',
'display_errors=1',
'log_errors=0',
'html_errors=0',
'track_errors=1',
'report_memleaks=0',
'report_zend_debug=0',
'docref_root=',
'docref_ext=.html',
'error_prepend_string=',
'error_append_string=',
'auto_prepend_file=',
'auto_append_file=',
'xdebug.default_enable=0',
'allow_url_fopen=1',
);
 
/**
* An object that supports the PEAR_Common->log() signature, or null
* @param PEAR_Common|null
*/
function __construct($logger = null, $options = array())
{
if (!defined('E_DEPRECATED')) {
define('E_DEPRECATED', 0);
}
if (!defined('E_STRICT')) {
define('E_STRICT', 0);
}
$this->ini_overwrites[] = 'error_reporting=' . (E_ALL & ~(E_DEPRECATED | E_STRICT));
if (is_null($logger)) {
require_once 'PEAR/Common.php';
$logger = new PEAR_Common;
}
$this->_logger = $logger;
$this->_options = $options;
 
$conf = &PEAR_Config::singleton();
$this->_php = $conf->get('php_bin');
}
 
/**
* 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 = '';
$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;
$e = $w = 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);
}
 
/**
* Turns a PHP INI string into an array
*
* Turns -d "include_path=/foo/bar" into this:
* array(
* 'include_path' => array(
* 'operator' => '-d',
* 'value' => '/foo/bar',
* )
* )
* Works both with quotes and without
*
* @param string an PHP INI string, -d "include_path=/foo/bar"
* @return array
*/
function iniString2array($ini_string)
{
if (!$ini_string) {
return array();
}
$split = preg_split('/[\s]|=/', $ini_string, -1, PREG_SPLIT_NO_EMPTY);
$key = $split[1][0] == '"' ? substr($split[1], 1) : $split[1];
$value = $split[2][strlen($split[2]) - 1] == '"' ? substr($split[2], 0, -1) : $split[2];
// FIXME review if this is really the struct to go with
$array = array($key => array('operator' => $split[0], 'value' => $value));
return $array;
}
 
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) {
if (is_array($value)) {
$operator = $value['operator'];
$value = $value['value'];
} else {
$operator = '-d';
}
$value = addslashes($value);
$settings .= " $operator \"$name=$value\"";
}
return $settings;
}
 
function _preparePhpBin($php, $file, $ini_settings)
{
$file = escapeshellarg($file);
$cmd = $php . $ini_settings . ' -f ' . $file;
 
return $cmd;
}
 
function runPHPUnit($file, $ini_settings = '')
{
if (!file_exists($file) && file_exists(getcwd() . DIRECTORY_SEPARATOR . $file)) {
$file = realpath(getcwd() . DIRECTORY_SEPARATOR . $file);
} elseif (file_exists($file)) {
$file = realpath($file);
}
 
$cmd = $this->_preparePhpBin($this->_php, $file, $ini_settings);
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
}
 
/**
* Runs an individual test case.
*
* @param string The filename of the test
* @param array|string INI settings to be applied to the test run
* @param integer Number what the current running test is of the
* whole test suite being runned.
*
* @return string|object Returns PASSED, WARNED, FAILED depending on how the
* test came out.
* PEAR Error when the tester it self fails
*/
function run($file, $ini_settings = array(), $test_number = 1)
{
$this->_restorePHPBinary();
 
if (empty($this->_options['cgi'])) {
// try to see if php-cgi is in the path
$res = $this->system_with_timeout('php-cgi -v');
if (false !== $res && !(is_array($res) && in_array($res[0], array(-1, 127)))) {
$this->_options['cgi'] = 'php-cgi';
}
}
if (1 < $len = strlen($this->tests_count)) {
$test_number = str_pad($test_number, $len, ' ', STR_PAD_LEFT);
$test_nr = "[$test_number/$this->tests_count] ";
} else {
$test_nr = '';
}
 
$file = realpath($file);
$section_text = $this->_readFile($file);
if (PEAR::isError($section_text)) {
return $section_text;
}
 
if (isset($section_text['POST_RAW']) && isset($section_text['UPLOAD'])) {
return PEAR::raiseError("Cannot contain both POST_RAW and UPLOAD in test file: $file");
}
 
$cwd = getcwd();
 
$pass_options = '';
if (!empty($this->_options['ini'])) {
$pass_options = $this->_options['ini'];
}
 
if (is_string($ini_settings)) {
$ini_settings = $this->iniString2array($ini_settings);
}
 
$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 = preg_split( "/[\n\r]+/", $section_text['INI']);
$ini_settings = $this->settings2array($ini, $ini_settings);
}
$ini_settings = $this->settings2params($ini_settings);
$shortname = str_replace($cwd . DIRECTORY_SEPARATOR, '', $file);
 
$tested = trim($section_text['TEST']);
$tested.= !isset($this->_options['simple']) ? "[$shortname]" : ' ';
 
if (!empty($section_text['POST']) || !empty($section_text['POST_RAW']) ||
!empty($section_text['UPLOAD']) || !empty($section_text['GET']) ||
!empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) {
if (empty($this->_options['cgi'])) {
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, "SKIP $test_nr$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';
}
$this->_savePHPBinary();
$this->_php = $this->_options['cgi'];
}
 
$temp_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';
$temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php';
$temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php';
$tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.');
 
// unlink old test results
$this->_cleanupOldFiles($file);
 
// Check if test should be skipped.
$res = $this->_runSkipIf($section_text, $temp_skipif, $tested, $ini_settings);
if (count($res) != 2) {
return $res;
}
$info = $res['info'];
$warn = $res['warn'];
 
// We've satisfied the preconditions - run the test!
if (isset($this->_options['coverage']) && $this->xdebug_loaded) {
$xdebug_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'xdebug';
$text = "\n" . 'function coverage_shutdown() {' .
"\n" . ' $xdebug = var_export(xdebug_get_code_coverage(), true);';
if (!function_exists('file_put_contents')) {
$text .= "\n" . ' $fh = fopen(\'' . $xdebug_file . '\', "wb");' .
"\n" . ' if ($fh !== false) {' .
"\n" . ' fwrite($fh, $xdebug);' .
"\n" . ' fclose($fh);' .
"\n" . ' }';
} else {
$text .= "\n" . ' file_put_contents(\'' . $xdebug_file . '\', $xdebug);';
}
 
// Workaround for http://pear.php.net/bugs/bug.php?id=17292
$lines = explode("\n", $section_text['FILE']);
$numLines = count($lines);
$namespace = '';
$coverage_shutdown = 'coverage_shutdown';
 
if (
substr($lines[0], 0, 2) == '<?' ||
substr($lines[0], 0, 5) == '<?php'
) {
unset($lines[0]);
}
 
 
for ($i = 0; $i < $numLines; $i++) {
if (isset($lines[$i]) && substr($lines[$i], 0, 9) == 'namespace') {
$namespace = substr($lines[$i], 10, -1);
$coverage_shutdown = $namespace . '\\coverage_shutdown';
$namespace = "namespace " . $namespace . ";\n";
 
unset($lines[$i]);
break;
}
}
 
$text .= "\n xdebug_stop_code_coverage();" .
"\n" . '} // end coverage_shutdown()' .
"\n\n" . 'register_shutdown_function("' . $coverage_shutdown . '");';
$text .= "\n" . 'xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);' . "\n";
 
$this->save_text($temp_file, "<?php\n" . $namespace . $text . "\n" . implode("\n", $lines));
} else {
$this->save_text($temp_file, $section_text['FILE']);
}
 
$args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : '';
$cmd = $this->_preparePhpBin($this->_php, $temp_file, $ini_settings);
$cmd.= "$args 2>&1";
if (isset($this->_logger)) {
$this->_logger->log(2, 'Running command "' . $cmd . '"');
}
 
// Reset environment from any previous test.
$env = $this->_resetEnv($section_text, $temp_file);
 
$section_text = $this->_processUpload($section_text, $file);
if (PEAR::isError($section_text)) {
return $section_text;
}
 
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 = "$this->_php$pass_options$ini_settings \"$temp_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 = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post";
} else {
$env['REQUEST_METHOD'] = 'GET';
$env['CONTENT_TYPE'] = '';
$env['CONTENT_LENGTH'] = '';
}
 
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;
$stdin = isset($section_text['STDIN']) ? $section_text['STDIN'] : null;
$out = $this->system_with_timeout($cmd, $env, $stdin);
$return_value = $out[0];
$out = $out[1];
}
 
$output = preg_replace('/\r\n/', "\n", trim($out));
 
if (isset($tmp_post) && realpath($tmp_post) && file_exists($tmp_post)) {
@unlink(realpath($tmp_post));
}
chdir($cwd); // in case the test moves us around
 
/* when using CGI, strip the headers from the output */
$output = $this->_stripHeadersCGI($output);
 
if (isset($section_text['EXPECTHEADERS'])) {
$testheaders = $this->_processHeaders($section_text['EXPECTHEADERS']);
$missing = array_diff_assoc($testheaders, $this->_headers);
$changed = '';
foreach ($missing as $header => $value) {
if (isset($this->_headers[$header])) {
$changed .= "-$header: $value\n+$header: ";
$changed .= $this->_headers[$header];
} else {
$changed .= "-$header: $value\n";
}
}
if ($missing) {
// tack on failed headers to output:
$output .= "\n====EXPECTHEADERS FAILURE====:\n$changed";
}
}
 
$this->_testCleanup($section_text, $temp_clean);
 
// Does the output match what is expected?
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 $test_nr$tested$info");
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' - ' . $tested);
}
return 'PASSED';
}
} else {
if (isset($section_text['EXPECTFILE'])) {
$f = $temp_dir . '/' . trim($section_text['EXPECTFILE']);
if (!($fp = @fopen($f, 'rb'))) {
return PEAR::raiseError('--EXPECTFILE-- section file ' .
$f . ' not found');
}
fclose($fp);
$section_text['EXPECT'] = file_get_contents($f);
}
 
if (isset($section_text['EXPECT'])) {
$wanted = preg_replace('/\r\n/', "\n", trim($section_text['EXPECT']));
} else {
$wanted = '';
}
 
// compare and leave on success
if (!$returnfail && 0 == strcmp($output, $wanted)) {
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 $test_nr$tested$info");
}
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
$expectf = isset($section_text['EXPECTF']) ? $wanted_re : null;
$faildiff = $this->generate_diff($wanted, $output, null, $expectf);
$faildiff = preg_replace('/\r/', '', $faildiff);
$wanted = preg_replace('/\r/', '', trim($section_text['FAIL']));
if ($faildiff == $wanted) {
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, "PASS $test_nr$tested$info");
}
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.
$txt = $warn ? 'WARN ' : 'FAIL ';
$this->_logger->log(0, $txt . $test_nr . $tested . $info);
 
// write .exp
$res = $this->_writeLog($exp_filename, $wanted);
if (PEAR::isError($res)) {
return $res;
}
 
// write .out
$res = $this->_writeLog($output_filename, $output);
if (PEAR::isError($res)) {
return $res;
}
 
// write .diff
$returns = isset($section_text['RETURNS']) ?
array(trim($section_text['RETURNS']), $return_value) : null;
$expectf = isset($section_text['EXPECTF']) ? $wanted_re : null;
$data = $this->generate_diff($wanted, $output, $returns, $expectf);
$res = $this->_writeLog($diff_filename, $data);
if (isset($this->_options['showdiff'])) {
$this->_logger->log(0, "========DIFF========");
$this->_logger->log(0, $data);
$this->_logger->log(0, "========DONE========");
}
if (PEAR::isError($res)) {
return $res;
}
 
// write .log
$data = "
---- EXPECTED OUTPUT
$wanted
---- ACTUAL OUTPUT
$output
---- FAILED
";
 
if ($returnfail) {
$data .= "
---- EXPECTED RETURN
$section_text[RETURNS]
---- ACTUAL RETURN
$return_value
";
}
 
$res = $this->_writeLog($log_filename, $data);
if (PEAR::isError($res)) {
return $res;
}
 
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, $rvalue, $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);
$o2 = $w2 = array();
foreach ($w1 as $idx => $val) {
if (!$wanted_re || !isset($wr[$idx]) || !isset($o1[$idx]) ||
!preg_match('/^' . $wr[$idx] . '\\z/', $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] . '\\z/', $val)) {
$o2[sprintf("%03d>", $idx)] = sprintf("%03d+ ", $idx + 1) . $val;
}
}
$diff = array_merge($w2, $o2);
ksort($diff);
$extra = $rvalue ? "##EXPECTED: $rvalue[0]\r\n##RETURNED: $rvalue[1]" : '';
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
}}}
";
}
 
function _cleanupOldFiles($file)
{
$temp_dir = realpath(dirname($file));
$mainFileName = basename($file, 'phpt');
$diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'diff';
$log_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'log';
$exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'exp';
$output_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'out';
$memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'mem';
$temp_file = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'php';
$temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'skip.php';
$temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'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($temp_skipif);
@unlink($tmp_post);
@unlink($temp_clean);
}
 
function _runSkipIf($section_text, $temp_skipif, $tested, $ini_settings)
{
$info = '';
$warn = false;
if (array_key_exists('SKIPIF', $section_text) && trim($section_text['SKIPIF'])) {
$this->save_text($temp_skipif, $section_text['SKIPIF']);
$output = $this->system_with_timeout("$this->_php$ini_settings -f \"$temp_skipif\"");
$output = $output[1];
$loutput = ltrim($output);
unlink($temp_skipif);
if (!strncasecmp('skip', $loutput, 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', $loutput, 4)
&& preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) {
$info = " (info: $m[1])";
}
 
if (!strncasecmp('warn', $loutput, 4)
&& preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) {
$warn = true; /* only if there is a reason */
$info = " (warn: $m[1])";
}
}
 
return array('warn' => $warn, 'info' => $info);
}
 
function _stripHeadersCGI($output)
{
$this->headers = array();
if (!empty($this->_options['cgi']) &&
$this->_php == $this->_options['cgi'] &&
preg_match("/^(.*?)(?:\n\n(.*)|\\z)/s", $output, $match)) {
$output = isset($match[2]) ? trim($match[2]) : '';
$this->_headers = $this->_processHeaders($match[1]);
}
 
return $output;
}
 
/**
* Return an array that can be used with array_diff() to compare headers
*
* @param string $text
*/
function _processHeaders($text)
{
$headers = array();
$rh = preg_split("/[\n\r]+/", $text);
foreach ($rh as $line) {
if (strpos($line, ':')!== false) {
$line = explode(':', $line, 2);
$headers[trim($line[0])] = trim($line[1]);
}
}
return $headers;
}
 
function _readFile($file)
{
// Load the sections of the test file.
$section_text = array(
'TEST' => '(unnamed test)',
'SKIPIF' => '',
'GET' => '',
'COOKIE' => '',
'POST' => '',
'ARGS' => '',
'INI' => '',
'CLEAN' => '',
);
 
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);
 
return $section_text;
}
 
function _writeLog($logname, $data)
{
if (!$log = fopen($logname, 'w')) {
return PEAR::raiseError("Cannot create test log - $logname");
}
fwrite($log, $data);
fclose($log);
}
 
function _resetEnv($section_text, $temp_file)
{
$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'])) {
if (strpos($section_text['ENV'], '{PWD}') !== false) {
$section_text['ENV'] = str_replace('{PWD}', dirname($temp_file), $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)) {
$env['QUERY_STRING'] = trim($section_text['GET']);
} else {
$env['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['PATH_TRANSLATED'] = $temp_file;
$env['SCRIPT_FILENAME'] = $temp_file;
 
return $env;
}
 
function _processUpload($section_text, $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;
}
 
return $section_text;
}
 
function _testCleanup($section_text, $temp_clean)
{
if ($section_text['CLEAN']) {
$this->_restorePHPBinary();
 
// perform test cleanup
$this->save_text($temp_clean, $section_text['CLEAN']);
$output = $this->system_with_timeout("$this->_php $temp_clean 2>&1");
if (strlen($output[1])) {
echo "BORKED --CLEAN-- section! output:\n", $output[1];
}
if (file_exists($temp_clean)) {
unlink($temp_clean);
}
}
}
 
function _savePHPBinary()
{
$this->_savephp = $this->_php;
}
 
function _restorePHPBinary()
{
if (isset($this->_savephp))
{
$this->_php = $this->_savephp;
unset($this->_savephp);
}
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Config.php
New file
0,0 → 1,2131
<?php
/**
* PEAR_Config, customized configuration handling for the PEAR Installer
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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';
 
/**
* 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')) {
define('PEAR_RUNTYPE', 'pear');
}
 
if (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 metadata_dir
if (getenv('PHP_PEAR_METADATA_DIR')) {
define('PEAR_CONFIG_DEFAULT_METADATA_DIR', getenv('PHP_PEAR_METADATA_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_METADATA_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 cfg_dir
if (getenv('PHP_PEAR_CFG_DIR')) {
define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_CFG_DIR',
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg');
}
 
// Default for www_dir
if (getenv('PHP_PEAR_WWW_DIR')) {
define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_WWW_DIR',
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www');
}
 
// Default for man_dir
if (getenv('PHP_PEAR_MAN_DIR')) {
define('PEAR_CONFIG_DEFAULT_MAN_DIR', getenv('PHP_PEAR_MAN_DIR'));
} else {
if (defined('PHP_MANDIR')) { // Added in PHP5.3.7
define('PEAR_CONFIG_DEFAULT_MAN_DIR', PHP_MANDIR);
} else {
define('PEAR_CONFIG_DEFAULT_MAN_DIR', PHP_PREFIX . DIRECTORY_SEPARATOR .
'local' . DIRECTORY_SEPARATOR .'man');
}
}
 
// 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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Config extends PEAR
{
/**
* 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', 'cfg_dir',
'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username',
'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini'
);
 
/**
* 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)',
),
'cfg_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_CFG_DIR,
'doc' => 'directory where modifiable configuration files are installed',
'prompt' => 'PEAR configuration file directory',
'group' => 'File Locations (Advanced)',
),
'www_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_WWW_DIR,
'doc' => 'directory where www frontend files (html/js) are installed',
'prompt' => 'PEAR www files directory',
'group' => 'File Locations (Advanced)',
),
'man_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_MAN_DIR,
'doc' => 'directory where unix manual pages are installed',
'prompt' => 'Systems manpage files 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 web service 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_DOWNLOAD_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_prefix' => array(
'type' => 'string',
'default' => '',
'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs',
'prompt' => '--program-prefix passed to PHP\'s ./configure',
'group' => 'File Locations (Advanced)',
),
'php_suffix' => array(
'type' => 'string',
'default' => '',
'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs',
'prompt' => '--program-suffix passed to PHP\'s ./configure',
'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)',
),
'metadata_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_METADATA_DIR,
'doc' => 'directory where metadata files are installed (registry, filemap, channels, ...)',
'prompt' => 'PEAR metadata directory',
'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
);
 
/**
* 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 __construct($user_file = '', $system_file = '', $ftp_file = false,
$strict = true)
{
parent::__construct();
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)) {
$system_file = PEAR_CONFIG_SYSCONFDIR . $sl;
if (OS_WINDOWS) {
$system_file .= 'pearsys.ini';
} else {
$system_file .= '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'], false, false,
$this->configuration['default']['metadata_dir']);
$this->_registry['default']->setConfig($this, false);
$this->_regInitialized['default'] = false;
//$GLOBALS['_PEAR_Config_instance'] = &$this;
}
 
/**
* Return the default locations of user and system configuration files
*/
public static function getDefaultConfigFiles()
{
$sl = DIRECTORY_SEPARATOR;
if (OS_WINDOWS) {
return array(
'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini',
'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini'
);
}
 
return array(
'user' => getenv('HOME') . $sl . '.pearrc',
'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf'
);
}
 
/**
* 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
*
* @see PEAR_Config::PEAR_Config
*/
public static 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'];
}
 
/**
* 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;
}
 
/**
* 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) {
return true;
}
 
$this->_errorsFound++;
$this->lastError = $data;
 
return $data;
}
 
$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, false, false,
$this->get('metadata_dir', $layer, 'pear.php.net'));
$this->_registry[$layer]->setConfig($this, false);
$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')) {
return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config');
}
 
$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)) {
return true;
}
 
$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);
} while (false); // poor man's catch
unset($this->files['ftp']);
return PEAR::raiseError('no remote host specified');
}
 
/**
* 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);
}
 
function deleteChannel($channel)
{
$ch = strtolower($channel);
foreach ($this->configuration as $layer => $data) {
if (isset($data['__channels']) && isset($data['__channels'][$ch])) {
unset($this->configuration[$layer]['__channels'][$ch]);
}
}
 
$this->_channels = array_flip($this->_channels);
unset($this->_channels[$ch]);
$this->_channels = array_flip($this->_channels);
}
 
/**
* 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) {
return true;
}
 
$this->_errorsFound++;
$this->lastError = $data;
 
return $data;
}
 
$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, false, false,
$this->get('metadata_dir', $layer, 'pear.php.net'));
$this->_registry[$layer]->setConfig($this, false);
$this->_regInitialized[$layer] = false;
} else {
unset($this->_registry[$layer]);
}
return true;
}
 
/**
* @param array
* @param array
* @return array
*/
public 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);
}
 
/**
* 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;
}
 
/**
* 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);
fclose($fp);
$contents = file_get_contents($file);
if (empty($contents)) {
return $this->raiseError('Configuration file "' . $file . '" is empty');
}
 
$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;
}
 
$data = array();
}
// add parsing of newer formats here...
} else {
$err = $this->raiseError("$file: unknown version `$version'");
return $err;
}
 
return $data;
}
 
/**
* 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 string Configuration class name, used for detecting duplicate calls
* @param array information on a role as parsed from its xml file
* @return true|PEAR_Error
* @access private
*/
function _addConfigVars($class, $vars)
{
static $called = array();
if (isset($called[$class])) {
return;
}
 
$called[$class] = 1;
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');
} elseif (!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)');
}
 
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)) {
return $this->raiseError(
'Unknown constant "' . $val . '" requested in ' .
'default value for configuration variable "' .
$name . '"');
}
 
$real_default .= constant($val);
} 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;
}
 
/**
* 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;
}
 
/**
* 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;
}
 
/**
* 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;
}
 
/**
* 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;
}
 
/**
* 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') {
return $ret;
}
 
 
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
}
 
return $this->getDefaultChannel($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 (!isset($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;
}
 
return false;
}
 
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, false);
}
}
 
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, false, false,
$this->get('metadata_dir', $layer, 'pear.php.net'));
$this->_registry[$layer]->setConfig($this, false);
$this->_regInitialized[$layer] = false;
} else {
unset($this->_registry[$layer]);
return;
}
}
 
$this->setChannels($this->_registry[$layer]->listChannels(), $merge);
$this->_regInitialized[$layer] = true;
$merge = true;
}
}
}
 
/**
* 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;
}
 
/**
* 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;
}
 
/**
* 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;
}
 
/**
* 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;
}
 
/**
* 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;
}
 
/**
* 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);
}
 
/**
* 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;
}
 
/**
* 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;
}
 
/**
* 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 the a config key from a specific config layer.
*
* @param string config key
* @param string (optional) config layer
* @param string (optional) channel (defaults to default channel)
* @return bool TRUE on success, FALSE on failure
*
* @access public
*/
function remove($key, $layer = 'user', $channel = null)
{
if ($channel === null) {
$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;
}
 
/**
* 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;
}
 
/**
* 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);
}
 
/**
* 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 '';
}
 
/**
* 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;
}
 
/**
* 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]);
}
 
/**
* 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);
}
 
function apiVersion()
{
return '1.1';
}
 
/**
* @return PEAR_Registry
*/
function &getRegistry($use = null)
{
$layer = $use === null ? 'user' : $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;
}
 
// 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, false);
}
 
return true;
}
 
function noRegistry()
{
$this->_noRegistry = true;
}
 
/**
* @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;
}
 
$a = false;
return $a;
}
 
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'), false, false,
$this->get('metadata_dir', $layer, 'pear.php.net'));
$this->_registry[$layer]->setConfig($this, false);
$this->_regInitialized[$layer] = false;
}
}
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/PackageFile/Generator/v1.php
New file
0,0 → 1,1284
<?php
/**
* package.xml generation class, package.xml version 1.0
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct(&$packagefile)
{
$this->_packagefile = &$packagefile;
}
 
function getPackagerVersion()
{
return '1.10.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)
{
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.10.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('required' => 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
$a = array_flip($min);
$min = array_pop($a);
} else {
$min = false;
}
if (count($max)) {
// get the lowest maximum
$a = array_flip($max);
$max = array_shift($a);
} 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)
{
$ret = $tests = array();
foreach ($deps as $name => $dep) {
foreach ($dep as $d) {
$tests[$name][] = $this->_processDep($d);
}
}
 
foreach ($tests as $name => $test) {
$max = $min = $php = 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
$a = array_flip($min);
$min = array_pop($a);
} else {
$min = false;
}
if (count($max)) {
// get the lowest maximum
$a = array_flip($max);
$max = array_shift($a);
} 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;
}
}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/PackageFile/Generator/v2.php
New file
0,0 → 1,886
<?php
/**
* package.xml generation class, package.xml version 2.0
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Stephan Schmidt (original XML_Serializer code)
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* file/dir manipulation routines
*/
require_once 'System.php';
require_once 'XML/Util.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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 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 conjunction 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 __construct(&$packagefile)
{
$this->_packagefile = &$packagefile;
if (isset($this->_packagefile->encoding)) {
$this->_defaultOptions['encoding'] = $this->_packagefile->encoding;
}
}
 
/**
* @return string
*/
function getPackagerVersion()
{
return '1.10.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');
}
 
$file = $where . DIRECTORY_SEPARATOR . 'package.xml';
if (file_exists($file) && !is_file($file)) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' .
' "' . $file .'"');
}
 
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($dest_package) && !is_file($dest_package)) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' .
$dest_package . '"');
}
 
$pkgfile = $this->_packagefile->getPackageFile();
if (!$pkgfile) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: package file object must ' .
'be created from a real file');
}
 
$pkgdir = dirname(realpath($pkgfile));
$pkgfile = basename($pkgfile);
 
// {{{ 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");
}
 
$origperms = fileperms($file);
$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(
array($this->_packagefile->getTasksNs() . ':', '-'),
array('', '_'), $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);
}
 
chmod($tfile, $origperms);
$filelist[$i++] = $tfile;
$this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($tfile), $i - 1);
$packager->log(2, "Adding file $fname");
}
}
// }}}
 
$name = $pf1 !== null ? 'package2.xml' : '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']);
}
 
// Fix the notes a little bit
if (isset($arr['notes'])) {
// This trims out the indenting, needs fixing
$arr['notes'] = "\n" . trim($arr['notes']) . "\n";
}
 
if (isset($arr['changelog']) && !empty($arr['changelog'])) {
// Fix for inconsistency how the array is filled depending on the changelog release amount
if (!isset($arr['changelog']['release'][0])) {
$release = $arr['changelog']['release'];
unset($arr['changelog']['release']);
 
$arr['changelog']['release'] = array();
$arr['changelog']['release'][0] = $release;
}
 
foreach (array_keys($arr['changelog']['release']) as $key) {
$c =& $arr['changelog']['release'][$key];
if (isset($c['notes'])) {
// This trims out the indenting, needs fixing
$c['notes'] = "\n" . trim($c['notes']) . "\n";
}
}
}
 
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.10.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)) {
$tagName = isset($this->options['rootName']) ? $this->options['rootName'] : 'array';
$this->_serializedData .= $this->_serializeArray($data, $tagName, $this->options['rootAttributes']);
}
 
// add doctype declaration
if ($this->options['addDoctype'] === true) {
$this->_serializedData = XML_Util::getDoctypeDeclaration($tagName, $this->options['doctype'])
. $this->options['linebreak']
. $this->_serializedData;
}
 
// build xml declaration
if ($this->options['addDecl']) {
$atts = array();
$encoding = isset($this->options['encoding']) ? $this->options['encoding'] : null;
$this->_serializedData = 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 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) && (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 = 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 {
$indent = $multiline = 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 ($replaceEntities === true) {
$replaceEntities = XML_UTIL_ENTITIES_XML;
}
 
$tag = XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak']);
} 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 = XML_Util::createTagFromArray($tag, $replaceEntities);
}
return $tag;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/PackageFile/v2/Validator.php
New file
0,0 → 1,2135
<?php
/**
* PEAR_PackageFile_v2, package.xml version 2.0, read/write version
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a8
*/
/**
* 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
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a8
* @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']) &&
'1.10.1' != '@package' . '_version@' &&
version_compare('1.10.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');
}
$test = isset($this->_packageInfo['uri']) ? 'uri' :'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('channel' => $chan->getName(),
'package' => $this->_pf->getPackage(),
'name' => $valpack['_content'],
'version' => $valpack['attribs']['version']),
'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*)?\\z/',
$this->_packageInfo['version']['release'])) {
$this->_invalidVersion('release', $this->_packageInfo['version']['release']);
}
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$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]+)?\\z/',
$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]+)?\\z/',
$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]+)?\\z/',
$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*)?\\z/',
$dep['min'])) {
$this->_invalidVersion('<dependencies><required><pearinstaller><min>',
$dep['min']);
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$dep['max'])) {
$this->_invalidVersion('<dependencies><required><pearinstaller><max>',
$dep['max']);
}
}
if (isset($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$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*)?\\z/',
$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*)?\\z/',
$dep['min'])) {
$this->_invalidVersion('<dependencies>' . $group . $type . '<min>', $dep['min']);
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$dep['max'])) {
$this->_invalidVersion('<dependencies>' . $group . $type . '<max>', $dep['max']);
}
}
if (isset($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$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*)?\\z/',
$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*)?\\z/',
$dep['min'])) {
$this->_invalidVersion(substr($type, 1) . '<min', $dep['min']);
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$dep['max'])) {
$this->_invalidVersion(substr($type, 1) . '<max', $dep['max']);
}
}
if (isset($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
$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*)?\\z/',
$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*)?\\z/',
$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*)?\\z/',
$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*)?\\z/',
$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'] . '">';
if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
str_replace('\\', '/', $list['attribs']['name']))) {
// file contains .. parent directory or . cur directory
$this->_invalidDirName($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 (preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
str_replace('\\', '/', $file['attribs']['as']))) {
// file contains .. parent directory or . cur directory references
$this->_invalidFileInstallAs($file['attribs']['name'],
$file['attribs']['as']);
}
}
}
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 (is_string($list['file'])) {
$this->_oldStyleFileNotAllowed();
return false;
}
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'])) {
if ($file['attribs']['name']{0} == '.' &&
$file['attribs']['name']{1} == '/') {
// name is something like "./doc/whatever.txt"
$this->_invalidFileName($file['attribs']['name'], $dirname);
}
if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
str_replace('\\', '/', $file['attribs']['name']))) {
// file contains .. parent directory or . cur directory
$this->_invalidFileName($file['attribs']['name'], $dirname);
}
}
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.10.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 _oldStyleFileNotAllowed()
{
$this->_stack->push(__FUNCTION__, 'error', array(),
'Old-style <file>name</file> is not allowed. Use' .
'<file name="name" role="role"/>');
}
 
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%" in directory "%dir%" cannot begin with "./" or contain ".."');
}
 
function _invalidFileInstallAs($file, $as)
{
$this->_stack->push(__FUNCTION__, 'error', array(
'file' => $file, 'as' => $as),
'File "%file%" <install as="%as%"/> cannot contain "./" or contain ".."');
}
 
function _invalidDirName($dir)
{
$this->_stack->push(__FUNCTION__, 'error', array(
'dir' => $file),
'Directory "%dir%" cannot begin with "./" or contain ".."');
}
 
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%> for role "%role%" must contain either <uri>, or <channel> and <package>');
}
 
function _usesroletaskMustHavePackage($role, $tag)
{
$this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag),
'<%tag%> for role "%role%" 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('name' => $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);
$common = new PEAR_Common;
$log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') :
array($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);
}
 
// Silence this function so we can catch PHP Warnings and show our own custom message
$tokens = @token_get_all($contents);
if (isset($php_errormsg)) {
if (isset($this->_stack)) {
$pn = $this->_pf->getPackage();
$this->_stack->push(__FUNCTION__, 'warning',
array('file' => $file, 'package' => $pn),
'in %file%: Could not process file for unknown reasons,' .
' possibly a PHP parse error in %file% from %package%');
}
}
/*
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)) {
if (isset($this->_stack)) {
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
'Parser error: invalid PHP found in file "%file%"');
} else {
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 ($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:
$token = $tokens[$i - 1][0];
if (!($token == T_WHITESPACE || $token == T_STRING || $token == T_STATIC || $token == T_VARIABLE)) {
if (isset($this->_stack)) {
$this->_stack->push(__FUNCTION__, 'warning', array('file' => $file),
'Parser error: invalid PHP found in file "%file%"');
} else {
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,
);
}
 
/**
* 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 = isset($this->_pf) ? $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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/PackageFile/v2/rw.php
New file
0,0 → 1,1603
<?php
/**
* PEAR_PackageFile_v2, package.xml version 2.0, read/write version
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 (is_array($maintainer) && $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;
}
} else {
$this->_packageInfo['contents'] = array('bundledpackage' => array());
}
}
 
/**
* @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['attribs']['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']);
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/PackageFile/Parser/v1.php
New file
0,0 → 1,458
<?php
/**
* package.xml parsing class, package.xml version 1.0
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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) {
$a = &PEAR::raiseError('Cannot create xml parser for parsing package.xml');
return $a;
}
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);
$a = PEAR::raiseError(sprintf("XML error: %s at line %d",
$str = xml_error_string($code), $line), 2);
return $a;
}
 
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";
} elseif (trim(substr($line, 0, $indent_len))) {
$data .= ltrim($line);
}
}
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':
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 ;-)
// Trim only on the right side
$data = rtrim($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;
}
}
 
// }}}
}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/PackageFile/Parser/v2.php
New file
0,0 → 1,112
<?php
/**
* package.xml parsing class, package.xml version 2.0
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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";
} else {
$data .= $line . "\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 = null, $archive = false, $class = 'PEAR_PackageFile_v2')
{
if (PEAR::isError($err = parent::parse($data))) {
return $err;
}
 
$ret = new $class;
$ret->encoding = $this->encoding;
$ret->setConfig($this->_config);
if (isset($this->_logger)) {
$ret->setLogger($this->_logger);
}
 
$ret->fromArray($this->_unserializedData);
$ret->setPackagefile($file, $archive);
return $ret;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/PackageFile/v1.php
New file
0,0 → 1,1602
<?php
/**
* PEAR_PackageFile_v1, package.xml version 1.0
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct()
{
$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 (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) {
// file contains .. parent directory or . cur directory references
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
array('file' => $file));
}
if (isset($fa['install-as']) &&
preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
str_replace('\\', '/', $fa['install-as']))) {
// install-as contains .. parent directory or . cur directory references
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
array('file' => $file . ' [installed as ' . $fa['install-as'] . ']'));
}
if (isset($fa['baseinstalldir']) &&
preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
str_replace('\\', '/', $fa['baseinstalldir']))) {
// install-as contains .. parent directory or . cur directory references
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']'));
}
}
}
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 ($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);
}
}
 
// }}}
}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/PackageFile/v2.php
New file
0,0 → 1,2060
<?php
/**
* PEAR_PackageFile_v2, package.xml version 2.0
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct()
{
$this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null);
$this->_isValid = false;
}
 
/**
* PHP 4 style constructor for backwards compatibility.
* Used by PEAR_PackageFileManager2
*/
public function PEAR_PackageFile_v2()
{
$this->__construct();
}
 
/**
* 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)
{
if (!isset($this->_packageInfo['stability'])) {
$this->_packageInfo['stability'] = array();
}
$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']);
// If the changelog isn't an array then it was passed in as an empty tag
if (isset($pinfo['changelog']) && !is_array($pinfo['changelog'])) {
unset($pinfo['changelog']);
}
$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'])) {
return false;
}
if (!isset($contents['dir']['file'][0])) {
$contents['dir']['file'] = array($contents['dir']['file']);
}
foreach ($contents['dir']['file'] as $file) {
if (!isset($file['attribs']['name'])) {
continue;
}
$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])
|| empty($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);
$taskfile = str_replace(' ', '/', ucwords($task));
$task = str_replace(array(' ', '/'), '_', ucwords($task));
if (class_exists("PEAR_Task_$task")) {
return "PEAR_Task_$task";
}
$fp = @fopen("PEAR/Task/$taskfile.php", 'r', true);
if ($fp) {
fclose($fp);
require_once "PEAR/Task/$taskfile.php";
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;
}
}
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Man.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>man_dir</locationconfig>
<honorsbaseinstall>1</honorsbaseinstall>
<unusualbaseinstall />
<phpfile />
<executable />
<phpextension />
<config_vars />
</role>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Www.php
New file
0,0 → 1,27
<?php
/**
* PEAR_Installer_Role_Www
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2007-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.7.0
*/
 
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2007-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.7.0
*/
class PEAR_Installer_Role_Www extends PEAR_Installer_Role_Common {}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Src.php
New file
0,0 → 1,33
<?php
/**
* PEAR_Installer_Role_Src
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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++;
}
}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Php.php
New file
0,0 → 1,27
<?php
/**
* PEAR_Installer_Role_Php
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 {}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Common.php
New file
0,0 → 1,173
<?php
/**
* Base class for all installation roles.
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct(&$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'];
}
}
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Www.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>www_dir</locationconfig>
<honorsbaseinstall>1</honorsbaseinstall>
<unusualbaseinstall />
<phpfile />
<executable />
<phpextension />
<config_vars />
</role>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Cfg.php
New file
0,0 → 1,105
<?php
/**
* PEAR_Installer_Role_Cfg
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2007-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.7.0
*/
 
/**
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2007-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.7.0
*/
class PEAR_Installer_Role_Cfg extends PEAR_Installer_Role_Common
{
/**
* @var PEAR_Installer
*/
var $installer;
 
/**
* the md5 of the original file
*
* @var unknown_type
*/
var $md5 = null;
 
/**
* 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)
{
$this->installer = &$installer;
$reg = &$this->installer->config->getRegistry();
$package = $reg->getPackage($pkg->getPackage(), $pkg->getChannel());
if ($package) {
$filelist = $package->getFilelist();
if (isset($filelist[$file]) && isset($filelist[$file]['md5sum'])) {
$this->md5 = $filelist[$file]['md5sum'];
}
}
}
 
function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null)
{
$test = parent::processInstallation($pkg, $atts, $file, $tmp_path, $layer);
if (@file_exists($test[2]) && @file_exists($test[3])) {
$md5 = md5_file($test[2]);
// configuration has already been installed, check for mods
if ($md5 !== $this->md5 && $md5 !== md5_file($test[3])) {
// configuration has been modified, so save our version as
// configfile-version
$old = $test[2];
$test[2] .= '.new-' . $pkg->getVersion();
// backup original and re-install it
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$tmpcfg = $this->config->get('temp_dir');
$newloc = System::mkdir(array('-p', $tmpcfg));
if (!$newloc) {
// try temp_dir
$newloc = System::mktemp(array('-d'));
if (!$newloc || PEAR::isError($newloc)) {
PEAR::popErrorHandling();
return PEAR::raiseError('Could not save existing configuration file '.
$old . ', unable to install. Please set temp_dir ' .
'configuration variable to a writeable location and try again');
}
} else {
$newloc = $tmpcfg;
}
 
$temp_file = $newloc . DIRECTORY_SEPARATOR . uniqid('savefile');
if (!@copy($old, $temp_file)) {
PEAR::popErrorHandling();
return PEAR::raiseError('Could not save existing configuration file '.
$old . ', unable to install. Please set temp_dir ' .
'configuration variable to a writeable location and try again');
}
 
PEAR::popErrorHandling();
$this->installer->log(0, "WARNING: configuration file $old is being installed as $test[2], you should manually merge in changes to the existing configuration file");
$this->installer->addFileOperation('rename', array($temp_file, $old, false));
$this->installer->addFileOperation('delete', array($temp_file));
}
}
 
return $test;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Src.xml
New file
0,0 → 1,12
<role version="1.0">
<releasetypes>extsrc</releasetypes>
<releasetypes>zendextsrc</releasetypes>
<installable>1</installable>
<locationconfig>temp_dir</locationconfig>
<honorsbaseinstall />
<unusualbaseinstall />
<phpfile />
<executable />
<phpextension />
<config_vars />
</role>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Ext.php
New file
0,0 → 1,27
<?php
/**
* PEAR_Installer_Role_Ext
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 {}
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Script.php
New file
0,0 → 1,27
<?php
/**
* PEAR_Installer_Role_Script
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 {}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Doc.php
New file
0,0 → 1,27
<?php
/**
* PEAR_Installer_Role_Doc
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 {}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Cfg.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>cfg_dir</locationconfig>
<honorsbaseinstall />
<unusualbaseinstall>1</unusualbaseinstall>
<phpfile />
<executable />
<phpextension />
<config_vars />
</role>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Data.php
New file
0,0 → 1,27
<?php
/**
* PEAR_Installer_Role_Data
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 {}
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Man.php
New file
0,0 → 1,28
<?php
/**
* PEAR_Installer_Role_Man
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Hannes Magnusson <bjori@php.net>
* @copyright 2011 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version SVN: $Id: $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.10.0
*/
 
/**
* @category pear
* @package PEAR
* @author Hannes Magnusson <bjori@php.net>
* @copyright 2011 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.10.0
*/
class PEAR_Installer_Role_Man extends PEAR_Installer_Role_Common {}
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role/Test.php
New file
0,0 → 1,27
<?php
/**
* PEAR_Installer_Role_Test
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 {}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Installer/Role.php
New file
0,0 → 1,266
<?php
/**
* PEAR_Installer_Role
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
*/
public 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($class, $info['config_vars']);
}
}
 
/**
* @param PEAR_PackageFile_v2
* @param string role name
* @param PEAR_Config
* @return PEAR_Installer_Role_Common
*/
public 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
*/
public 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
*/
public static function getInstallableRoles($clear = false)
{
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
PEAR_Installer_Role::registerRoles();
}
 
static $ret;
if ($clear) {
unset($ret);
}
 
if (isset($ret)) {
return $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
*/
public static function getBaseinstallRoles($clear = false)
{
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
PEAR_Installer_Role::registerRoles();
}
 
static $ret;
if ($clear) {
unset($ret);
}
 
if (isset($ret)) {
return $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
*/
public static function getPhpRoles($clear = false)
{
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
PEAR_Installer_Role::registerRoles();
}
 
static $ret;
if ($clear) {
unset($ret);
}
 
if (isset($ret)) {
return $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
*/
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: does not exist/is not directory");
}
 
$dp = @opendir($dir);
if (empty($dp)) {
return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg");
}
 
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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Downloader/Package.php
New file
0,0 → 1,1981
<?php
/**
* PEAR_Downloader_Package
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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);
/**
* Error code when parameter initialization fails because no releases
* exist that will work with the existing PHP version
*/
define('PEAR_DOWNLOADER_PACKAGE_PHPVERSION', -1004);
 
/**
* 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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
* @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 __construct(&$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) {
return true;
}
 
$options = $this->_downloader->getOptions();
if (isset($options['offline'])) {
if (PEAR::isError($origErr) && !isset($options['soft'])) {
foreach ($origErr->getUserInfo() as $userInfo) {
if (isset($userInfo['message'])) {
$this->_downloader->log(0, $userInfo['message']);
}
}
 
$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) && !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);
}
 
if (!isset($options['soft'])) {
$this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file");
}
 
// Passing no message back - already logged above
return PEAR::raiseError();
}
 
if (PEAR::isError($err) && !isset($options['soft'])) {
$this->_downloader->log(0, $err->getMessage());
}
 
if (is_array($param)) {
$param = $this->_registry->parsedPackageNameToString($param, true);
}
 
if (!isset($options['soft'])) {
$this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file");
}
 
// Passing no message back - already logged above
return PEAR::raiseError();
}
}
 
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['channel'] == 'pecl.php.net' && $newinfo['channel'] == 'pear.php.net') {
$info['channel'] = 'pear.php.net';
if ($info == $newinfo) {
// skip the channel check if a pecl package says it's a PEAR package
break;
}
}
if ($info['channel'] == 'pear.php.net' && $newinfo['channel'] == 'pecl.php.net') {
$info['channel'] = 'pecl.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);
}
 
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
*/
public static function removeInstalled(&$params)
{
if (!isset($params[0])) {
return;
}
 
$options = $params[0]->_downloader->getOptions();
if (!isset($options['downloadonly'])) {
foreach ($params as $i => $param) {
$package = $param->getPackage();
$channel = $param->getChannel();
// remove self if already installed with this version
// this does not need any pecl magic - we only remove exact matches
if ($param->_installRegistry->packageExists($package, $channel)) {
$packageVersion = $param->_installRegistry->packageInfo($package, 'version', $channel);
if (version_compare($packageVersion, $param->getVersion(), '==')) {
if (!isset($options['force']) && !isset($options['packagingroot'])) {
$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 ' . $packageVersion);
}
$params[$i] = false;
}
} elseif (!isset($options['force']) && !isset($options['upgrade']) &&
!isset($options['soft']) && !isset($options['packagingroot'])) {
$info = $param->getParsedPackage();
$param->_downloader->log(1, 'Skipping package "' .
$param->getShortName() .
'", already installed as version ' . $packageVersion);
$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;
} elseif (PEAR::isError($ret) && !isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
}
} 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;
} elseif (PEAR::isError($ret) && !isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
}
}
}
 
// 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']);
}
 
$ret = $this->_detect2Dep($dep, $pname, 'optional', $params);
if (PEAR::isError($ret) && !isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
 
if (!$ret) {
$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()) {
continue;
}
 
$groupname = 'default'; // try the default dependency group
}
 
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) && 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;
} elseif (PEAR::isError($ret) && !isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
}
} else {
$ret = $this->_detect2Dep($group[$packagetype], $pname,
'dependency group "' .
$group['attribs']['name'] . '"', $params);
if (is_array($ret)) {
$this->_downloadDeps[] = $ret;
} elseif (PEAR::isError($ret) && !isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
}
}
}
}
 
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;
}
 
// 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 (isset ($dep['type']) && $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 optional 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) && 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();
}
 
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);
}
 
return false;
}
 
function getPackageType()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getPackageType();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getPackageType();
}
 
return false;
}
 
function isBundle()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getPackageType() == 'bundle';
}
 
return false;
}
 
function getPackageXmlVersion()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getPackagexmlVersion();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getPackagexmlVersion();
}
 
return '1.0';
}
 
function getChannel()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getChannel();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getChannel();
}
 
return false;
}
 
function getURI()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getURI();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getURI();
}
 
return false;
}
 
function getVersion()
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getVersion();
} elseif (isset($this->_downloadURL['version'])) {
return $this->_downloadURL['version'];
}
 
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);
}
 
return true;
}
 
function setGroup($group)
{
$this->_parsedname['group'] = $group;
}
 
function getGroup()
{
if (isset($this->_parsedname['group'])) {
return $this->_parsedname['group'];
}
 
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;
}
 
return false;
}
 
return false;
}
 
function getDeps()
{
if (isset($this->_packagefile)) {
$ver = $this->_packagefile->getPackagexmlVersion();
if (version_compare($ver, '2.0', '>=')) {
return $this->_packagefile->getDeps(true);
}
 
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);
}
 
return $this->_downloadURL['info']->getDeps();
}
 
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());
}
 
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'])) {
$packageVersion = $this->_installRegistry->packageInfo($package, 'version', $channel);
if (version_compare($packageVersion, $dep['version'], '>=')) {
return true;
}
 
return false;
}
 
return true;
}
 
return false;
}
 
/**
* Detect duplicate package names with differing versions
*
* If a user requests to install Date 1.4.6 and Date 1.4.7,
* for instance, this is a logic error. This method
* detects this situation.
*
* @param array $params array of PEAR_Downloader_Package objects
* @param array $errorparams empty array
* @return array array of stupid duplicated packages in PEAR_Downloader_Package obejcts
*/
public static function detectStupidDuplicates($params, &$errorparams)
{
$existing = array();
foreach ($params as $i => $param) {
$package = $param->getPackage();
$channel = $param->getChannel();
$group = $param->getGroup();
if (!isset($existing[$channel . '/' . $package])) {
$existing[$channel . '/' . $package] = array();
}
 
if (!isset($existing[$channel . '/' . $package][$group])) {
$existing[$channel . '/' . $package][$group] = array();
}
 
$existing[$channel . '/' . $package][$group][] = $i;
}
 
$indices = array();
foreach ($existing as $package => $groups) {
foreach ($groups as $group => $dupes) {
if (count($dupes) > 1) {
$indices = $indices + $dupes;
}
}
}
 
$indices = array_unique($indices);
foreach ($indices as $index) {
$errorparams[] = $params[$index];
}
 
return count($errorparams);
}
 
/**
* @param array
* @param bool ignore install groups - for final removal of dupe packages
*/
public static function removeDuplicates(&$params, $ignoreGroups = false)
{
$pnames = array();
foreach ($params as $i => $param) {
if (!$param) {
continue;
}
 
if ($param->getPackage()) {
$group = $ignoreGroups ? '' : $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;
}
 
$group = $ignoreGroups ? '' : $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;
}
 
/**
*/
public static function mergeDependencies(&$params)
{
$bundles = $newparams = 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;
}
 
// FIXME do symlink check
 
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;
}
$a = $dir . DIRECTORY_SEPARATOR . $file;
$e = $obj->_fromFile($a);
PEAR::popErrorHandling();
if (PEAR::isError($e)) {
if (!isset($options['soft'])) {
$dl->log(0, $e->getMessage());
}
continue;
}
 
if (!PEAR_Downloader_Package::willDownload($obj,
array_merge($params, $newparams)) && !$param->isInstalled($obj)) {
$newparams[] = $obj;
}
}
}
 
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) {
$merge = array_merge($params, $newparams);
if (!PEAR_Downloader_Package::willDownload($dep, $merge)
&& !$param->isInstalled($dep)
) {
$newdeps[] = $dep;
} else {
//var_dump($dep);
// 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());
}
}
 
$newparams[] = $obj;
}
}
 
if (count($newparams)) {
foreach ($newparams as $i => $unused) {
$params[] = &$newparams[$i];
}
return true;
}
 
return false;
}
 
 
/**
*/
public 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)
{
$a = new PEAR_PackageFile($c, $d);
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();
$pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->_debug);
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|https|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;
}
 
$this->_downloader->log(3, 'Downloading "' . $param . '"');
$file = $this->_downloader->downloadHttp($param, $this->_downloader->ui,
$dir, $callback, null, false, $this->getChannel());
$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') {
return PEAR::raiseError('CRITICAL ERROR: package.xml downloaded does ' .
'not match value returned from xml-rpc');
}
 
// 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');
}
}
 
// whew, download worked!
$pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug);
 
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());
}
 
///FIXME need to pass back some error code that we can use to match with to cancel all further operations
/// At least stop all deps of this package from being installed
$out = $saveparam ? $saveparam : $param;
$err = PEAR::raiseError('Download of "' . $out . '" 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();
$channel = $this->_config->get('default_channel');
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pname = $this->_registry->parsePackageName($param, $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, $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 = 'rest';
}
 
$this->_parsedname = $pname;
$this->_explicitState = isset($pname['state']) ? $pname['state'] : false;
$this->_explicitGroup = isset($pname['group']) ? true : 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 === false) {
$saveparam = !is_string($param) ? ", cannot download \"$param\"" : '';
 
// 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() . '")');
}
}
 
$preferred_state = $this->_config->get('preferred_state');
if (!isset($info['url'])) {
$package_version = $this->_registry->packageInfo($info['info']->getPackage(),
'version', $info['info']->getChannel());
if ($this->isInstalled($info)) {
if ($isdependency && version_compare($info['version'], $package_version, '<=')) {
// 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;
}
}
 
if ($info['version'] === $package_version) {
if (!isset($options['soft'])) {
$this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] .
'/' . $pname['package'] . '-' . $package_version. ', additionally the suggested version' .
' (' . $package_version . ') is the same as the locally installed one.');
}
 
return false;
}
 
if (version_compare($info['version'], $package_version, '<=')) {
if (!isset($options['soft'])) {
$this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] .
'/' . $pname['package'] . '-' . $package_version . ', additionally the suggested version' .
' (' . $info['version'] . ') is a lower version than the locally installed one (' . $package_version . ').');
}
 
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($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 "' . $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 "' . $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 {
if (isset($info['php']) && $info['php']) {
$err = PEAR::raiseError('Failed to download ' .
$this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'],
'package' => $pname['package']),
true) .
', latest release is version ' . $info['php']['v'] .
', but it requires PHP version "' .
$info['php']['m'] . '", use "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'], 'package' => $pname['package'],
'version' => $info['php']['v'])) . '" to install',
PEAR_DOWNLOADER_PACKAGE_PHPVERSION);
return $err;
}
 
// 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($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 "' . $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;
}
 
// Checks if the user has a package installed already and checks the release against
// the state against the installed package, this allows upgrades for packages
// with lower stability than the preferred_state
$stability = $this->_registry->packageInfo($pname['package'], 'stability', $pname['channel']);
if (!$this->isInstalled($info)
|| !in_array($info['info']->getState(), PEAR_Common::betterStates($stability['release'], true))
) {
$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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/ChannelFile.php
New file
0,0 → 1,1560
<?php
/**
* PEAR_ChannelFile, the channel handling class
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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 protocol
*/
define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10);
/**
* Error code when channel server is invalid for 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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct()
{
$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' => $result->getMessage()));
} 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
*
* @return PEAR_ChannelFile|false false if invalid
*/
public static 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
*
* @return PEAR_ChannelFile
*/
public static 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']['rest'])) {
$ret .= $this->_makeRestXml($channelInfo['servers']['primary']['rest'], ' ');
}
$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 <rest> tag
* @access private
*/
function _makeRestXml($info, $indent)
{
$ret = $indent . "<rest>\n";
if (isset($info['baseurl']) && !isset($info['baseurl'][0])) {
$info['baseurl'] = array($info['baseurl']);
}
 
if (isset($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['rest'])) {
if (isset($mirror['rest'])) {
$ret .= $this->_makeRestXml($mirror['rest'], ' ');
}
$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'], $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'], $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']['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']);
}
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['rest'])) {
$this->_validateFunctions('rest', $mirror['rest']['baseurl'],
$mirror['attribs']['host']);
}
}
}
return $this->_isValid;
}
 
/**
* @param string rest - 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_NOBASEURLTYPE,
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'];
}
 
return false;
}
 
/**
* @return string|false
*/
function getServer()
{
if (isset($this->_channelInfo['name'])) {
return $this->_channelInfo['name'];
}
 
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'];
}
 
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;
}
 
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'];
}
 
return false;
}
 
/**
* @param string protocol type
* @param string Mirror name
* @return array|false
*/
function getFunctions($protocol, $mirror = false)
{
if ($this->getName() == '__uri') {
return false;
}
 
$function = $protocol == 'rest' ? 'baseurl' : '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];
}
 
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) {
$mir = $this->getMirror($mirror);
if (!$mir) {
return false;
}
 
$rest = $mir['rest'];
} else {
$rest = $this->_channelInfo['servers']['primary']['rest'];
}
 
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
* @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;
}
 
return false;
}
 
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->resetREST($mirror);
 
if (!isset($this->_channelInfo['servers'])) {
$this->_channelInfo['servers'] = array('primary' =>
array('rest' => array()));
} elseif (!isset($this->_channelInfo['servers']['primary'])) {
$this->_channelInfo['servers']['primary'] = array('rest' => array());
}
 
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;
}
 
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;
}
 
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;
}
 
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;
}
 
/**
* @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'];
}
return '';
}
 
/**
* 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 = '')
{
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) {
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;
}
 
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();
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Registry.php
New file
0,0 → 1,2388
<?php
/**
* PEAR_Registry
*
* PHP versions 4 and 5
*
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Registry extends PEAR
{
/**
* 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 false|PEAR_ChannelFile
*/
var $_docChannel;
 
/**
* @var PEAR_DependencyDB
*/
var $_dependencyDB;
 
/**
* @var PEAR_Config
*/
var $_config;
 
/**
* 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 __construct($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false,
$pecl_channel = false, $pear_metadata_dir = '')
{
parent::__construct();
$this->setInstallDir($pear_install_dir, $pear_metadata_dir);
$this->_pearChannel = $pear_channel;
$this->_peclChannel = $pecl_channel;
$this->_config = false;
}
 
function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR, $pear_metadata_dir = '')
{
$ds = DIRECTORY_SEPARATOR;
$this->install_dir = $pear_install_dir;
if (!$pear_metadata_dir) {
$pear_metadata_dir = $pear_install_dir;
}
$this->channelsdir = $pear_metadata_dir.$ds.'.channels';
$this->statedir = $pear_metadata_dir.$ds.'.registry';
$this->filemap = $pear_metadata_dir.$ds.'.filemap';
$this->lockfile = $pear_metadata_dir.$ds.'.lock';
}
 
function hasWriteAccess()
{
if (!file_exists($this->install_dir)) {
$dir = $this->install_dir;
while ($dir && $dir != '.') {
$olddir = $dir;
$dir = dirname($dir);
if ($dir != '.' && file_exists($dir)) {
if (is_writeable($dir)) {
return true;
}
 
return false;
}
 
if ($dir == $olddir) { // this can happen in safe mode
return @is_writable($dir);
}
}
 
return false;
}
 
return is_writeable($this->install_dir);
}
 
function setConfig(&$config, $resetInstallDir = true)
{
$this->_config = &$config;
if ($resetInstallDir) {
$this->setInstallDir($config->get('php_dir'), $config->get('metadata_dir'));
}
}
 
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 . 'doc.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->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/');
$pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/');
//$pear_channel->setBaseURL('REST1.4', 'http://pear.php.net/rest/');
} else {
$pear_channel->setServer('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->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->setServer('pecl.php.net');
$pecl_channel->setAlias('pecl');
}
 
$pecl_channel->validate();
$this->_addChannel($pecl_channel);
}
 
if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) {
$doc_channel = $this->_docChannel;
if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) {
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$doc_channel = new PEAR_ChannelFile;
$doc_channel->setAlias('phpdocs');
$doc_channel->setServer('doc.php.net');
$doc_channel->setSummary('PHP Documentation Team');
$doc_channel->setDefaultPEARProtocols();
$doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/');
$doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/');
$doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/');
} else {
$doc_channel->setServer('doc.php.net');
$doc_channel->setAlias('doc');
}
 
$doc_channel->validate();
$this->_addChannel($doc_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->setDefaultPEARProtocols();
$private->setBaseURL('REST1.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\\z/', $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?
$file = OS_WINDOWS ? 'pear.ini' : '.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('metadata_dir', null, 'pear.php.net') .
DIRECTORY_SEPARATOR . '.depdb')) {
@unlink($this->_config->get('metadata_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;
}
}
}
 
/**
* PEAR_Registry destructor. Makes sure no locks are forgotten.
*
* @access private
*/
function _PEAR_Registry()
{
parent::_PEAR();
if (is_resource($this->lock_fp)) {
$this->_unlock();
}
}
 
/**
* 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 . 'doc.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;
}
 
/**
* 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;
}
 
/**
* 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;
}
 
/**
* 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';
}
 
/**
* 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';
}
 
/**
* @param string
* @return string
*/
function _getChannelAliasFileName($alias)
{
return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' .
DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt';
}
 
/**
* 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 == 'doc.php.net') {
return 'doc.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)));
}
 
return $channel;
}
 
/**
* 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';
}
 
if ($channel == 'doc.php.net') {
return 'phpdocs';
}
 
return false;
}
 
$channel = $this->_getChannel($channel);
if (PEAR::isError($channel)) {
return $channel;
}
 
return $channel->getAlias();
}
 
/**
* 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;
}
 
$ch = $this->_getChannelFromAlias($channel);
if (!$ch) {
$ch = $channel;
}
 
return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' .
str_replace('/', '_', $ch));
}
 
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;
}
 
function _closePackageFile($fp)
{
fclose($fp);
}
 
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;
}
 
function _closeChannelFile($fp)
{
fclose($fp);
}
 
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') {
if (!isset($files[$attrs['role']])) {
$files[$attrs['role']] = array();
}
$files[$attrs['role']][$file] = array(strtolower($channel),
strtolower($package));
} else {
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;
}
 
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();
$fsize = filesize($this->filemap);
fclose($fp);
$data = file_get_contents($this->filemap);
$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 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 (stristr(php_uname(), 'Windows 9')) {
return true;
}
 
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');
}
 
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)) {
$this->lock_fp = null;
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;
}
 
//is resource at this point, close it on error.
fclose($this->lock_fp);
$this->lock_fp = null;
return $this->raiseError("could not acquire $str lock ($this->lockfile)",
PEAR_REGISTRY_ERROR_LOCK);
}
 
return true;
}
 
function _unlock()
{
$ret = $this->_lock(LOCK_UN);
if (is_resource($this->lock_fp)) {
fclose($this->lock_fp);
}
 
$this->lock_fp = null;
return $ret;
}
 
function _packageExists($package, $channel = false)
{
return file_exists($this->_packageFileName($package, $channel));
}
 
/**
* 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;
}
 
if (!$a && $channel == 'doc.php.net') {
return true;
}
 
return $a;
}
 
/**
* Determine whether a mirror exists within the deafult channel in the registry
*
* @param string Channel name
* @param string Mirror name
*
* @return boolean
*/
function _mirrorExists($channel, $mirror)
{
$data = $this->_channelInfo($channel);
if (!isset($data['servers']['mirror'])) {
return false;
}
 
foreach ($data['servers']['mirror'] as $m) {
if ($m['attribs']['host'] == $mirror) {
return true;
}
}
 
return false;
}
 
/**
* @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', 'doc.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;
}
 
/**
* 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')) {
return false;
}
 
if (!$channel->validate()) {
return false;
}
$channel = $channel->getName();
}
 
if ($this->_getChannelFromAlias($channel) == '__uri') {
return false;
}
 
if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
return false;
}
 
if ($this->_getChannelFromAlias($channel) == 'doc.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;
}
 
/**
* Determine whether a channel exists in the registry
* @param string Channel Alias
* @return boolean
*/
function _isChannelAlias($alias)
{
return file_exists($this->_getChannelAliasFileName($alias));
}
 
/**
* @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;
}
 
clearstatcache();
$this->_closePackageFile($fp);
$data = file_get_contents($this->_packageFileName($package, $channel));
$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;
}
 
/**
* @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;
}
 
clearstatcache();
$this->_closeChannelFile($fp);
$data = file_get_contents($this->_channelFileName($channel));
$data = unserialize($data);
return $data;
}
 
function _listChannels()
{
$channellist = array();
if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) {
return array('pear.php.net', 'pecl.php.net', 'doc.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('doc.php.net', $channellist)) {
$channellist[] = 'doc.php.net';
}
 
 
if (!in_array('__uri', $channellist)) {
$channellist[] = '__uri';
}
 
natsort($channellist);
return $channellist;
}
 
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;
}
 
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 (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) {
return false;
}
 
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->setServer('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/');
$pear_channel->setBaseURL('REST1.3', '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->setServer('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) == 'doc.php.net') {
// the registry is not properly set up, so use defaults
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$doc_channel = new PEAR_ChannelFile;
$doc_channel->setServer('doc.php.net');
$doc_channel->setAlias('phpdocs');
$doc_channel->setSummary('PHP Documentation Team');
$doc_channel->setDefaultPEARProtocols();
$doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/');
$doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/');
$doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/');
return $doc_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->setDefaultPEARProtocols();
$private->setBaseURL('REST1.0', '****');
$private->setSummary('Pseudo-channel for static packages');
return $private;
}
 
return $ch;
}
 
/**
* @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;
}
 
// }}}
 
/**
* @param string channel name mirror is in
* @param string mirror name
*
* @return bool
*/
function mirrorExists($channel, $mirror)
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
 
$ret = $this->_mirrorExists($channel, $mirror);
$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') || !$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);
$ret = file_exists($file) ? @unlink($file) : 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);
$this->_unlock();
if (!$ret) {
return PEAR::raiseError('Unknown channel: ' . $channel);
}
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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Task/Postinstallscript/rw.php
New file
0,0 → 1,182
<?php
/**
* <tasks:postinstallscript> - read/write version
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
*/
public $_pkg;
/**
* Enter description here...
*
* @param PEAR_PackageFile_v2_rw $pkg Package
* @param PEAR_Config $config Config
* @param PEAR_Frontend $logger Logger
* @param array $fileXml XML
*
* @return PEAR_Task_Postinstallscript_rw
*/
function __construct(&$pkg, &$config, &$logger, $fileXml)
{
parent::__construct($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
public function validate()
{
return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
}
 
public 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
*/
public 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
*/
public 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;
}
 
public function getXml()
{
return $this->_params;
}
 
/**
* Use to set up a param tag for use in creating a paramgroup
*
* @param mixed $name Name of parameter
* @param mixed $prompt Prompt
* @param string $type Type, defaults to 'string'
* @param mixed $default Default value
*
* @return array
*/
public 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,
);
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Task/Replace.php
New file
0,0 → 1,186
<?php
/**
* <tasks:replace>
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Replace extends PEAR_Task_Common
{
public $type = 'simple';
public $phase = PEAR_TASK_PACKAGEANDINSTALL;
public $_replacements;
 
/**
* Validate the raw xml at parsing-time.
*
* @param PEAR_PackageFile_v2
* @param array raw, parsed xml
* @param PEAR_Config
*/
public 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
* @param unused
*/
public function init($xml, $attribs, $lastVersion = null)
{
$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
*/
public 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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Task/Unixeol/rw.php
New file
0,0 → 1,55
<?php
/**
* <tasks:unixeol> - read/write version
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct(&$pkg, &$config, &$logger, $fileXml)
{
parent::__construct($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
public function validate()
{
return true;
}
 
public function getName()
{
return 'unixeol';
}
 
public function getXml()
{
return '';
}
}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Task/Postinstallscript.php
New file
0,0 → 1,349
<?php
/**
* <tasks:postinstallscript>
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Postinstallscript extends PEAR_Task_Common
{
public $type = 'script';
public $_class;
public $_params;
public $_obj;
/**
*
* @var PEAR_PackageFile_v2
*/
public $_pkg;
public $_contents;
public $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
*/
public 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 $xml raw, parsed xml
* @param array $fileattribs attributes from the <file> tag containing
* this task
* @param string|null $lastversion last installed version of this package,
* if any (useful for upgrades)
*/
public 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
*/
public 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 mixed $pkg PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param string $contents file name
*
* @return bool|PEAR_Error false to skip this file, PEAR_Error to fail
* (use $this->throwError)
*/
public 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
*/
public static function run()
{
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Task/Unixeol.php
New file
0,0 → 1,79
<?php
/**
* <tasks:unixeol>
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Unixeol extends PEAR_Task_Common
{
public $type = 'simple';
public $phase = PEAR_TASK_PACKAGE;
public $_replacements;
 
/**
* Validate the raw xml at parsing-time.
*
* @param PEAR_PackageFile_v2
* @param array raw, parsed xml
* @param PEAR_Config
*/
public 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
* @param unused
*/
public function init($xml, $attribs, $lastVersion = null)
{
}
 
/**
* 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
*/
public 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);
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Task/Windowseol/rw.php
New file
0,0 → 1,56
<?php
/**
* <tasks:windowseol> - read/write version
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct(&$pkg, &$config, &$logger, $fileXml)
{
parent::__construct($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
public function validate()
{
return true;
}
 
public function getName()
{
return 'windowseol';
}
 
public function getXml()
{
return '';
}
}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Task/Replace/rw.php
New file
0,0 → 1,59
<?php
/**
* <tasks:replace> - read/write version
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
{
public function __construct(&$pkg, &$config, &$logger, $fileXml)
{
parent::__construct($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
public function validate()
{
return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
}
 
public function setInfo($from, $to, $type)
{
$this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type));
}
 
public function getName()
{
return 'replace';
}
 
public function getXml()
{
return $this->_params;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Task/Common.php
New file
0,0 → 1,207
<?php
/**
* PEAR_Task_Common, base class for installer tasks
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
*/
protected $type = 'simple';
/**
* Determines which install phase this task is executed under
*/
public $phase = PEAR_TASK_INSTALL;
/**
* @access protected
*/
protected $config;
/**
* @access protected
*/
protected $registry;
/**
* @access protected
*/
public $logger;
/**
* @access protected
*/
protected $installphase;
/**
* @param PEAR_Config
* @param PEAR_Common
*/
function __construct(&$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
*
* @abstract
*/
public static 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
*/
public 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
*/
public 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
*/
public static function run($tasks)
{
}
 
/**
* @final
*/
public static function hasPostinstallTasks()
{
return isset($GLOBALS['_PEAR_TASK_POSTINSTANCES']);
}
 
/**
* @final
*/
public static 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
*/
public function isScript()
{
return $this->type == 'script';
}
 
public function throwError($msg, $code = -1)
{
include_once 'PEAR.php';
 
return PEAR::raiseError($msg, $code);
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Task/Windowseol.php
New file
0,0 → 1,80
<?php
/**
* <tasks:windowseol>
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Windowseol extends PEAR_Task_Common
{
public $type = 'simple';
public $phase = PEAR_TASK_PACKAGE;
public $_replacements;
 
/**
* Validate the raw xml at parsing-time.
*
* @param PEAR_PackageFile_v2
* @param array raw, parsed xml
* @param PEAR_Config
*/
public 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
* @param unused
*/
public function init($xml, $attribs, $lastVersion = null)
{
}
 
/**
* 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
*/
public 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);
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/XMLParser.php
New file
0,0 → 1,247
<?php
/**
* PEAR_XMLParser
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Stephan Schmidt (original XML_Unserializer code)
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license New BSD License
* @version Release: 1.10.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;
 
/**
* The XML encoding to use
* @var string $encoding
*/
var $encoding = 'ISO-8859-1';
 
/**
* @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->_dataStack = $this->_valStack = array();
$this->_depth = 0;
 
if (
strpos($data, 'encoding="UTF-8"')
|| strpos($data, 'encoding="utf-8"')
|| strpos($data, "encoding='UTF-8'")
|| strpos($data, "encoding='utf-8'")
) {
$this->encoding = 'UTF-8';
}
 
$xp = xml_parser_create($this->encoding);
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)
{
$this->_depth++;
$this->_dataStack[$this->_depth] = null;
 
$val = array(
'name' => $element,
'value' => null,
'type' => 'string',
'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;
}
 
$value['value'] = isset($value['children']) ? $value['children'] : 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;
}
 
// 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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/REST.php
New file
0,0 → 1,496
<?php
/**
* PEAR_REST
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_REST
{
var $config;
var $_options;
 
function __construct(&$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, $channel = 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, $channel);
}
 
/**
* 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, $channel = false)
{
$cacheId = $this->getCacheId($url);
if ($ret = $this->useLocalCache($url, $cacheId)) {
return $ret;
}
 
$file = $trieddownload = false;
if (!isset($this->_options['offline'])) {
$trieddownload = true;
$file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept, $channel);
}
 
if (PEAR::isError($file)) {
if ($file->getCode() !== -9276) {
return $file;
}
 
$trieddownload = false;
$file = false; // use local copy if available on socket connect error
}
 
if (!$file) {
$ret = $this->getCache($url);
if (!PEAR::isError($ret) && $trieddownload) {
// reset the age of the cache if the server says it was unmodified
$result = $this->saveCache($url, $ret, null, true, $cacheId);
if (PEAR::isError($result)) {
return PEAR::raiseError($result->getMessage());
}
}
 
return $ret;
}
 
if (is_array($file)) {
$headers = $file[2];
$lastmodified = $file[1];
$content = $file[0];
} else {
$headers = array();
$lastmodified = false;
$content = $file;
}
 
if ($forcestring) {
$result = $this->saveCache($url, $content, $lastmodified, false, $cacheId);
if (PEAR::isError($result)) {
return PEAR::raiseError($result->getMessage());
}
 
return $content;
}
 
if (isset($headers['content-type'])) {
$content_type = explode(";", $headers['content-type']);
$content_type = $content_type[0];
switch ($content_type) {
case 'text/xml' :
case 'application/xml' :
case 'text/plain' :
if ($content_type === 'text/plain') {
$check = substr($content, 0, 5);
if ($check !== '<?xml') {
break;
}
}
 
$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();
}
 
$result = $this->saveCache($url, $content, $lastmodified, false, $cacheId);
if (PEAR::isError($result)) {
return PEAR::raiseError($result->getMessage());
}
 
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)) {
return false;
}
 
$cacheid = unserialize(implode('', file($cacheidfile)));
}
 
$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)) {
return false;
}
 
$ret = unserialize(implode('', file($cacheidfile)));
return $ret;
}
 
function getCache($url)
{
$cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cachefile';
 
if (!file_exists($cachefile)) {
return PEAR::raiseError('No cached content available for "' . $url . '"');
}
 
return unserialize(implode('', file($cachefile)));
}
 
/**
* @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)
{
$cache_dir = $this->config->get('cache_dir');
$d = $cache_dir . DIRECTORY_SEPARATOR . md5($url);
$cacheidfile = $d . 'rest.cacheid';
$cachefile = $d . 'rest.cachefile';
 
if (!is_dir($cache_dir)) {
if (System::mkdir(array('-p', $cache_dir)) === false) {
return PEAR::raiseError("The value of config option cache_dir ($cache_dir) is not a directory and attempts to create the directory failed.");
}
}
 
if (!is_writeable($cache_dir)) {
// If writing to the cache dir is not going to work, silently do nothing.
// An ugly hack, but retains compat with PEAR 1.9.1 where many commands
// work fine as non-root user (w/out write access to default cache dir).
return true;
}
 
if ($cacheid === null && $nochange) {
$cacheid = unserialize(implode('', file($cacheidfile)));
}
 
$idData = serialize(array(
'age' => time(),
'lastChange' => ($nochange ? $cacheid['lastChange'] : $lastmodified),
));
 
$result = $this->saveCacheFile($cacheidfile, $idData);
if (PEAR::isError($result)) {
return $result;
} elseif ($nochange) {
return true;
}
 
$result = $this->saveCacheFile($cachefile, serialize($contents));
if (PEAR::isError($result)) {
if (file_exists($cacheidfile)) {
@unlink($cacheidfile);
}
 
return $result;
}
 
return true;
}
 
function saveCacheFile($file, $contents)
{
$len = strlen($contents);
 
$cachefile_fp = @fopen($file, 'xb'); // x is the O_CREAT|O_EXCL mode
if ($cachefile_fp !== false) { // create file
if (fwrite($cachefile_fp, $contents, $len) < $len) {
fclose($cachefile_fp);
return PEAR::raiseError("Could not write $file.");
}
} else { // update file
$cachefile_fp = @fopen($file, 'r+b'); // do not truncate file
if (!$cachefile_fp) {
return PEAR::raiseError("Could not open $file for writing.");
}
 
if (OS_WINDOWS) {
$not_symlink = !is_link($file); // see bug #18834
} else {
$cachefile_lstat = lstat($file);
$cachefile_fstat = fstat($cachefile_fp);
$not_symlink = $cachefile_lstat['mode'] == $cachefile_fstat['mode']
&& $cachefile_lstat['ino'] == $cachefile_fstat['ino']
&& $cachefile_lstat['dev'] == $cachefile_fstat['dev']
&& $cachefile_fstat['nlink'] === 1;
}
 
if ($not_symlink) {
ftruncate($cachefile_fp, 0); // NOW truncate
if (fwrite($cachefile_fp, $contents, $len) < $len) {
fclose($cachefile_fp);
return PEAR::raiseError("Could not write $file.");
}
} else {
fclose($cachefile_fp);
$link = function_exists('readlink') ? readlink($file) : $file;
return PEAR::raiseError('SECURITY ERROR: Will not write to ' . $file . ' as it is symlinked to ' . $link . ' - Possible symlink attack');
}
}
 
fclose($cachefile_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, $channel = false)
{
static $redirect = 0;
// always reset , so we are clean case of error
$wasredirect = $redirect;
$redirect = 0;
 
$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 . '"');
}
 
$host = isset($info['host']) ? $info['host'] : null;
$port = isset($info['port']) ? $info['port'] : null;
$path = isset($info['path']) ? $info['path'] : null;
$schema = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http';
 
$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 ($schema === '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;
$proxy_schema = (isset($proxy['scheme']) && $proxy['scheme'] == 'https') ? 'https' : 'http';
}
 
if (empty($port)) {
$port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80;
}
 
if (isset($proxy['host'])) {
$request = "GET $url HTTP/1.1\r\n";
} else {
$request = "GET $path HTTP/1.1\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.10.1/PHP/" . PHP_VERSION . "\r\n";
 
$username = $this->config->get('username', null, $channel);
$password = $this->config->get('password', null, $channel);
 
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 .= "Accept-Encoding:\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 ($schema === '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();
$reply = 0;
while ($line = trim(fgets($fp, 1024))) {
if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $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 $schema://$host:$port$path not valid (received: $line)");
}
}
}
 
if ($reply != 200) {
if (!isset($headers['location'])) {
return PEAR::raiseError("File $schema://$host:$port$path not valid (redirected but no location)");
}
 
if ($wasredirect > 4) {
return PEAR::raiseError("File $schema://$host:$port$path not valid (redirection looped more than 5 times)");
}
 
$redirect = $wasredirect + 1;
return $this->downloadHttp($headers['location'], $lastmodified, $accept, $channel);
}
 
$length = isset($headers['content-length']) ? $headers['content-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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Packager.php
New file
0,0 → 1,200
<?php
/**
* PEAR_Packager for generating releases
*
* PHP versions 4 and 5
*
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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;
 
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");
}
 
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");
}
 
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");
}
 
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");
}
 
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)");
} elseif (file_exists("$pkgdir/.svn")) {
$svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion());
$svntag = $pf->getName() . "-$svnversion";
$this->log(1, 'Tag the released code with "pear svntag ' .
$main->getPackageFile() . '"');
$this->log(1, "(or set the SVN tag $svntag 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)");
} elseif (file_exists("$pkgdir/.svn")) {
$svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion());
$svntag = $pf->getName() . "-$svnversion";
$this->log(1, "Tag the released code with `pear svntag $pkgfile'");
$this->log(1, "(or set the SVN tag $svntag by hand)");
}
}
 
return $dest_package;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Command.php
New file
0,0 → 1,389
<?php
/**
* PEAR_Command, command pattern class
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
*/
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()
public static 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
*/
public 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
*/
public 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
*/
public 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
*/
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 ($file = readdir($dp)) {
if ($file{0} == '.' || substr($file, -4) != '.xml') {
continue;
}
 
$f = substr($file, 0, -4);
$class = "PEAR_Command_" . $f;
// List of commands
if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
$GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php';
}
 
$parser->parse(file_get_contents("$dir/$file"));
$implements = $parser->getData();
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
*/
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
*/
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
*/
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
*/
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
*/
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;
}
// }}}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/ErrorStack.php
New file
0,0 → 1,979
<?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-2008 Greg Beaver
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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.10.1
* @package PEAR_ErrorStack
* @category Debugging
* @copyright 2004-2008 Greg Beaver
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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 __construct($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
*
* @return PEAR_ErrorStack
*/
public static 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
*/
public 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
*/
public 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
*/
public static function staticPushCallback($cb)
{
array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
}
/**
* Remove a temporary overriding error callback
* @see staticPushCallback()
* @return array|string|false
*/
public 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()}
*/
public 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
*/
public 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
*
* @return array
*/
public static 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
*/
public static 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()
*/
public 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+)\) : (.*?)\\z;', $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
*
* @return string
*/
public static 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'));
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/Frontend.php
New file
0,0 → 1,223
<?php
/**
* PEAR_Frontend, the singleton-based frontend for user input/output
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* Include error handling
*/
//require_once 'PEAR.php';
 
/**
* 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
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
*/
public static function &singleton($type = null)
{
if ($type === null) {
if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) {
$a = false;
return $a;
}
return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
}
 
$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
*/
public 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 (is_a($obj, 'PEAR_Frontend')) {
$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj;
$GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass;
return $obj;
}
 
$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
*/
public 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;
}
 
$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject;
$GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject);
return $uiobject;
}
 
/**
* @param string $path relative or absolute include path
* @return boolean
*/
public static function isIncludeable($path)
{
if (file_exists($path) && is_readable($path)) {
return true;
}
 
$fp = @fopen($path, 'r', true);
if ($fp) {
fclose($fp);
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;
}
 
/**
* Log an action
*
* @param string $msg the message to log
* @param boolean $append_crlf
* @return boolean true
* @abstract
*/
function log($msg, $append_crlf = true)
{
}
 
/**
* Run a post-installation script
*
* @param array $scripts array of post-install scripts
* @abstract
*/
function runPostinstallScripts(&$scripts)
{
}
 
/**
* Display human-friendly output formatted depending on the
* $command parameter.
*
* This should be able to handle basic output data with no command
* @param mixed $data data structure containing the information to display
* @param string $command command from which this method was called
* @abstract
*/
function outputData($data, $command = '_default')
{
}
 
/**
* Display a modal form dialog and return the given input
*
* A frontend that requires multiple requests to retrieve and process
* data must take these needs into account, and implement the request
* handling code.
* @param string $command command from which this method was called
* @param array $prompts associative array. keys are the input field names
* and values are the description
* @param array $types array of input field types (text, password,
* etc.) keys have to be the same like in $prompts
* @param array $defaults array of default values. again keys have
* to be the same like in $prompts. Do not depend
* on a default value being set.
* @return array input sent by the user
* @abstract
*/
function userDialog($command, $prompts, $types = array(), $defaults = array())
{
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/ChannelFile/Parser.php
New file
0,0 → 1,67
<?php
/**
* PEAR_ChannelFile_Parser for parsing channel.xml
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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;
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/DependencyDB.php
New file
0,0 → 1,764
<?php
/**
* PEAR_DependencyDB, advanced installed packages dependency database
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
*/
public static function &singleton(&$config, $depdb = false)
{
$phpdir = $config->get('php_dir', null, 'pear.php.net');
if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) {
$a = new PEAR_DependencyDB;
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a;
$a->setConfig($config, $depdb);
$e = $a->assertDepsDB();
if (PEAR::isError($e)) {
return $e;
}
}
 
return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir];
}
 
/**
* 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) {
$dir = $this->_config->get('metadata_dir', null, 'pear.php.net');
if (!$dir) {
$dir = $this->_config->get('php_dir', null, 'pear.php.net');
}
$this->_depdb = $dir . 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;
}
 
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();
return;
}
 
$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 (
isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) &&
strtolower($dep['dep']['channel']) == $channel &&
strtolower($dep['dep']['name']) == $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']) == $depchannel &&
strtolower($info['dep']['name']) == $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;
$depchannel = isset($dep['dep']['uri']) ? '__uri' : strtolower($dep['dep']['channel']);
$depname = strtolower($dep['dep']['name']);
if (isset($data['packages'][$depchannel][$depname])) {
foreach ($data['packages'][$depchannel][$depname] as $i => $info) {
if ($info['channel'] == $channel && $info['package'] == $package) {
$found = true;
break;
}
}
}
 
if ($found) {
unset($data['packages'][$depchannel][$depname][$i]);
if (!count($data['packages'][$depchannel][$depname])) {
unset($data['packages'][$depchannel][$depname]);
if (!count($data['packages'][$depchannel])) {
unset($data['packages'][$depchannel]);
}
} else {
$data['packages'][$depchannel][$depname] =
array_values($data['packages'][$depchannel][$depname]);
}
}
}
 
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();
if (PEAR::isError($packages)) {
return $packages;
}
 
foreach ($packages as $channel => $ps) {
foreach ($ps as $package) {
$package = $this->_registry->getPackage($package, $channel);
if (PEAR::isError($package)) {
return $package;
}
$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 (stristr(php_uname(), 'Windows 9')) {
return true;
}
 
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;
}
 
clearstatcache();
fclose($fp);
$data = unserialize(file_get_contents($this->_depdb));
$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");
}
 
fwrite($fp, serialize($deps));
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();
}
 
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
 
if (!isset($data['dependencies'][$channel])) {
$data['dependencies'][$channel] = array();
}
 
$data['dependencies'][$channel][$package] = 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'][$channel][$package] == array()) {
unset($data['dependencies'][$channel][$package]);
if (!count($data['dependencies'][$channel])) {
unset($data['dependencies'][$channel]);
}
}
}
 
/**
* @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
);
 
$dep = array_map('strtolower', $dep);
$depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
if (!isset($data['dependencies'])) {
$data['dependencies'] = array();
}
 
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
 
if (!isset($data['dependencies'][$channel])) {
$data['dependencies'][$channel] = array();
}
 
if (!isset($data['dependencies'][$channel][$package])) {
$data['dependencies'][$channel][$package] = array();
}
 
$data['dependencies'][$channel][$package][] = $info;
if (isset($data['packages'][$depchannel][$dep['name']])) {
$found = false;
foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) {
if ($p['channel'] == $channel && $p['package'] == $package) {
$found = true;
break;
}
}
} else {
if (!isset($data['packages'])) {
$data['packages'] = array();
}
 
if (!isset($data['packages'][$depchannel])) {
$data['packages'][$depchannel] = array();
}
 
if (!isset($data['packages'][$depchannel][$dep['name']])) {
$data['packages'][$depchannel][$dep['name']] = array();
}
 
$found = false;
}
 
if (!$found) {
$data['packages'][$depchannel][$dep['name']][] = array(
'channel' => $channel,
'package' => $package
);
}
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/Builder.php
New file
0,0 → 1,499
<?php
/**
* PEAR_Builder for building PHP extensions (PECL packages)
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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';
require_once 'System.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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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
{
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;
 
/**
* PEAR_Builder constructor.
*
* @param object $ui user interface object (instance of PEAR_Frontend_*)
*
* @access public
*/
function __construct(&$ui)
{
parent::__construct();
$this->setFrontendObject($ui);
}
 
/**
* 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)) {
return $this->raiseError("could not chdir to " . realpath($vdir));
}
 
$dir = getcwd();
}
 
$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);
}
 
/**
* @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 an extension from source. Runs "phpize" in the source
* directory, but compiles in a temporary directory
* (TMPDIR/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)
{
if (preg_match('/(\\/|\\\\|^)([^\\/\\\\]+)?php([^\\/\\\\]+)?$/',
$this->config->get('php_bin'), $matches)) {
if (isset($matches[2]) && strlen($matches[2]) &&
trim($matches[2]) != trim($this->config->get('php_prefix'))) {
$this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') .
' appears to have a prefix ' . $matches[2] . ', but' .
' config variable php_prefix does not match');
}
 
if (isset($matches[3]) && strlen($matches[3]) &&
trim($matches[3]) != trim($this->config->get('php_suffix'))) {
$this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') .
' appears to have a suffix ' . $matches[3] . ', but' .
' config variable php_suffix does not match');
}
}
 
$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();
if (is_a($pkg, 'PEAR_PackageFile_v1')) {
$dir = dirname($descfile);
} else {
$dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName();
// automatically delete at session end
$this->addTempFile($dir);
}
} else {
$pf = new PEAR_PackageFile($this->config);
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pkg)) {
return $pkg;
}
$dir = dirname($descfile);
}
 
// Find config. outside of normal path - e.g. config.m4
foreach (array_keys($pkg->getInstallationFileList()) as $item) {
if (stristr(basename($item), 'config.m4') && dirname($item) != '.') {
$dir .= DIRECTORY_SEPARATOR . dirname($item);
break;
}
}
 
$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($this->config->get('php_prefix')
. "phpize" .
$this->config->get('php_suffix'),
array(&$this, 'phpizeCallback'));
if (PEAR::isError($err)) {
return $err;
}
 
if (!$err) {
return $this->raiseError("`phpize' failed");
}
 
// {{{ start of interactive part
$configure_command = "$dir/configure";
 
$phpConfigName = $this->config->get('php_prefix')
. 'php-config'
. $this->config->get('php_suffix');
$phpConfigPath = System::which($phpConfigName);
if ($phpConfigPath !== false) {
$configure_command .= ' --with-php-config='
. $phpConfigPath;
}
 
$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';
}
 
$tmpdir = $this->config->get('temp_dir');
$build_basedir = System::mktemp(' -t "' . $tmpdir . '" -d "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);
 
$make_command = getenv('MAKE') ? getenv('MAKE') : 'make';
 
$to_run = array(
$configure_command,
$make_command,
"$make_command INSTALL_ROOT=\"$inst_dir\" install",
"find \"$inst_dir\" | xargs ls -dils"
);
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.10.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($this->config->get('php_prefix')
. "php-config" .
$this->config->get('php_suffix') . " --prefix");
$this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files);
chdir($old_cwd);
return $built_files;
}
 
/**
* 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);
}
}
}
 
/**
* 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;
}
 
$exitcode = is_resource($pp) ? pclose($pp) : -1;
return ($exitcode == 0);
}
 
function log($level, $msg, $append_crlf = true)
{
if ($this->current_callback) {
if ($this->debug >= $level) {
call_user_func($this->current_callback, 'output', $msg);
}
return;
}
return parent::log($level, $msg, $append_crlf);
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/REST/10.php
New file
0,0 → 1,870
<?php
/**
* PEAR_REST_10
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct($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 = false)
{
$states = $this->betterStates($prefstate, true);
if (!$states) {
return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
}
 
$channel = $packageinfo['channel'];
$package = $packageinfo['package'];
$state = isset($packageinfo['state']) ? $packageinfo['state'] : null;
$version = isset($packageinfo['version']) ? $packageinfo['version'] : null;
$restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml';
 
$info = $this->_rest->retrieveData($restFile, false, false, $channel);
if (PEAR::isError($info)) {
return PEAR::raiseError('No releases available for package "' .
$channel . '/' . $package . '"');
}
 
if (!isset($info['r'])) {
return false;
}
 
$release = $found = 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, false, $channel);
}
 
function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage,
$prefstate = 'stable', $installed = false, $channel = false)
{
$states = $this->betterStates($prefstate, true);
if (!$states) {
return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
}
 
$channel = $dependency['channel'];
$package = $dependency['name'];
$state = isset($dependency['state']) ? $dependency['state'] : null;
$version = isset($dependency['version']) ? $dependency['version'] : null;
$restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml';
 
$info = $this->_rest->retrieveData($restFile, false, false, $channel);
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') {
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 {
$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']);
}
}
}
$release = $found = 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, false, $channel);
}
}
}
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, false, $channel);
}
 
/**
* 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|null $found determines whether the release was found or this is the next
* best alternative. If null, then versions were skipped because
* of PHP dependency
* @return array|PEAR_Error
* @access private
*/
function _returnDownloadURL($base, $package, $release, $info, $found, $phpversion = false, $channel = false)
{
if (!$found) {
$release = $info['r'][0];
}
 
$packageLower = strtolower($package);
$pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . $packageLower . '/' .
'info.xml', false, false, $channel);
if (PEAR::isError($pinfo)) {
return PEAR::raiseError('Package "' . $package .
'" does not have REST info xml available');
}
 
$releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' .
$release['v'] . '.xml', false, false, $channel);
if (PEAR::isError($releaseinfo)) {
return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] .
'" does not have REST xml available');
}
 
$packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' .
'deps.' . $release['v'] . '.txt', false, true, $channel);
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/' . $packageLower .
'/allreleases.xml', false, false, $channel);
if (PEAR::isError($allinfo)) {
return $allinfo;
}
 
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;
}
 
$deprecated = false;
if (isset($pinfo['dc']) && isset($pinfo['dp'])) {
if (is_array($pinfo['dp'])) {
$deprecated = array('channel' => (string) $pinfo['dc'],
'package' => trim($pinfo['dp']['_content']));
} else {
$deprecated = array('channel' => (string) $pinfo['dc'],
'package' => trim($pinfo['dp']));
}
}
 
$return = array(
'version' => $releaseinfo['v'],
'info' => $packagexml,
'package' => $releaseinfo['p']['_content'],
'stability' => $releaseinfo['st'],
'compatible' => $compatible,
'deprecated' => $deprecated,
);
 
if ($found) {
$return['url'] = $releaseinfo['g'];
return $return;
}
 
$return['php'] = $phpversion;
return $return;
}
 
function listPackages($base, $channel = false)
{
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
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'];
}
 
/**
* List all categories of a REST server
*
* @param string $base base URL of the server
* @return array of categorynames
*/
function listCategories($base, $channel = false)
{
$categories = array();
 
// c/categories.xml does not exist;
// check for every package its category manually
// This is SLOOOWWWW : ///
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
if (PEAR::isError($packagelist)) {
return $packagelist;
}
 
if (!is_array($packagelist) || !isset($packagelist['p'])) {
$ret = array();
return $ret;
}
 
if (!is_array($packagelist['p'])) {
$packagelist['p'] = array($packagelist['p']);
}
 
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
foreach ($packagelist['p'] as $package) {
$inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
if (PEAR::isError($inf)) {
PEAR::popErrorHandling();
return $inf;
}
$cat = $inf['ca']['_content'];
if (!isset($categories[$cat])) {
$categories[$cat] = $inf['ca'];
}
}
 
return array_values($categories);
}
 
/**
* List a category of a REST server
*
* @param string $base base URL of the server
* @param string $category name of the category
* @param boolean $info also download full package info
* @return array of packagenames
*/
function listCategory($base, $category, $info = false, $channel = false)
{
// gives '404 Not Found' error when category doesn't exist
$packagelist = $this->_rest->retrieveData($base.'c/'.urlencode($category).'/packages.xml', false, false, $channel);
if (PEAR::isError($packagelist)) {
return $packagelist;
}
 
if (!is_array($packagelist) || !isset($packagelist['p'])) {
return array();
}
 
if (!is_array($packagelist['p']) ||
!isset($packagelist['p'][0])) { // only 1 pkg
$packagelist = array($packagelist['p']);
} else {
$packagelist = $packagelist['p'];
}
 
if ($info == true) {
// get individual package info
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
foreach ($packagelist as $i => $packageitem) {
$url = sprintf('%s'.'r/%s/latest.txt',
$base,
strtolower($packageitem['_content']));
$version = $this->_rest->retrieveData($url, false, false, $channel);
if (PEAR::isError($version)) {
break; // skipit
}
$url = sprintf('%s'.'r/%s/%s.xml',
$base,
strtolower($packageitem['_content']),
$version);
$info = $this->_rest->retrieveData($url, false, false, $channel);
if (PEAR::isError($info)) {
break; // skipit
}
$packagelist[$i]['info'] = $info;
}
PEAR::popErrorHandling();
}
 
return $packagelist;
}
 
 
function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false)
{
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
if (PEAR::isError($packagelist)) {
return $packagelist;
}
if ($this->_rest->config->get('verbose') > 0) {
$ui = &PEAR_Frontend::singleton();
$ui->log('Retrieving data...0%', true);
}
$ret = array();
if (!is_array($packagelist) || !isset($packagelist['p'])) {
return $ret;
}
if (!is_array($packagelist['p'])) {
$packagelist['p'] = array($packagelist['p']);
}
 
// only search-packagename = quicksearch !
if ($searchpackage && (!$searchsummary || empty($searchpackage))) {
$newpackagelist = array();
foreach ($packagelist['p'] as $package) {
if (!empty($searchpackage) && stristr($package, $searchpackage) !== false) {
$newpackagelist[] = $package;
}
}
$packagelist['p'] = $newpackagelist;
}
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', false, false, $channel);
} else {
$latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/latest.txt', false, false, $channel);
}
if (PEAR::isError($latest)) {
$latest = false;
}
$info = array('stable' => $latest);
} else { // list-all command
$inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
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', false, false, $channel);
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', false, false, $channel);
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, $pref_state, $installed, $channel, &$reg)
{
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
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']);
}
 
foreach ($packagelist['p'] as $package) {
if (!isset($installed[strtolower($package)])) {
continue;
}
 
$inst_version = $reg->packageInfo($package, 'version', $channel);
$inst_state = $reg->packageInfo($package, 'release_state', $channel);
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/allreleases.xml', false, false, $channel);
PEAR::popErrorHandling();
if (PEAR::isError($info)) {
continue; // no remote releases
}
 
if (!isset($info['r'])) {
continue;
}
 
$release = $found = false;
if (!is_array($info['r']) || !isset($info['r'][0])) {
$info['r'] = array($info['r']);
}
 
// $info['r'] is sorted by version number
usort($info['r'], array($this, '_sortReleasesByVersionNumber'));
foreach ($info['r'] as $release) {
if ($inst_version && version_compare($release['v'], $inst_version, '<=')) {
// not newer than the one installed
break;
}
 
// new version > installed version
if (!$pref_state) {
// every state is a good state
$found = true;
break;
} else {
$new_state = $release['s'];
// if new state >= installed state: go
if (in_array($new_state, $this->betterStates($inst_state, true))) {
$found = true;
break;
} else {
// only allow to lower the state of package,
// if new state >= preferred state: go
if (in_array($new_state, $this->betterStates($pref_state, true))) {
$found = true;
break;
}
}
}
}
 
if (!$found) {
continue;
}
 
$relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
$release['v'] . '.xml', false, false, $channel);
if (PEAR::isError($relinfo)) {
return $relinfo;
}
 
$ret[$package] = array(
'version' => $release['v'],
'state' => $release['s'],
'filesize' => $relinfo['f'],
);
}
 
return $ret;
}
 
function packageInfo($base, $package, $channel = false)
{
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pinfo = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
if (PEAR::isError($pinfo)) {
PEAR::popErrorHandling();
return PEAR::raiseError('Unknown package: "' . $package . '" in channel "' . $channel . '"' . "\n". 'Debug: ' .
$pinfo->getMessage());
}
 
$releases = array();
$allreleases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/allreleases.xml', false, false, $channel);
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', false, false, $channel);
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', false, false, $channel);
 
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'])) {
if (is_array($pinfo['dp'])) {
$deprecated = array('channel' => (string) $pinfo['dc'],
'package' => trim($pinfo['dp']['_content']));
} else {
$deprecated = array('channel' => (string) $pinfo['dc'],
'package' => trim($pinfo['dp']));
}
} else {
$deprecated = false;
}
 
if (!isset($latest)) {
$latest = '';
}
 
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);
}
 
/**
* Sort releases by version number
*
* @access private
*/
function _sortReleasesByVersionNumber($a, $b)
{
if (version_compare($a['v'], $b['v'], '=')) {
return 0;
}
 
if (version_compare($a['v'], $b['v'], '>')) {
return -1;
}
 
if (version_compare($a['v'], $b['v'], '<')) {
return 1;
}
}
}
/branches/v1.3-critias/bibliotheque/pear/PEAR/REST/11.php
New file
0,0 → 1,340
<?php
/**
* PEAR_REST_11 - implement faster list-all/remote-list command
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.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 __construct($config, $options = array())
{
$this->_rest = new PEAR_REST($config, $options);
}
 
function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false)
{
$categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
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', false, false, $channel);
 
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) {
if (empty($packageinfo)) {
continue;
}
 
$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') {
$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
if (!isset($unstable)) {
$unstable = false;
$state = 'stable';
if (isset($stable)) {
$latest = $unstable = $stable;
}
} else {
$latest = $unstable;
}
 
if (!isset($latest)) {
$latest = false;
}
 
$deps = array();
if ($latest && 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;
}
 
/**
* List all categories of a REST server
*
* @param string $base base URL of the server
* @return array of categorynames
*/
function listCategories($base, $channel = false)
{
$categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
if (PEAR::isError($categorylist)) {
return $categorylist;
}
 
if (!is_array($categorylist) || !isset($categorylist['c'])) {
return array();
}
 
if (isset($categorylist['c']['_content'])) {
// only 1 category
$categorylist['c'] = array($categorylist['c']);
}
 
return $categorylist['c'];
}
 
/**
* List packages in a category of a REST server
*
* @param string $base base URL of the server
* @param string $category name of the category
* @param boolean $info also download full package info
* @return array of packagenames
*/
function listCategory($base, $category, $info = false, $channel = false)
{
if ($info == false) {
$url = '%s'.'c/%s/packages.xml';
} else {
$url = '%s'.'c/%s/packagesinfo.xml';
}
$url = sprintf($url,
$base,
urlencode($category));
 
// gives '404 Not Found' error when category doesn't exist
$packagelist = $this->_rest->retrieveData($url, false, false, $channel);
if (PEAR::isError($packagelist)) {
return $packagelist;
}
if (!is_array($packagelist)) {
return array();
}
 
if ($info == false) {
if (!isset($packagelist['p'])) {
return array();
}
if (!is_array($packagelist['p']) ||
!isset($packagelist['p'][0])) { // only 1 pkg
$packagelist = array($packagelist['p']);
} else {
$packagelist = $packagelist['p'];
}
return $packagelist;
}
 
// info == true
if (!isset($packagelist['pi'])) {
return array();
}
 
if (!is_array($packagelist['pi']) ||
!isset($packagelist['pi'][0])) { // only 1 pkg
$packagelist_pre = array($packagelist['pi']);
} else {
$packagelist_pre = $packagelist['pi'];
}
 
$packagelist = array();
foreach ($packagelist_pre as $i => $item) {
// compatibility with r/<latest.txt>.xml
if (isset($item['a']['r'][0])) {
// multiple releases
$item['p']['v'] = $item['a']['r'][0]['v'];
$item['p']['st'] = $item['a']['r'][0]['s'];
} elseif (isset($item['a'])) {
// first and only release
$item['p']['v'] = $item['a']['r']['v'];
$item['p']['st'] = $item['a']['r']['s'];
}
 
$packagelist[$i] = array('attribs' => $item['p']['r'],
'_content' => $item['p']['n'],
'info' => $item['p']);
}
 
return $packagelist;
}
 
/**
* 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);
}
}
?>
/branches/v1.3-critias/bibliotheque/pear/PEAR/REST/13.php
New file
0,0 → 1,396
<?php
/**
* PEAR_REST_13
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @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';
require_once 'PEAR/REST/10.php';
 
/**
* Implement REST 1.3
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a12
*/
class PEAR_REST_13 extends PEAR_REST_10
{
/**
* Retrieve information about a remote package to be downloaded from a REST server
*
* This is smart enough to resolve the minimum PHP version dependency prior to download
* @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 = false)
{
$states = $this->betterStates($prefstate, true);
if (!$states) {
return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
}
 
$channel = $packageinfo['channel'];
$package = $packageinfo['package'];
$state = isset($packageinfo['state']) ? $packageinfo['state'] : null;
$version = isset($packageinfo['version']) ? $packageinfo['version'] : null;
$restFile = $base . 'r/' . strtolower($package) . '/allreleases2.xml';
 
$info = $this->_rest->retrieveData($restFile, false, false, $channel);
if (PEAR::isError($info)) {
return PEAR::raiseError('No releases available for package "' .
$channel . '/' . $package . '"');
}
 
if (!isset($info['r'])) {
return false;
}
 
$release = $found = false;
if (!is_array($info['r']) || !isset($info['r'][0])) {
$info['r'] = array($info['r']);
}
 
$skippedphp = false;
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) {
if (!isset($version) && version_compare($release['m'], phpversion(), '>')) {
// skip releases that require a PHP version newer than our PHP version
$skippedphp = $release;
continue;
}
$found = true;
break;
}
 
// see if there is something newer and more stable
// bug #7221
if (in_array($release['s'], $this->betterStates($state), true)) {
if (!isset($version) && version_compare($release['m'], phpversion(), '>')) {
// skip releases that require a PHP version newer than our PHP version
$skippedphp = $release;
continue;
}
$found = true;
break;
}
} elseif (isset($version)) {
if ($release['v'] == $version) {
if (!isset($this->_rest->_options['force']) &&
!isset($version) &&
version_compare($release['m'], phpversion(), '>')) {
// skip releases that require a PHP version newer than our PHP version
$skippedphp = $release;
continue;
}
$found = true;
break;
}
} else {
if (in_array($release['s'], $states)) {
if (version_compare($release['m'], phpversion(), '>')) {
// skip releases that require a PHP version newer than our PHP version
$skippedphp = $release;
continue;
}
$found = true;
break;
}
}
}
 
if (!$found && $skippedphp) {
$found = null;
}
 
return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel);
}
 
function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage,
$prefstate = 'stable', $installed = false, $channel = false)
{
$states = $this->betterStates($prefstate, true);
if (!$states) {
return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
}
 
$channel = $dependency['channel'];
$package = $dependency['name'];
$state = isset($dependency['state']) ? $dependency['state'] : null;
$version = isset($dependency['version']) ? $dependency['version'] : null;
$restFile = $base . 'r/' . strtolower($package) .'/allreleases2.xml';
 
$info = $this->_rest->retrieveData($restFile, false, false, $channel);
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']);
}
}
}
 
$skippedphp = $found = $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'])) {
if (version_compare($release['m'], phpversion(), '>')) {
// skip dependency releases that require a PHP version
// newer than our PHP version
$skippedphp = $release;
continue;
}
 
$recommended = $release['v'];
break;
}
}
}
 
if ($recommended) {
if ($release['v'] != $recommended) { // if we want a specific
// version, then skip all others
continue;
}
 
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, false, $channel);
}
}
 
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...
if (version_compare($release['m'], phpversion(), '>')) {
// skip dependency releases that require a PHP version
// newer than our PHP version
$skippedphp = $release;
continue;
}
 
$found = true; // ... then use it
break;
}
}
 
if (!$found && $skippedphp) {
$found = null;
}
 
return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel);
}
 
/**
* List package upgrades but take the PHP version into account.
*/
function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg)
{
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
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']);
}
 
foreach ($packagelist['p'] as $package) {
if (!isset($installed[strtolower($package)])) {
continue;
}
 
$inst_version = $reg->packageInfo($package, 'version', $channel);
$inst_state = $reg->packageInfo($package, 'release_state', $channel);
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/allreleases2.xml', false, false, $channel);
PEAR::popErrorHandling();
if (PEAR::isError($info)) {
continue; // no remote releases
}
 
if (!isset($info['r'])) {
continue;
}
 
$release = $found = false;
if (!is_array($info['r']) || !isset($info['r'][0])) {
$info['r'] = array($info['r']);
}
 
// $info['r'] is sorted by version number
usort($info['r'], array($this, '_sortReleasesByVersionNumber'));
foreach ($info['r'] as $release) {
if ($inst_version && version_compare($release['v'], $inst_version, '<=')) {
// not newer than the one installed
break;
}
if (version_compare($release['m'], phpversion(), '>')) {
// skip dependency releases that require a PHP version
// newer than our PHP version
continue;
}
 
// new version > installed version
if (!$pref_state) {
// every state is a good state
$found = true;
break;
} else {
$new_state = $release['s'];
// if new state >= installed state: go
if (in_array($new_state, $this->betterStates($inst_state, true))) {
$found = true;
break;
} else {
// only allow to lower the state of package,
// if new state >= preferred state: go
if (in_array($new_state, $this->betterStates($pref_state, true))) {
$found = true;
break;
}
}
}
}
 
if (!$found) {
continue;
}
 
$relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
$release['v'] . '.xml', false, false, $channel);
if (PEAR::isError($relinfo)) {
return $relinfo;
}
 
$ret[$package] = array(
'version' => $release['v'],
'state' => $release['s'],
'filesize' => $relinfo['f'],
);
}
 
return $ret;
}
}
/branches/v1.3-critias/bibliotheque/pear/scripts/peardev.sh
New file
0,0 → 1,28
#!/bin/sh
 
# first find which PHP binary to use
if test "x$PHP_PEAR_PHP_BIN" != "x"; then
PHP="$PHP_PEAR_PHP_BIN"
else
if test "@php_bin@" = '@'php_bin'@'; then
PHP=php
else
PHP="@php_bin@"
fi
fi
 
# then look for the right pear include dir
if test "x$PHP_PEAR_INSTALL_DIR" != "x"; then
INCDIR=$PHP_PEAR_INSTALL_DIR
INCARG="-d include_path=$PHP_PEAR_INSTALL_DIR"
else
if test "@php_dir@" = '@'php_dir'@'; then
INCDIR=`dirname $0`
INCARG=""
else
INCDIR="@php_dir@"
INCARG="-d include_path=@php_dir@"
fi
fi
 
exec $PHP -d date.timezone=UTC -d memory_limit="-1" -C -q $INCARG -d output_buffering=1 -d open_basedir="" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d variables_order=EGPCS -d auto_append_file="" $INCDIR/pearcmd.php "$@"
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/pear/scripts/pear.sh
New file
0,0 → 1,28
#!/bin/sh
 
# first find which PHP binary to use
if test "x$PHP_PEAR_PHP_BIN" != "x"; then
PHP="$PHP_PEAR_PHP_BIN"
else
if test "@php_bin@" = '@'php_bin'@'; then
PHP=php
else
PHP="@php_bin@"
fi
fi
 
# then look for the right pear include dir
if test "x$PHP_PEAR_INSTALL_DIR" != "x"; then
INCDIR=$PHP_PEAR_INSTALL_DIR
INCARG="-d include_path=$PHP_PEAR_INSTALL_DIR"
else
if test "@php_dir@" = '@'php_dir'@'; then
INCDIR=`dirname $0`
INCARG=""
else
INCDIR="@php_dir@"
INCARG="-d include_path=@php_dir@"
fi
fi
 
exec $PHP -C -q $INCARG -d date.timezone=UTC -d output_buffering=1 -d variables_order=EGPCS -d open_basedir="" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d auto_append_file="" $INCDIR/pearcmd.php "$@"
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/pear/scripts/pearcmd.php
New file
0,0 → 1,497
<?php
/**
* PEAR, the PHP Extension and Application Repository
*
* Command line interface
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
*/
 
@ob_end_clean();
if (!defined('PEAR_RUNTYPE')) {
// this is defined in peclcmd.php as 'pecl'
define('PEAR_RUNTYPE', 'pear');
}
define('PEAR_IGNORE_BACKTRACE', 1);
/**
* @nodep Gtk
*/
//the space is needed for windows include paths with trailing backslash
// http://pear.php.net/bugs/bug.php?id=19482
if ('@include_path@ ' != '@'.'include_path'.'@ ') {
ini_set('include_path', trim('@include_path@ '). PATH_SEPARATOR . get_include_path());
$raw = false;
} else {
// this is a raw, uninstalled pear, either a cvs checkout, or php distro
$raw = true;
}
@ini_set('allow_url_fopen', true);
@set_time_limit(0);
ob_implicit_flush(true);
@ini_set('track_errors', true);
@ini_set('html_errors', false);
$_PEAR_PHPDIR = '#$%^&*';
set_error_handler('error_handler');
 
$pear_package_version = "@pear_version@";
 
require_once 'PEAR.php';
require_once 'PEAR/Frontend.php';
require_once 'PEAR/Config.php';
require_once 'PEAR/Command.php';
require_once 'Console/Getopt.php';
 
 
PEAR_Command::setFrontendType('CLI');
$all_commands = PEAR_Command::getCommands();
 
// remove this next part when we stop supporting that crap-ass PHP 4.2
if (!isset($_SERVER['argv']) && !isset($argv) && !isset($HTTP_SERVER_VARS['argv'])) {
echo 'ERROR: either use the CLI php executable, ' .
'or set register_argc_argv=On in php.ini';
exit(1);
}
 
$argv = Console_Getopt::readPHPArgv();
// fix CGI sapi oddity - the -- in pear.bat/pear is not removed
if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') {
unset($argv[1]);
$argv = array_values($argv);
}
$progname = PEAR_RUNTYPE;
array_shift($argv);
$options = Console_Getopt::getopt2($argv, "c:C:d:D:Gh?sSqu:vV");
if (PEAR::isError($options)) {
usage($options);
}
 
$opts = $options[0];
 
$fetype = 'CLI';
if ($progname == 'gpear' || $progname == 'pear-gtk') {
$fetype = 'Gtk2';
} else {
foreach ($opts as $opt) {
if ($opt[0] == 'G') {
$fetype = 'Gtk2';
}
}
}
 
$pear_user_config = '';
$pear_system_config = '';
$store_user_config = false;
$store_system_config = false;
$verbose = 1;
 
foreach ($opts as $opt) {
switch ($opt[0]) {
case 'c':
$pear_user_config = $opt[1];
break;
case 'C':
$pear_system_config = $opt[1];
break;
}
}
 
PEAR_Command::setFrontendType($fetype);
$ui = &PEAR_Command::getFrontendObject();
$config = &PEAR_Config::singleton($pear_user_config, $pear_system_config);
 
if (PEAR::isError($config)) {
$_file = '';
if ($pear_user_config !== false) {
$_file .= $pear_user_config;
}
if ($pear_system_config !== false) {
$_file .= '/' . $pear_system_config;
}
if ($_file == '/') {
$_file = 'The default config file';
}
$config->getMessage();
$ui->outputData("ERROR: $_file is not a valid config file or is corrupted.");
// We stop, we have no idea where we are :)
exit(1);
}
 
// this is used in the error handler to retrieve a relative path
$_PEAR_PHPDIR = $config->get('php_dir');
$ui->setConfig($config);
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError"));
 
$verbose = $config->get("verbose");
$cmdopts = array();
 
if ($raw) {
if (!$config->isDefinedLayer('user') && !$config->isDefinedLayer('system')) {
$found = false;
foreach ($opts as $opt) {
if ($opt[0] == 'd' || $opt[0] == 'D') {
// the user knows what they are doing, and are setting config values
$found = true;
}
}
if (!$found) {
// no prior runs, try to install PEAR
$parent = dirname(__FILE__);
if (strpos($parent, 'scripts')) {
$grandparent = dirname($parent);
$packagexml = $grandparent . DIRECTORY_SEPARATOR . 'package2.xml';
$pearbase = $grandparent;
} else {
$packagexml = $parent . DIRECTORY_SEPARATOR . 'package2.xml';
$pearbase = $parent;
}
if (file_exists($packagexml)) {
$options[1] = array(
'install',
$packagexml
);
$config->set('php_dir', $pearbase . DIRECTORY_SEPARATOR . 'php');
$config->set('data_dir', $pearbase . DIRECTORY_SEPARATOR . 'data');
$config->set('doc_dir', $pearbase . DIRECTORY_SEPARATOR . 'docs');
$config->set('test_dir', $pearbase . DIRECTORY_SEPARATOR . 'tests');
$config->set(
'ext_dir',
$pearbase . DIRECTORY_SEPARATOR . 'extensions'
);
$config->set('bin_dir', $pearbase);
$config->mergeConfigFile($pearbase . 'pear.ini', false);
$config->store();
$config->set('auto_discover', 1);
}
}
}
}
foreach ($opts as $opt) {
$param = !empty($opt[1]) ? $opt[1] : true;
switch ($opt[0]) {
case 'd':
if ($param === true) {
die(
'Invalid usage of "-d" option, expected -d config_value=value, ' .
'received "-d"' . "\n"
);
}
$possible = explode('=', $param);
if (count($possible) != 2) {
die(
'Invalid usage of "-d" option, expected ' .
'-d config_value=value, received "' . $param . '"' . "\n"
);
}
list($key, $value) = explode('=', $param);
$config->set($key, $value, 'user');
break;
case 'D':
if ($param === true) {
die(
'Invalid usage of "-d" option, expected ' .
'-d config_value=value, received "-d"' . "\n"
);
}
$possible = explode('=', $param);
if (count($possible) != 2) {
die(
'Invalid usage of "-d" option, expected ' .
'-d config_value=value, received "' . $param . '"' . "\n"
);
}
list($key, $value) = explode('=', $param);
$config->set($key, $value, 'system');
break;
case 's':
$store_user_config = true;
break;
case 'S':
$store_system_config = true;
break;
case 'u':
$config->remove($param, 'user');
break;
case 'v':
$config->set('verbose', $config->get('verbose') + 1);
break;
case 'q':
$config->set('verbose', $config->get('verbose') - 1);
break;
case 'V':
usage(null, 'version');
case 'c':
case 'C':
break;
default:
// all non pear params goes to the command
$cmdopts[$opt[0]] = $param;
break;
}
}
 
if ($store_system_config) {
$config->store('system');
}
 
if ($store_user_config) {
$config->store('user');
}
 
$command = (isset($options[1][0])) ? $options[1][0] : null;
if (empty($command) && ($store_user_config || $store_system_config)) {
exit;
}
 
if ($fetype == 'Gtk2') {
if (!$config->validConfiguration()) {
PEAR::raiseError(
"CRITICAL ERROR: no existing valid configuration files found in " .
"files '$pear_user_config' or '$pear_system_config', " .
"please copy an existing configuration file to one of these " .
"locations, or use the -c and -s options to create one"
);
}
Gtk::main();
} else {
do {
if ($command == 'help') {
usage(null, isset($options[1][1]) ? $options[1][1] : null);
}
 
if (!$config->validConfiguration()) {
PEAR::raiseError(
"CRITICAL ERROR: no existing valid configuration files found " .
"in files '$pear_user_config' or '$pear_system_config', " .
"please copy an existing configuration file to one of " .
"these locations, or use the -c and -s options to create one"
);
}
 
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$cmd = PEAR_Command::factory($command, $config);
PEAR::popErrorHandling();
if (PEAR::isError($cmd)) {
usage(null, isset($options[1][0]) ? $options[1][0] : null);
}
 
$short_args = $long_args = null;
PEAR_Command::getGetoptArgs($command, $short_args, $long_args);
array_shift($options[1]);
$tmp = Console_Getopt::getopt2($options[1], $short_args, $long_args);
 
if (PEAR::isError($tmp)) {
break;
}
 
list($tmpopt, $params) = $tmp;
$opts = array();
foreach ($tmpopt as $foo => $tmp2) {
list($opt, $value) = $tmp2;
if ($value === null) {
$value = true; // options without args
}
 
if (strlen($opt) == 1) {
$cmdoptions = $cmd->getOptions($command);
foreach ($cmdoptions as $o => $d) {
if (isset($d['shortopt']) && $d['shortopt'] == $opt) {
$opts[$o] = $value;
}
}
} else {
if (substr($opt, 0, 2) == '--') {
$opts[substr($opt, 2)] = $value;
}
}
}
 
$ok = $cmd->run($command, $opts, $params);
if ($ok === false) {
PEAR::raiseError("unknown command `$command'");
}
 
if (PEAR::isError($ok)) {
PEAR::setErrorHandling(
PEAR_ERROR_CALLBACK, array($ui, "displayFatalError")
);
PEAR::raiseError($ok);
}
} while (false);
}
 
// {{{ usage()
 
/**
* Display usage information
*
* @param mixed $error Optional error message
* @param mixed $helpsubject Optional subject/command to display help for
*
* @return void
*/
function usage($error = null, $helpsubject = null)
{
global $progname, $all_commands;
$stdout = fopen('php://stdout', 'w');
if (PEAR::isError($error)) {
fputs($stdout, $error->getMessage() . "\n");
} elseif ($error !== null) {
fputs($stdout, "$error\n");
}
 
if ($helpsubject != null) {
$put = cmdHelp($helpsubject);
} else {
$put = "Commands:\n";
$maxlen = max(array_map("strlen", $all_commands));
$formatstr = "%-{$maxlen}s %s\n";
ksort($all_commands);
foreach ($all_commands as $cmd => $class) {
$put .= sprintf($formatstr, $cmd, PEAR_Command::getDescription($cmd));
}
$put .=
"Usage: $progname [options] command [command-options] <parameters>\n".
"Type \"$progname help options\" to list all options.\n".
"Type \"$progname help shortcuts\" to list all command shortcuts.\n".
"Type \"$progname help version\" or ".
"\"$progname version\" to list version information.\n".
"Type \"$progname help <command>\" to get the help ".
"for the specified command.";
}
fputs($stdout, "$put\n");
fclose($stdout);
 
if ($error === null) {
exit(0);
}
exit(1);
}
 
/**
* Return help string for specified command
*
* @param string $command Command to return help for
*
* @return void
*/
function cmdHelp($command)
{
global $progname, $all_commands, $config;
if ($command == "options") {
return
"Options:\n".
" -v increase verbosity level (default 1)\n".
" -q be quiet, decrease verbosity level\n".
" -c file find user configuration in `file'\n".
" -C file find system configuration in `file'\n".
" -d foo=bar set user config variable `foo' to `bar'\n".
" -D foo=bar set system config variable `foo' to `bar'\n".
" -G start in graphical (Gtk) mode\n".
" -s store user configuration\n".
" -S store system configuration\n".
" -u foo unset `foo' in the user configuration\n".
" -h, -? display help/usage (this message)\n".
" -V version information\n";
} elseif ($command == "shortcuts") {
$sc = PEAR_Command::getShortcuts();
$ret = "Shortcuts:\n";
foreach ($sc as $s => $c) {
$ret .= sprintf(" %-8s %s\n", $s, $c);
}
return $ret;
 
} elseif ($command == "version") {
return "PEAR Version: ".$GLOBALS['pear_package_version'].
"\nPHP Version: ".phpversion().
"\nZend Engine Version: ".zend_version().
"\nRunning on: ".php_uname();
 
} elseif ($help = PEAR_Command::getHelp($command)) {
if (is_string($help)) {
return "$progname $command [options] $help\n";
}
 
if ($help[1] === null) {
return "$progname $command $help[0]";
}
 
return "$progname $command [options] $help[0]\n$help[1]";
}
 
return "Command '$command' is not valid, try '$progname help'";
}
 
// }}}
 
/**
* error_handler
*
* @param mixed $errno Error number
* @param mixed $errmsg Message
* @param mixed $file Filename
* @param mixed $line Line number
* @param mixed $vars Variables
*
* @access public
* @return boolean
*/
function error_handler($errno, $errmsg, $file, $line, $vars)
{
if ($errno & E_STRICT
|| $errno & E_DEPRECATED
|| !error_reporting()
) {
if ($errno & E_STRICT) {
return; // E_STRICT
}
if ($errno & E_DEPRECATED) {
return; // E_DEPRECATED
}
if (!error_reporting() && isset($GLOBALS['config']) && $GLOBALS['config']->get('verbose') < 4) {
return false; // @silenced error, show all if debug is high enough
}
}
$errortype = array (
E_DEPRECATED => 'Deprecated Warning',
E_ERROR => "Error",
E_WARNING => "Warning",
E_PARSE => "Parsing Error",
E_STRICT => 'Strict Warning',
E_NOTICE => "Notice",
E_CORE_ERROR => "Core Error",
E_CORE_WARNING => "Core Warning",
E_COMPILE_ERROR => "Compile Error",
E_COMPILE_WARNING => "Compile Warning",
E_USER_ERROR => "User Error",
E_USER_WARNING => "User Warning",
E_USER_NOTICE => "User Notice"
);
$prefix = $errortype[$errno];
global $_PEAR_PHPDIR;
if (stristr($file, $_PEAR_PHPDIR)) {
$file = substr($file, strlen($_PEAR_PHPDIR) + 1);
} else {
$file = basename($file);
}
print "\n$prefix: $errmsg in $file on line $line\n";
return false;
}
 
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: nil
* mode: php
* End:
*/
// vim600:syn=php
/branches/v1.3-critias/bibliotheque/pear/scripts/pecl.bat
New file
0,0 → 1,115
@ECHO OFF
 
REM ----------------------------------------------------------------------
REM PHP version 5
REM ----------------------------------------------------------------------
REM Copyright (c) 1997-2004 The PHP Group
REM ----------------------------------------------------------------------
REM This source file is subject to version 3.0 of the PHP license,
REM that is bundled with this package in the file LICENSE, and is
REM available at through the world-wide-web at
REM http://www.php.net/license/3_0.txt.
REM If you did not receive a copy of the PHP license and are unable to
REM obtain it through the world-wide-web, please send a note to
REM license@php.net so we can mail you a copy immediately.
REM ----------------------------------------------------------------------
REM Authors: Alexander Merz (alexmerz@php.net)
REM ----------------------------------------------------------------------
REM
REM Last updated 02/08/2004 ($Id$ is not replaced if the file is binary)
 
REM change this lines to match the paths of your system
REM -------------------
 
 
REM Test to see if this is a raw pear.bat (uninstalled version)
SET TMPTMPTMPTMPT=@includ
SET PMTPMTPMT=%TMPTMPTMPTMPT%e_path@
FOR %%x IN ("@include_path@") DO (if %%x=="%PMTPMTPMT%" GOTO :NOTINSTALLED)
 
REM Check PEAR global ENV, set them if they do not exist
IF "%PHP_PEAR_INSTALL_DIR%"=="" SET "PHP_PEAR_INSTALL_DIR=@include_path@"
IF "%PHP_PEAR_BIN_DIR%"=="" SET "PHP_PEAR_BIN_DIR=@bin_dir@"
IF "%PHP_PEAR_PHP_BIN%"=="" SET "PHP_PEAR_PHP_BIN=@php_bin@"
GOTO :INSTALLED
 
:NOTINSTALLED
ECHO WARNING: This is a raw, uninstalled pear.bat
 
REM Check to see if we can grab the directory of this file (Windows NT+)
IF %~n0 == pear (
FOR %%x IN (cli\php.exe php.exe) DO (if "%%~$PATH:x" NEQ "" (
SET "PHP_PEAR_PHP_BIN=%%~$PATH:x"
echo Using PHP Executable "%PHP_PEAR_PHP_BIN%"
"%PHP_PEAR_PHP_BIN%" -v
GOTO :NEXTTEST
))
GOTO :FAILAUTODETECT
:NEXTTEST
IF "%PHP_PEAR_PHP_BIN%" NEQ "" (
 
REM We can use this PHP to run a temporary php file to get the dirname of pear
 
echo ^<?php $s=getcwd^(^);chdir^($a=dirname^(__FILE__^).'\\'^);if^(stristr^($a,'\\scripts'^)^)$a=dirname^(dirname^($a^)^).'\\';$f=fopen^($s.'\\~a.a','wb'^);echo$s.'\\~a.a';fwrite^($f,$a^);fclose^($f^);chdir^($s^);?^> > ~~getloc.php
"%PHP_PEAR_PHP_BIN%" ~~getloc.php
set /p PHP_PEAR_BIN_DIR=fakeprompt < ~a.a
DEL ~a.a
DEL ~~getloc.php
set "PHP_PEAR_INSTALL_DIR=%PHP_PEAR_BIN_DIR%pear"
 
REM Make sure there is a pearcmd.php at our disposal
 
IF NOT EXIST %PHP_PEAR_INSTALL_DIR%\pearcmd.php (
IF EXIST %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php COPY %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php
IF EXIST pearcmd.php COPY pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php
IF EXIST %~dp0\scripts\pearcmd.php COPY %~dp0\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php
)
)
GOTO :INSTALLED
) ELSE (
REM Windows Me/98 cannot succeed, so allow the batch to fail
)
:FAILAUTODETECT
echo WARNING: failed to auto-detect pear information
:INSTALLED
 
REM Check Folders and files
IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%" GOTO PEAR_INSTALL_ERROR
IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" GOTO PEAR_INSTALL_ERROR2
IF NOT EXIST "%PHP_PEAR_BIN_DIR%" GOTO PEAR_BIN_ERROR
IF NOT EXIST "%PHP_PEAR_PHP_BIN%" GOTO PEAR_PHPBIN_ERROR
REM launch pearcmd
GOTO RUN
:PEAR_INSTALL_ERROR
ECHO PHP_PEAR_INSTALL_DIR is not set correctly.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_INSTALL_DIR%
GOTO END
:PEAR_INSTALL_ERROR2
ECHO PHP_PEAR_INSTALL_DIR is not set correctly.
ECHO pearcmd.php could not be found there.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_INSTALL_DIR%
GOTO END
:PEAR_BIN_ERROR
ECHO PHP_PEAR_BIN_DIR is not set correctly.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_BIN_DIR%
GOTO END
:PEAR_PHPBIN_ERROR
ECHO PHP_PEAR_PHP_BIN is not set correctly.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_PHP_BIN%
GOTO END
:RUN
"%PHP_PEAR_PHP_BIN%" -C -n -d date.timezone=UTC -d output_buffering=1 -d safe_mode=0 -d "include_path='%PHP_PEAR_INSTALL_DIR%'" -d register_argc_argv="On" -d variables_order=EGPCS -f "%PHP_PEAR_INSTALL_DIR%\peclcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9
:END
@ECHO ON
/branches/v1.3-critias/bibliotheque/pear/scripts/peardev.bat
New file
0,0 → 1,115
@ECHO OFF
 
REM ----------------------------------------------------------------------
REM PHP version 5
REM ----------------------------------------------------------------------
REM Copyright (c) 1997-2004 The PHP Group
REM ----------------------------------------------------------------------
REM This source file is subject to version 3.0 of the PHP license,
REM that is bundled with this package in the file LICENSE, and is
REM available at through the world-wide-web at
REM http://www.php.net/license/3_0.txt.
REM If you did not receive a copy of the PHP license and are unable to
REM obtain it through the world-wide-web, please send a note to
REM license@php.net so we can mail you a copy immediately.
REM ----------------------------------------------------------------------
REM Authors: Alexander Merz (alexmerz@php.net)
REM ----------------------------------------------------------------------
REM
REM $Id: peardev.bat,v 1.6 2007-09-03 03:00:17 cellog Exp $
 
REM change this lines to match the paths of your system
REM -------------------
 
 
REM Test to see if this is a raw pear.bat (uninstalled version)
SET TMPTMPTMPTMPT=@includ
SET PMTPMTPMT=%TMPTMPTMPTMPT%e_path@
FOR %%x IN ("@include_path@") DO (if %%x=="%PMTPMTPMT%" GOTO :NOTINSTALLED)
 
REM Check PEAR global ENV, set them if they do not exist
IF "%PHP_PEAR_INSTALL_DIR%"=="" SET "PHP_PEAR_INSTALL_DIR=@include_path@"
IF "%PHP_PEAR_BIN_DIR%"=="" SET "PHP_PEAR_BIN_DIR=@bin_dir@"
IF "%PHP_PEAR_PHP_BIN%"=="" SET "PHP_PEAR_PHP_BIN=@php_bin@"
GOTO :INSTALLED
 
:NOTINSTALLED
ECHO WARNING: This is a raw, uninstalled pear.bat
 
REM Check to see if we can grab the directory of this file (Windows NT+)
IF %~n0 == pear (
FOR %%x IN (cli\php.exe php.exe) DO (if "%%~$PATH:x" NEQ "" (
SET "PHP_PEAR_PHP_BIN=%%~$PATH:x"
echo Using PHP Executable "%PHP_PEAR_PHP_BIN%"
"%PHP_PEAR_PHP_BIN%" -v
GOTO :NEXTTEST
))
GOTO :FAILAUTODETECT
:NEXTTEST
IF "%PHP_PEAR_PHP_BIN%" NEQ "" (
 
REM We can use this PHP to run a temporary php file to get the dirname of pear
 
echo ^<?php $s=getcwd^(^);chdir^($a=dirname^(__FILE__^).'\\'^);if^(stristr^($a,'\\scripts'^)^)$a=dirname^(dirname^($a^)^).'\\';$f=fopen^($s.'\\~a.a','wb'^);echo$s.'\\~a.a';fwrite^($f,$a^);fclose^($f^);chdir^($s^);?^> > ~~getloc.php
"%PHP_PEAR_PHP_BIN%" ~~getloc.php
set /p PHP_PEAR_BIN_DIR=fakeprompt < ~a.a
DEL ~a.a
DEL ~~getloc.php
set "PHP_PEAR_INSTALL_DIR=%PHP_PEAR_BIN_DIR%pear"
 
REM Make sure there is a pearcmd.php at our disposal
 
IF NOT EXIST %PHP_PEAR_INSTALL_DIR%\pearcmd.php (
IF EXIST %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php COPY %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php
IF EXIST pearcmd.php COPY pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php
IF EXIST %~dp0\scripts\pearcmd.php COPY %~dp0\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php
)
)
GOTO :INSTALLED
) ELSE (
REM Windows Me/98 cannot succeed, so allow the batch to fail
)
:FAILAUTODETECT
echo WARNING: failed to auto-detect pear information
:INSTALLED
 
REM Check Folders and files
IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%" GOTO PEAR_INSTALL_ERROR
IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" GOTO PEAR_INSTALL_ERROR2
IF NOT EXIST "%PHP_PEAR_BIN_DIR%" GOTO PEAR_BIN_ERROR
IF NOT EXIST "%PHP_PEAR_PHP_BIN%" GOTO PEAR_PHPBIN_ERROR
REM launch pearcmd
GOTO RUN
:PEAR_INSTALL_ERROR
ECHO PHP_PEAR_INSTALL_DIR is not set correctly.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_INSTALL_DIR%
GOTO END
:PEAR_INSTALL_ERROR2
ECHO PHP_PEAR_INSTALL_DIR is not set correctly.
ECHO pearcmd.php could not be found there.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_INSTALL_DIR%
GOTO END
:PEAR_BIN_ERROR
ECHO PHP_PEAR_BIN_DIR is not set correctly.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_BIN_DIR%
GOTO END
:PEAR_PHPBIN_ERROR
ECHO PHP_PEAR_PHP_BIN is not set correctly.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_PHP_BIN%
GOTO END
:RUN
"%PHP_PEAR_PHP_BIN%" -C -d date.timezone=UTC -d memory_limit="-1" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d auto_append_file="" -d variables_order=EGPCS -d open_basedir="" -d output_buffering=1 -d "include_path='%PHP_PEAR_INSTALL_DIR%'" -f "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9
:END
@ECHO ON
/branches/v1.3-critias/bibliotheque/pear/scripts/pear.bat
New file
0,0 → 1,111
@ECHO OFF
 
REM ----------------------------------------------------------------------
REM PHP version 5
REM ----------------------------------------------------------------------
REM Copyright (c) 1997-2010 The Authors
REM ----------------------------------------------------------------------
REM http://opensource.org/licenses/bsd-license.php New BSD License
REM ----------------------------------------------------------------------
REM Authors: Alexander Merz (alexmerz@php.net)
REM ----------------------------------------------------------------------
REM
REM Last updated 12/29/2004 ($Id$ is not replaced if the file is binary)
 
REM change this lines to match the paths of your system
REM -------------------
 
 
REM Test to see if this is a raw pear.bat (uninstalled version)
SET TMPTMPTMPTMPT=@includ
SET PMTPMTPMT=%TMPTMPTMPTMPT%e_path@
FOR %%x IN ("@include_path@") DO (if %%x=="%PMTPMTPMT%" GOTO :NOTINSTALLED)
 
REM Check PEAR global ENV, set them if they do not exist
IF "%PHP_PEAR_INSTALL_DIR%"=="" SET "PHP_PEAR_INSTALL_DIR=@include_path@"
IF "%PHP_PEAR_BIN_DIR%"=="" SET "PHP_PEAR_BIN_DIR=@bin_dir@"
IF "%PHP_PEAR_PHP_BIN%"=="" SET "PHP_PEAR_PHP_BIN=@php_bin@"
 
GOTO :INSTALLED
 
:NOTINSTALLED
ECHO WARNING: This is a raw, uninstalled pear.bat
 
REM Check to see if we can grab the directory of this file (Windows NT+)
IF %~n0 == pear (
FOR %%x IN (cli\php.exe php.exe) DO (if "%%~$PATH:x" NEQ "" (
SET "PHP_PEAR_PHP_BIN=%%~$PATH:x"
echo Using PHP Executable "%PHP_PEAR_PHP_BIN%"
"%PHP_PEAR_PHP_BIN%" -v
GOTO :NEXTTEST
))
GOTO :FAILAUTODETECT
:NEXTTEST
IF "%PHP_PEAR_PHP_BIN%" NEQ "" (
 
REM We can use this PHP to run a temporary php file to get the dirname of pear
 
echo ^<?php $s=getcwd^(^);chdir^($a=dirname^(__FILE__^).'\\'^);if^(stristr^($a,'\\scripts'^)^)$a=dirname^(dirname^($a^)^).'\\';$f=fopen^($s.'\\~a.a','wb'^);echo$s.'\\~a.a';fwrite^($f,$a^);fclose^($f^);chdir^($s^);?^> > ~~getloc.php
"%PHP_PEAR_PHP_BIN%" ~~getloc.php
set /p PHP_PEAR_BIN_DIR=fakeprompt < ~a.a
DEL ~a.a
DEL ~~getloc.php
set "PHP_PEAR_INSTALL_DIR=%PHP_PEAR_BIN_DIR%pear"
 
REM Make sure there is a pearcmd.php at our disposal
 
IF NOT EXIST %PHP_PEAR_INSTALL_DIR%\pearcmd.php (
IF EXIST %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php COPY %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php
IF EXIST pearcmd.php COPY pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php
IF EXIST %~dp0\scripts\pearcmd.php COPY %~dp0\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php
)
)
GOTO :INSTALLED
) ELSE (
REM Windows Me/98 cannot succeed, so allow the batch to fail
)
:FAILAUTODETECT
echo WARNING: failed to auto-detect pear information
:INSTALLED
 
REM Check Folders and files
IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%" GOTO PEAR_INSTALL_ERROR
IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" GOTO PEAR_INSTALL_ERROR2
IF NOT EXIST "%PHP_PEAR_BIN_DIR%" GOTO PEAR_BIN_ERROR
IF NOT EXIST "%PHP_PEAR_PHP_BIN%" GOTO PEAR_PHPBIN_ERROR
 
REM launch pearcmd
GOTO RUN
:PEAR_INSTALL_ERROR
ECHO PHP_PEAR_INSTALL_DIR is not set correctly.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_INSTALL_DIR%
GOTO END
:PEAR_INSTALL_ERROR2
ECHO PHP_PEAR_INSTALL_DIR is not set correctly.
ECHO pearcmd.php could not be found there.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_INSTALL_DIR%
GOTO END
:PEAR_BIN_ERROR
ECHO PHP_PEAR_BIN_DIR is not set correctly.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_BIN_DIR%
GOTO END
:PEAR_PHPBIN_ERROR
ECHO PHP_PEAR_PHP_BIN is not set correctly.
ECHO Please fix it using your environment variable or modify
ECHO the default value in pear.bat
ECHO The current value is:
ECHO %PHP_PEAR_PHP_BIN%
GOTO END
:RUN
"%PHP_PEAR_PHP_BIN%" -C -d date.timezone=UTC -d output_buffering=1 -d safe_mode=0 -d open_basedir="" -d auto_prepend_file="" -d auto_append_file="" -d variables_order=EGPCS -d register_argc_argv="On" -d "include_path='%PHP_PEAR_INSTALL_DIR%'" -f "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9
:END
@ECHO ON
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/pear/scripts/pecl.sh
New file
0,0 → 1,28
#!/bin/sh
 
# first find which PHP binary to use
if test "x$PHP_PEAR_PHP_BIN" != "x"; then
PHP="$PHP_PEAR_PHP_BIN"
else
if test "@php_bin@" = '@'php_bin'@'; then
PHP=php
else
PHP="@php_bin@"
fi
fi
 
# then look for the right pear include dir
if test "x$PHP_PEAR_INSTALL_DIR" != "x"; then
INCDIR=$PHP_PEAR_INSTALL_DIR
INCARG="-d include_path=$PHP_PEAR_INSTALL_DIR"
else
if test "@php_dir@" = '@'php_dir'@'; then
INCDIR=`dirname $0`
INCARG=""
else
INCDIR="@php_dir@"
INCARG="-d include_path=@php_dir@"
fi
fi
 
exec $PHP -C -n -q $INCARG -d date.timezone=UTC -d output_buffering=1 -d variables_order=EGPCS -d safe_mode=0 -d register_argc_argv="On" $INCDIR/peclcmd.php "$@"
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/pear/scripts/peclcmd.php
New file
0,0 → 1,42
<?php
/**
* PEAR, the PHP Extension and Application Repository
*
* Command line interface
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
*/
 
/**
* @nodep Gtk
*/
//the space is needed for windows include paths with trailing backslash
// http://pear.php.net/bugs/bug.php?id=19482
if ('@include_path@ ' != '@'.'include_path'.'@ ') {
ini_set('include_path', trim('@include_path@ '). PATH_SEPARATOR . get_include_path());
$raw = false;
} else {
// this is a raw, uninstalled pear, either a cvs checkout, or php distro
$raw = true;
}
define('PEAR_RUNTYPE', 'pecl');
require_once 'pearcmd.php';
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: nil
* mode: php
* End:
*/
// vim600:syn=php
 
?>
/branches/v1.3-critias/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();
}
?>
/branches/v1.3-critias/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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/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;
}
}
}
?>
/branches/v1.3-critias/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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/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
/branches/v1.3-critias/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;
}
?>
/branches/v1.3-critias/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);
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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
 
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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;
 
}
 
}
?>
/branches/v1.3-critias/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;
 
}
 
}
?>
/branches/v1.3-critias/bibliotheque/artichow/DEPRECATED
New file
0,0 → 1,3
Artichow 1.0.9
 
- Pie::setBorder(): replaced by Pie::setBorderColor()
/branches/v1.3-critias/bibliotheque/artichow/cache/Albert
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/cache/Albert
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/cache/Example-006-time
New file
0,0 → 1,2
1166203465
png
/branches/v1.3-critias/bibliotheque/artichow/cache/Example-006
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/cache/Example-006
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/cache/Abel-time
New file
0,0 → 1,2
1166203484
png
/branches/v1.3-critias/bibliotheque/artichow/cache/Abel
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/cache/Abel
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/cache/Albert-time
New file
0,0 → 1,2
1166203480
png
/branches/v1.3-critias/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'
);
 
?>
/branches/v1.3-critias/bibliotheque/artichow/images/paperclip.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/images/paperclip.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/images/error.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/images/error.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/images/errors/missing-gd2.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/images/errors/missing-gd2.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/images/errors/missing-anti-aliasing.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/images/errors/missing-anti-aliasing.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/images/star.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/images/star.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/images/book.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/images/book.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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;
}
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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>
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-bd.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-bd.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-bg-long.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/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
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-bg.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-bg.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-hd-transparent.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/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
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-hd.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-hd.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-hg-transparent.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/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
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-hg.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-hg.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/doc/image/fond.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/doc/image/fond.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/doc/image/back-rayures.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/doc/image/back-rayures.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/doc/image/fond-flou.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/doc/image/fond-flou.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-bd.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/doc/image/coin-bd.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/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))
/branches/v1.3-critias/bibliotheque/artichow/font/Tuffy.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/font/Tuffy.ttf
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/font/TuffyBold.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/font/TuffyBold.ttf
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/font/TuffyItalic.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/font/TuffyItalic.ttf
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/bibliotheque/artichow/font/TuffyBoldItalic.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/v1.3-critias/bibliotheque/artichow/font/TuffyBoldItalic.ttf
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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);
?>
/branches/v1.3-critias/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.'%';
}
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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';
 
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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);
}
?>
/branches/v1.3-critias/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);
}
 
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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);
 
 
 
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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');
}
 
?>
/branches/v1.3-critias/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');
}
 
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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');
 
?>
/branches/v1.3-critias/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.'.');
}
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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 :-(";
}
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/bibliotheque/artichow/examples/tutorials/smiley.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/examples/tutorials/smiley.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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);
?>
/branches/v1.3-critias/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>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/bibliotheque/artichow/examples/champignon.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/examples/champignon.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/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();
 
?>
/branches/v1.3-critias/bibliotheque/artichow/examples/test/error.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
/branches/v1.3-critias/bibliotheque/artichow/examples/test/error.png
New file
Property changes:
Added: svn:mime-type
+image/png
\ No newline at end of property
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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();
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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');
?>
/branches/v1.3-critias/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 = GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_projet_categorie '.
'ORDER BY gpc_libelle';
break;
case ProjetCategorie::GPC_ID:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_projet_categorie ';
break;
case ProjetCategorie::GPC_LIBELLE:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/bibliotheque/metier/TravailProjet.class.php
New file
0,0 → 1,205
<?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';
const GTP_UTILISATEUR_SOMME_TEMPS_PAR_PROJET = 'TRAVAILPROJET_ID_UTILISATEUR_SOMME_TEMPS_PAR_PROJET';
/*** 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 = GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_travail_projet ';
break;
case TravailProjet::GTP_ID_MAX_PROJET:
$requete = 'SELECT MAX(gtp_id_projet) '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_travail_projet ';
break;
case TravailProjet::GTP_ID_MAX_DATE_TRAVAIL:
$requete = 'SELECT MAX(gtp_id_date_travail) '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_travail_projet ';
break;
case TravailProjet::GTP_PROJET:
$requete = 'SELECT gtp_id_projet '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_travail_projet '.
'WHERE gtp_id_projet = #0 ';
break;
case TravailProjet::GTP_UTILISATEUR:
$requete = 'SELECT gtp_id_utilisateur '.
'FROM ' . GTT_BDD_PREFIXE . '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);
}
 
/**
* Retourne la somme des heures travaillées pour chaque projet, pour un
* utilisateur donné
*
* @WARNING Fonction plus pratique que d'utiliser le DAO (mais c'est MAL !)
*
* @param int $idUtilisateur l'identifiant de l'utilisateur
*/
public function getTempsTravailUtilisateurParProjet($idUtilisateur) {
 
$requete = 'SELECT gtp_id_utilisateur '.
', gtp_id_projet '.
', sum(gtp_duree) AS temps_total_heures '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_travail_projet '.
'WHERE gtp_id_utilisateur = ' . $idUtilisateur . ' '.
'GROUP BY gtp_id_projet ';
 
$resultat = $GLOBALS['db']->getAll($requete);
 
return $resultat;
}
}
 
/* +--Fin du code ----------------------------------------------------------------------------------------+
*
* $Log$
*
* +-- Fin du code ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/bibliotheque/metier/Calendrier.class.php
New file
0,0 → 1,244
<?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),
// TODO : gérer les jours fériès depuis l'interface d'admin...
// N'est plus un jour férié...
$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;
}
}
}
?>
/branches/v1.3-critias/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 = GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/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 = GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_note_frais '.
'WHERE gnf_id_note_frais = #0 ';
break;
case NoteFrais::GNF_ID_MAX:
$requete = 'SELECT MAX(gnf_id_note_frais) '.
'FROM ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/bibliotheque/metier/Utilisateur.class.php
New file
0,0 → 1,494
<?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 = GTT_BDD_PREFIXE . '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;
}
 
// Tdt Par Numéro du jour
public function getTdtParNumJour($num)
{
$tdt = 0;
if ($num == 1) {
$tdt = $this->getTdtLundi();
} else if ($num == 2) {
$tdt = $this->getTdtMardi();
} else if ($num == 3) {
$tdt = $this->getTdtMercredi();
} else if ($num == 4) {
$tdt = $this->getTdtJeudi();
} else if ($num == 5) {
$tdt = $this->getTdtVendredi();
} else if ($num == 6) {
$tdt = $this->getTdtSamedi();
} else if ($num == 7) {
$tdt = $this->getTdtDimanche();
}
 
return $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 ' . GTT_BDD_PREFIXE . 'gestion_utilisateur '.
'ORDER BY gu_nom, gu_prenom ASC';
break;
case Utilisateur::GU_ID:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_utilisateur '.
'WHERE gu_id_utilisateur = #0 ';
break;
case Utilisateur::GU_ID_MAX:
$requete = 'SELECT MAX(gu_id_utilisateur) AS gu_id_utilisateur '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_utilisateur ';
break;
case Utilisateur::GU_CE_STATUT:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_utilisateur '.
'WHERE gu_ce_statut = "#0" ';
break;
case Utilisateur::GU_MAIL:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_utilisateur '.
'WHERE gu_email = "#0" ';
break;
case Utilisateur::GU_TOUS_AFFICHABLE:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_utilisateur '.
'WHERE gu_mark_recapitulatif = 0 '.
'ORDER BY gu_nom, gu_prenom ASC';
break;
case Utilisateur::GU_ADMIN:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/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 = GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_frais_km '.
'WHERE gfk_id_frais_km = #0 ';
break;
case FraisKm::GFK_ID_MAX:
$requete = 'SELECT MAX(gfk_id_frais_km) '.
'FROM ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/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 = GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/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 = GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_absence_motif ';
break;
case AbsenceMotif::GAM_ID:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_absence_motif ';
break;
case AbsenceMotif::GAM_LIBELLE:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/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 = GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_utilisateur_a_projet ';
break;
case UtilisateurAProjet::GUAP_ID_MAX_PROJET:
$requete = 'SELECT MAX(guap_id_projet) '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_utilisateur_a_projet ';
break;
case UtilisateurAProjet::GUAP_UTILISATEUR:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_utilisateur_a_projet '.
'WHERE guap_id_utilisateur = #0 ';
break;
case UtilisateurAProjet::GUAP_PROJET:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/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 = GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_utilisateur_statut ';
break;
case UtilisateurStatut::GUS_ID:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_utilisateur_statut ';
break;
case UtilisateurStatut::GUS_LIBELLE:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/bibliotheque/metier/aGttSql.class.php
New file
0,0 → 1,283
<?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;
}
}
}
// les indices numériques contiennent des copies des valeurs présentes
// dans les indices [#0], [#1]... => wtf ? si le préfixe de table
// contient un chiffre, celui-ci sera remplacé et tout va péter
// => bricolage cracra, on enlève tous les indices numériques
foreach ($parametres as $k => &$v) {
if (is_numeric($k)) {
unset($parametres[$k]);
}
}
// 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>';
}
}
?>
/branches/v1.3-critias/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 = GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_absence '.
'WHERE ga_id_absence_motif = #0 ';
break;
case Absence::GA_ID_UTILISATEUR:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_absence '.
'WHERE ga_id_utilisateur = #0 ';
break;
case Absence::GA_ID_UTILISATEUR_DATE_DEB_FIN:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_absence ';
break;
case Absence::GA_ID_MAX_ABSENCE_MOTIF:
$requete = 'SELECT MAX(ga_id_absence_motif) '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_absence ';
break;
case Absence::GA_ID_MAX_DATE_ABSENCE:
$requete = 'SELECT MAX(ga_id_date_absence) '.
'FROM ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/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;
}
}
?>
/branches/v1.3-critias/bibliotheque/metier/Projet.class.php
New file
0,0 → 1,271
<?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 = GTT_BDD_PREFIXE . '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;
}
 
/**
* Calcule l'avancement d'un projet en pourcentage, en fonction du nombre
* d'heures déclaré et du nombre d'heures effectuées (tous utilisateurs
* confondus) - @TODO devrait devenir une vue / être requêté au moment de
* charger le projet
*/
public function getAvancementCalcule()
{
$avancementCalcule = null;
 
$requete = "SELECT IFNULL(FLOOR(sum(gtp_duree) / 7), 0) as jours"
. " FROM " . GTT_BDD_PREFIXE . "gestion_travail_projet"
. " WHERE gtp_id_projet = " . $this->id_projet;
 
$resultat = $GLOBALS['db']->query($requete);
(DB::isError($resultat)) ? trigger_error(GestionnaireErreur::retournerErreurSql(__FILE__, __LINE__, $resultat->getMessage(), $requete), E_USER_ERROR) : '' ;
while ($donnees =& $resultat->fetchRow(DB_FETCHMODE_ASSOC)) {
$avancementCalcule = $donnees['jours'];
}
 
return $avancementCalcule;
}
 
/*** 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 ' . GTT_BDD_PREFIXE . 'gestion_projet LEFT JOIN ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . 'gestion_projet '.
'WHERE gp_id_projet = #0 ';
break;
case Projet::GP_NOM:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_projet '.
'WHERE gp_nom = "#0" ';
break;
case Projet::GP_ID_MAX:
$requete = 'SELECT MAX(gp_id_projet) AS gp_id_projet '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_projet ';
break;
case Projet::GP_ID_LIST:
$requete = 'SELECT * '.
'FROM ' . GTT_BDD_PREFIXE . 'gestion_projet LEFT JOIN ' . GTT_BDD_PREFIXE . '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 ' . GTT_BDD_PREFIXE . '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 ----------------------------------------------------------------------------------------+
*/
?>
/branches/v1.3-critias/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
/branches/v1.3-critias/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 />4, rue de Belfort\n<br />34000 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
/branches/v1.3-critias/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);
}
}
?>
/branches/v1.3-critias/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__');
}
}
?>
/branches/v1.3-critias/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__');
}
}
?>
/branches/v1.3-critias/actions/GttCtrlActionPreferences.class.php
New file
0,0 → 1,100
<?php
class GttCtrlActionPreferences extends aControlleurAction {
 
public function __construct(Registre $Registre)
{
$Registre->ajouterEspace('Preferences', 'preferences');
}
 
public function executer()
{
// Liste des projets
$aso_preferences = array();
$this->getRegistre()->setTitre('Modifier mes préférences');
$Projet = new Projet();
$tab_projets = $Projet->consulter(Projet::GP_TOUS);
 
// Temps de travail perso sur chaque projet
$aso_temps_perso = array();
$TravailProjet = new TravailProjet();
$utilisateurEnCours = $GLOBALS['_GTT_']['Utilisateur'];
$tab_temps_perso = $TravailProjet->getTempsTravailUtilisateurParProjet($utilisateurEnCours->getIdUtilisateur());
//echo '<pre>'.print_r($tab_temps_perso, true).'</pre>';
 
if (false == $tab_temps_perso) {
$aso_preferences['messages'][] = "Impossible de lire le temps de travail personnel";
} else {
// Parcours du tableau de temps de travail perso par projet
foreach ($tab_temps_perso as $tp) {
$aso_temps_perso[$tp[1]] = array(
'temps_heures' => $tp[2],
'temps_jours' => floor(($tp[2] / 7))
);
}
}
//echo '<pre>'.print_r($aso_temps_perso, true).'</pre>';
 
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);
// Parcours 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;
$present = $UtilisateurAProjet->consulter($cmd, $param);
if ($present) {
$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(),
'tpp' => $aso_temps_perso[$Projet->getIdProjet()]['temps_jours'], // temps perso. passé
'av' => $Projet->getAvancement(),
'avc' => $Projet->getAvancementCalcule(), // trop de la boulette !
'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__');
}
}
?>
/branches/v1.3-critias/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__');
}
}
?>
/branches/v1.3-critias/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);
}
}
?>
/branches/v1.3-critias/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);
}
}
?>
/branches/v1.3-critias/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__');
}
}
?>
/branches/v1.3-critias/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__');
}
}
?>
/branches/v1.3-critias/actions/GttCtrlActionGestion.class.php
New file
0,0 → 1,472
<?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] = '';
$aso_abscence_initial[$num] = array(
'duree' => '',
'duree_defaut' => $GLOBALS['_GTT_']['Utilisateur']->getTdtParNumJour($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_abscence_initial;
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]['duree'] = $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)) {
// Si un temps de travail est mis à 0, on le supprime.
// Les heures sup sont réinitialisés ci-dessous.
$TP->supprimer();
} 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);
//echo '<pre>'.print_r($tab_a, true).'</pre>';
// Ajout ou Mise à jour des durées d'absences pour congés payés
$cp_h_modif = 0;
$hs_h_modif = 0;
$abscences_a_supprimer = $tab_a;
//echo '<pre>'.print_r($_POST['ab'], true).'</pre>';
if (isset($_POST['ab'])) {
//echo '<pre>'.print_r($_POST['ab'], true).'</pre>';
foreach($_POST['ab'] as $num_j => $tab_ab_id_duree) {
if (isset($tab_ab_id_duree)) {
list($ab_id, $ab_duree) = explode(':', $tab_ab_id_duree);
 
// 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);
 
// 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 $id => $A) {
if ($A->getIdDateAbsence() == $aso_semaine[$num_j]['mysql']) {
if ($A->getIdAbsenceMotif() == $ab_id) {
unset($abscences_a_supprimer[$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));
}
}
}
}
}
}
}
// Ajout de nouvelle abscences
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);
}
}
}
}
}
// Suppression des abscences décochées
//echo '<pre>'.print_r($abscences_a_supprimer, true).'</pre>';
if (count($abscences_a_supprimer) > 0) {
foreach ($abscences_a_supprimer as $A) {
$num_jour_ab = $aso_jours[$A->getIdDateAbsence()];
$AbsenceMotif = new AbsenceMotif();
$AbsenceMotif->consulter(AbsenceMotif::GAM_ID, $A->getIdAbsenceMotif(), true);
if ($AbsenceMotif->getMarkHsDiminuer()) {
$jours_w_semaine[$num_jour_ab]['pre_a'] = $A->getDuree();
$jours_w_semaine[$num_jour_ab]['act_a'] = 0;
$jours_w_semaine[$num_jour_ab]['mod'] = true;
}
$A->supprimer();
}
}
 
// Gestion de la mise à jour des heures sup
//echo '<pre>'.print_r($jours_w_semaine, true).'</pre>';
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)) {
if ($j['mod'] == false) {// Première fois que l'on modifie le jour
if ($j['act_a'] == 0 && $j['act'] != 0) {// Journée de travail
$heure_sup_act = $j['act'] - $j['tdt'];
if ($heure_sup_act > 0) {
$Utilisateur->augmenterQuotaHeuresSup($heure_sup_act);
}
if ($heure_sup_act < 0) {
$Utilisateur->diminuerQuotaHeuresSup($heure_sup_act);
}
} else {// Journée d'abscence
$Utilisateur->diminuerQuotaHeuresSup($j['act_a']);
}
} else {// Les heures sup ont déjà été comptabilisées, réinitialisation nécessaire
// Nous restaurons les heures sup précédement ajoutées ou décomptées
if ($j['pre_a'] == 0 && $j['pre'] != 0) {// Journée de travail
$heure_sup_pre = $j['pre'] - $j['tdt'];
if ($heure_sup_pre > 0) {
$Utilisateur->diminuerQuotaHeuresSup($heure_sup_pre);
} else if ($heure_sup_pre < 0) {
$Utilisateur->augmenterQuotaHeuresSup($heure_sup_pre);
}
} else {// Journée d'abscence
$Utilisateur->augmenterQuotaHeuresSup($j['pre_a']);
}
// Nous ajoutons ou décomptons les heures sup actuelles
if ($j['act_a'] == 0 && $j['act'] != 0) {// Journée de travail
$heure_sup_act = $j['act'] - $j['tdt'];
if ($heure_sup_act > 0) {
$Utilisateur->augmenterQuotaHeuresSup($heure_sup_act);
}
if ($heure_sup_act < 0) {
$Utilisateur->diminuerQuotaHeuresSup($heure_sup_act);
}
} else {// Journée d'abscence
$Utilisateur->diminuerQuotaHeuresSup($j['act_a']);
}
}
}
}
$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__');
}
}
?>
/branches/v1.3-critias/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' => GTT_BDD_PREFIXE.'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);
}
}
?>
/branches/v1.3-critias/gtt_config.inc.php
New file
0,0 → 1,75
<?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 - le nom du cookie est défini dans config.inc.php
$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
/branches/v1.3-critias/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.
/branches/v1.3-critias/CHANGELOG
New file
0,0 → 1,29
Changements 2016-12-28 [création de la branche "v1.3-critias"]:
* compatibilité PHP 7 (mise à jour de PEAR et PEAR DB)
* décompte du temps personnel par projet, dans la page "préférences"
* suppression de messages inutiles
* réduction du seuil d'alerte de dépassement de 15 à 5 %
 
Changements 2015-12-28 [création de la branche "v1.2-democrite"]:
* restauration du lundi de Pentecôte (nique Raffarin !)
* Utilisation d'un préfixe de tables
* Correction URL formulaire : absolue => relative
* Suppression des tags courts dans les templates (foreach) pour plus de compatibilité
* Inclusion de DROP TABLEs dans gtt_installation.sql
* Modif script SQL d'install : mdp explicite pour l'utilisateur par défaut
* Le nom du cookie d'authentification est maintenant géré dans config.php
* Visualisation de l'avancement global dans "gestion de mes projets", avec décompte des jours prévus et travaillés, du pourcentage effectué, et alertes en cas de dépassement
* Script d'installation et de clonage
 
Changements 2013-03-27 [création de la branche "v1.1-thales"]:
* Passage au doctype HTML5
* Gestion des absences par journée entière (case à cocher)
* Correction du bogue provoquant une mauvais comptabilisation des heures supplémentaires
* Suppression de l'affichage des congés payés
* Suppression des absences et des temps de travail si le nombre d'heure est mis à zéro (avant la donnée était malgré tout gardée)
* Le lundi de pentecôte n'est plus considéré comme férié
 
Changements 2008-09-19 [création de la branche "v1.0-homere"]:
* Création de l'application avec ses fonctionnalités initiales...
 
Premier commit : 2006-05
/branches/v1.3-critias/scripts/config.defaut.sh
New file
0,0 → 1,13
# configuration de clonegtt
 
# base dans laquelle seront creees les instances de GTT
BDD_HOTE="localhost"
BDD_BASE=""
BDD_LOGIN=""
BDD_MDP=""
 
# chemin des executables MySQL (dossier "bin")
CHEMIN_MYSQL="/usr/bin"
 
# prefixe des tables depuis lesquelles copier les donnees (ex: "gtt_2016_")
BDD_SOURCE_PREFIXE=""
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v1.3-critias/scripts/clonegtt.sh
New file
0,0 → 1,105
#!/bin/bash
 
# Crée une instance de GTT pour l'année à venir.
#
# Nécessite de remplir config.sh à partir de config.defaut.sh.
# Si un fichier "htaccess" est présent, il sera renommé en ".htaccess" dans le
# dossier de destination de la nouvelle instance
#
# Utilisation :
# ./clonegtt.sh 2016 trunk clonebdd
#
# Mathias - 2015-12-23
 
# ligne magique trouvee sur http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 
SCRIPTNAME=`basename "$0"`
 
# date du jour
DATE=`date +%Y-%m-%d`
 
# chargement de la config
. "$SCRIPTDIR/config.sh"
 
function notice {
echo "Utilisation: $SCRIPTNAME annee branche [clonebdd]"
echo " annee: cree une instance de GTT pour l'annee fournie (ex: 2016), dans un nouveau dossier correspondant"
echo " branche: utilise une branche particuliere du SVN (ex: trunk, branches/v1.2-democrite)"
echo " clonebdd (optionnel): si mentionne, copiera les donnees (utilisateurs, projets, categories) de l'installation, dont le prefixe est specifie dans config.sh"
echo "Exemples:"
echo " $SCRIPTNAME 2016 trunk clonebdd"
echo " $SCRIPTNAME 2016 branches/v1.2-democrite"
}
 
function copie_table {
REQ="TRUNCATE ${PREFIXE}$1; INSERT INTO ${PREFIXE}$1 SELECT * FROM ${BDD_SOURCEPREFIXE}$1;"
#echo "$REQ"
CMD="$CHEMIN_MYSQL/mysql -h$BDD_HOTE -u$BDD_LOGIN -p$BDD_MDP -e \"$REQ\" $BDD_BASE"
eval "$CMD"
}
 
function clone_gtt {
ANNEE="$1"
PREFIXE="gtt_${ANNEE}_"
 
echo "deploiement d'une instance de GTT pour l'ANNEE [$ANNEE]"
 
# copie du code
dossier_svn="trunk"
if [ "$#" -gt 1 ]; then
echo "recuperation de la branche [$2]";
dossier_svn="$2"
else
echo "recuperation du [trunk]"
fi
svn co "http://svn.tela-botanica.net/svn/applications/gtt/$dossier_svn" "$ANNEE"
 
# copie du .htaccess
if [ -e "$SCRIPTDIR/htaccess" ]; then
echo "copie du .htaccess de reference"
cp "$SCRIPTDIR/htaccess" "$ANNEE/.htaccess"
fi
 
# creation de la config
echo "creation de la config"
echo "<?php
// cree par clonegtt le $DATE
define('GTT_AUTH_SESSION_NOM', 'gtt_auth_$PREFIXE');
define('GTT_BDD_NOM', '$BDD_BASE');
define('GTT_BDD_DSN', 'mysqli://$BDD_LOGIN:$BDD_MDP@$BDD_HOTE/'.GTT_BDD_NOM);
define('GTT_BDD_PREFIXE', '$PREFIXE');
define('GTT_DEBOGAGE', false);
define('GTT_DEBOGAGE_SQL', false);
?>" > "$ANNEE/config.inc.php"
 
# modification des fichiers .sql pour ajouter le prefixe, et insertion dans la base
# "sort" sert a s'assurer que "installation" est execute avant "maj" @WARNING bancal comme systeme !
find "$ANNEE/documentation" -name "*.sql" | sort | while read line; do
echo "Insertion de $line"
sed "s/gestion_/${PREFIXE}gestion_/" "$line" > "${line}_${ANNEE}.sql"
CMD="$CHEMIN_MYSQL/mysql -h$BDD_HOTE -u$BDD_LOGIN -p$BDD_MDP $BDD_BASE < ${line}_${ANNEE}.sql"
eval $CMD
rm "${line}_${ANNEE}.sql"
done
 
# copie de l'ancienne base vers la nouvelle (configurer)
if [ "$#" -gt 2 ]; then
if [ "$3" = "clonebdd" ]; then
echo "clonage de la base precedente (prefixe [$BDD_SOURCE_PREFIXE])"
# copies SQL des tables a recuperer
copie_table "gestion_absence_motif"
copie_table "gestion_projet"
copie_table "gestion_projet_categorie"
copie_table "gestion_utilisateur"
# copie_table "gestion_utilisateur_a_projet"
copie_table "gestion_utilisateur_statut"
fi
fi
}
 
if [ "$#" -lt 1 ]; then
notice
else
clone_gtt $@
fi
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v1.3-critias/scripts/htaccess.exemple
New file
0,0 → 1,3
# exemple de .htaccess pour Tela Botanica / Sequoia (2015)
AddHandler x-httpd-php5 .php
AddDefaultCharset UTF-8
/branches/v1.3-critias/scripts/installgtt.sh
New file
0,0 → 1,71
#!/bin/bash
 
# Installe GTT à partir du code en cours.
#
# Nécessite de remplir config.sh à partir de config.defaut.sh.
# Si un fichier "htaccess" est présent, il sera renommé en ".htaccess" dans le
# dossier de destination de la nouvelle instance
#
# Utilisation :
# ./installgtt.sh [prefixe]
#
# Mathias - 2015-12-28
 
# ligne magique trouvee sur http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 
SCRIPTNAME=`basename "$0"`
 
# date du jour
DATE=`date +%Y-%m-%d`
 
# chargement de la config
. "$SCRIPTDIR/config.sh"
 
function notice {
echo "Utilisation: $SCRIPTNAME [prefixe]"
echo " prefixe (optionnel): prefixe les tables de GTT dans la base de donnees"
echo "Exemples:"
echo " $SCRIPTNAME"
echo " $SCRIPTNAME gtt_2016_"
}
 
function install_gtt {
PREFIXE="$1"
 
echo "installation de GTT - prefixe: [$PREFIXE]"
 
# copie du .htaccess
if [ -e "$SCRIPTDIR/htaccess" ]; then
echo "copie du .htaccess de reference"
cp "$SCRIPTDIR/htaccess" "../.htaccess"
fi
 
# creation de la config
echo "creation de la config"
echo "<?php
// cree par installgtt le $DATE
define('GTT_AUTH_SESSION_NOM', 'gtt_auth_$PREFIXE');
define('GTT_BDD_NOM', '$BDD_BASE');
define('GTT_BDD_DSN', 'mysqli://$BDD_LOGIN:$BDD_MDP@$BDD_HOTE/'.GTT_BDD_NOM);
define('GTT_BDD_PREFIXE', '$PREFIXE');
define('GTT_DEBOGAGE', false);
define('GTT_DEBOGAGE_SQL', false);
?>" > "../config.inc.php"
 
# modification des fichiers .sql pour ajouter le prefixe, et insertion dans la base
# "sort" sert a s'assurer que "installation" est execute avant "maj" @WARNING bancal comme systeme !
find "../documentation" -name "*.sql" | sort | while read line; do
echo "Insertion de $line"
sed "s/gestion_/${PREFIXE}gestion_/" "$line" > "${line}_${PREFIXE}.sql"
CMD="$CHEMIN_MYSQL/mysql -h$BDD_HOTE -u$BDD_LOGIN -p$BDD_MDP $BDD_BASE < ${line}_${PREFIXE}.sql"
eval $CMD
rm "${line}_${PREFIXE}.sql"
done
}
 
if [ "$1" = "help" ]; then
notice
else
install_gtt $@
fi
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/v1.3-critias/scripts
New file
Property changes:
Added: svn:ignore
+config.sh
/branches/v1.3-critias/AUTEURS
New file
0,0 → 1,4
Mathias Chouet >mathias@tela-botanica.org> pour la suite
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.
/branches/v1.3-critias/documentation/gtt_installation.sql
New file
0,0 → 1,197
-- 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`
--
 
DROP TABLE IF EXISTS `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`
--
 
DROP TABLE IF EXISTS `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`
--
 
DROP TABLE IF EXISTS `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`
--
 
DROP TABLE IF EXISTS `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`
--
 
DROP TABLE IF EXISTS `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`
--
 
DROP TABLE IF EXISTS `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', MD5('demo'), 'demo', '', '', '', '', 0, 0, 7, 0, 1, 0, NULL);
 
-- --------------------------------------------------------
 
--
-- Structure de la table `gestion_utilisateur_a_projet`
--
 
DROP TABLE IF EXISTS `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`
--
DROP TABLE IF EXISTS `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);
/branches/v1.3-critias/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` ;
/branches/v1.3-critias/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>
/branches/v1.3-critias/config.inc.defaut.php
New file
0,0 → 1,13
<?php
// Session : nom du cookie
define('GTT_AUTH_SESSION_NOM', 'gtt_auth_v4');
// Base de données
define('GTT_BDD_NOM', 'gtt_v4');
define('GTT_BDD_DSN', 'mysqli://utilsiateur:mot_de_passe@localhost/'.GTT_BDD_NOM);
define('GTT_BDD_PREFIXE', '');
// 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);
?>
/branches/v1.3-critias
New file
Property changes:
Added: svn:ignore
+.buildpath
+.projectOptions
+.externalToolBuilders
+.project
+.cache
+nbproject
+config.inc.php
+.settings
Added: svn:mergeinfo
Merged /branches/v1.2-democrite:r184