/branches/v1.6-croc/jrest/jrest.ini.php.defaut |
---|
New file |
0,0 → 1,114 |
;<?/* |
[settings] |
; URL de base relative du CEL |
baseURL = "/jrest/" |
; URL de base relative alternative du CEL (pour les raccourcis par exemple) |
baseAlternativeURL = "/service:cel:" |
; URL de base aboslu du CEL |
baseURLAbsolu = "http://localhost/jrest/" |
; URL de base aboslu du CEL construit dynamiquement dans le fichier Cel.php |
baseURLAbsoluDyn = "" |
; Url d'eFlore affichant la carte du CEL |
efloreUrlTpl = "http://www.tela-botanica.org/bdtfx-nn-%s" |
; URL des services web du CEL sous forme de template à utiliser avec sprintf |
baseURLServicesAnnuaireTpl = "http://www.tela-botanica.org/service:annuaire:%s" |
; URL des services web du CEL sous forme de template à utiliser avec sprintf |
baseURLServicesCelTpl = "http://www.tela-botanica.org/service:cel:%s" |
; Squelette d'Url permettant d'afficher une image du CEL (remplace %s par l'id de l'image sans underscore) |
celImgUrlTpl = "http://www.tela-botanica.org/appli:cel-img:%s.jpg" |
; Url de PhpMyEdit permettant de faire les corrections du CEL pour les Super Admin |
phpEditUrlTpl = "http://www.tela-botanica.org/eflore/cel2/jrest/util/cel_inventory.php?PME_sys_fl=0&PME_sys_fm=0&PME_sys_sfn[0]=0&PME_sys_operation=PME_op_Change&PME_sys_rec=%s" |
; Indication du nom de l'éditeur pour les flux de syndication |
editeur = "Tela Botanica" |
; Format du Guid des observations du CEL pour les flux de syndication principalement |
guidObsTpl = "urn:lsid:tela-botanica.org:cel:obs%s" |
; Format du Guid des images du CEL pour les flux de syndication principalement |
guidImgTpl = "urn:lsid:tela-botanica.org:cel:img%s" |
; Indication de la locale (setLocale(LC_ALL, ?)) pour les classes héritant de Cel |
locale = "fr_FR.UTF-8" |
; Indication du fuseau horraire par défaut date_default_timezone_set(?)pour les classes héritant de Cel |
fuseauHoraire = "Europe/Paris" |
; template de chemin pour les marqueur google maps pour le widget carto |
cheminCelMarkerObsTpl = "/home/telabotap/www/commun/icones/carto/groupe/g%s.png" |
; URL des services web du CEL sous forme de template à utiliser avec sprintf |
baseURLServicesCelTpl = "http://localhost/service:cel:%s" |
; Squelette d'Url permettant d'afficher une image du CEL (remplace %s par l'id de l'image sans underscore) |
celImgUrlTpl = "http://www.tela-botanica.org/appli:cel-img:%s.jpg" |
; URL des services web du CEL sous forme de template à utiliser avec sprintf |
baseURLServicesAnnuaireTpl = "http://www.tela-botanica.org/service:annuaire:%s" |
; Default |
[eflore] |
phptype = mysqli |
username = |
password = |
hostspec = |
database = tela_prod_eflore_v1_1_principale |
url_service_nom = "http://localhost/service:eflore:0.1/bdtfx/noms" |
url_service_taxon = "http://localhost/service:eflore:0.1/bdtfx/taxons" |
url_service_chorologie_obs = "http://localhost/service:eflore:0.1/chorodep/observations" |
url_service_chorologie_carte = "http://localhost/service:eflore:0.1/chorodep/cartes" |
url_service_photoflora = "http://photoflora.free.fr/eflore-photoflora/services/index.php/0.1/projets/photoflora/images" |
; Images |
[cel] |
chemin_images = /opt/lampp/htdocs/Documents/images_serveur |
chemin_export = /opt/lampp/htdocs/Documents/export_images |
chemin_stockage_temp = /home/tmp |
url_images = http://localhost/Documents/images_serveur |
url_export = http://localhost/Documents/export_images |
url_service_geo_local = http://www.tela-botanica.org/service:eflore:0.1/osm/nom-commune |
url_service_geo_geonames = http://ws.geonames.org/ |
nom_service_geocoding_geonames = postalCodeSearchJSON |
nom_service_reverse_geocoding_geonames = findNearbyJSON |
taille_max = 2097152 |
taille_max_archive = 8500000 |
format_XS = 150_100 |
format_S = 400_300 |
format_CRS = 300_300 |
format_M = 600_450 |
format_L = 800_600 |
format_XL = 1024_768 |
format_X2L = 1280_960 |
format_X3L = 1600_1200 |
format_CRX2S = 63_63 |
format_CS = 300_300 |
format_CXS = 100_100 |
format_CRXS = 100_100 |
; Stockage |
[database_cel] |
phptype = mysqli |
username = |
password = |
hostspec = localhost |
database = tb_cel |
database_migration = tb_cel_migration |
; Identification |
[database_ident] |
phptype = mysql |
username = |
password = |
hostspec = localhost |
database = tela_prod |
annuaire = annuaire_tela |
ann_id = U_MAIL |
ann_pwd = U_PASSWD |
pass_crypt_funct = md5 |
; LOGS |
[log] |
cheminlog = "/home/Logs/" |
timezone = "Europe/Paris" |
taillemax = 100000 |
; ADMIN |
[jrest_admin] |
admin = aurelien@tela-botanica.org,david.delon@clapas.net,jpm@tela-botanica.org,marie@tela-botanica.org |
;*/?> |
/branches/v1.6-croc/jrest/services/ImageContribution.php |
---|
New file |
0,0 → 1,134 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* Classe renvoyant une liste très succinte des observations liées à une image de l'utilisateur |
* |
*/ |
class ImageContribution extends Cel { |
/** |
* Renvoi un petit bout de html contenant les dernières obs liées à |
* une image d'un utilisateur |
* |
* @param string $uid[0] mail de l'utilisateur |
* @param string $uid[1] identifiant numérique de l'utilisateur |
*/ |
function getElement($uid){ |
$requete_obs_liee_images = 'SELECT * FROM cel_obs'. |
' WHERE ce_utilisateur = '.$this->proteger($uid[1]). |
' AND id_observation IN (SELECT id_observation |
FROM cel_obs_images |
WHERE id_utilisateur = '.$this->proteger($uid[1]).' )'. |
' AND transmission = 0'. |
' ORDER BY date_modification DESC LIMIT 0,5'; |
$html = '<div id="resume_cel">'; |
$obs_liees_images = array(); |
$resultat_obs_liees_images = $this->requeter($requete_obs_liee_images); |
if(is_array($resultat_obs_liees_images)) { |
$obs_liees_images = $resultat_obs_liees_images; |
} |
foreach ($obs_liees_images as $obs) { |
$chemin_sur_serveur = $this->config['cel']['url_images']; |
$requete_img_liees = 'SELECT * FROM cel_images WHERE id_image '. |
'IN (SELECT id_image FROM cel_obs_images '. |
'WHERE id_observation = "'.$obs['id_observation'].'") '. |
'AND ce_utilisateur = "'.$obs['ce_utilisateur'].'"' ; |
$resultat_requete_img_liees = $this->requeter($requete_img_liees); |
if (is_array($resultat_requete_img_liees) && count($resultat_requete_img_liees) > 0) { |
$premiere_image_liee = $resultat_requete_img_liees[0]; |
$premiere_image_liee['nom_original'] = htmlspecialchars($premiere_image_liee['nom_original']); |
$premiere_image_liee['id_image'] = htmlspecialchars($premiere_image_liee['id_image']); |
$id = $premiere_image_liee['id_image']; |
$tailleXY = $this->calculerDimensions(array($premiere_image_liee['largeur'], $premiere_image_liee['hauteur'])); |
$id = sprintf('%09s', $id) ; |
$id = wordwrap($id, 3 , '_', true) ; |
$id_fichier = $id.".jpg" ; |
$niveauDossier = explode("_", $id) ; |
$dossierNiveau1 = $niveauDossier[0] ; |
$dossierNiveau2 = $niveauDossier[1] ; |
$chemin_sur_serveur_final = $chemin_sur_serveur.'/'.$dossierNiveau1.'/'.$dossierNiveau2 ; |
$chemin_fichier = $chemin_sur_serveur_final.'/L/'.$id."_L.jpg" ; |
$chemin_fichier_s = $chemin_sur_serveur_final.'/M/'.$id."_M.jpg" ; |
$html .= '<div class="item_resume_cel">'; |
$html .= '<h4><a href="'.$chemin_fichier.'">'.$obs['nom_ret'].'</a></h4>'. |
'<img src="'.$chemin_fichier_s.'" alt="'.$premiere_image_liee['nom_original'].'" height="'.$tailleXY[1].'px" width="'.$tailleXY[0].'px"></img><br/>'; |
$html .= '<span>Datée du '.$obs['date_modification'].'<br/>' ; |
$html .= 'Lieu : '.trim($obs['zone_geo'],'000null').' ('.trim($obs['ce_zone_geo'],'000null').') '.trim($obs['station'],'000null').' '.trim($obs['lieudit'],'000null').'<br/></p>' ; |
$html .= '</span>'; |
$html .= '</div>'; |
} |
} |
$html.= '</div>'; |
header("Content-Type: text/html; charset=UTF-8"); |
print $html; |
exit; |
} |
private function calculerDimensions($tailleXY) { |
$tailleOr = 75 ; |
if($tailleXY[1] == 0) { |
$tailleXY[1] = $tailleOr; |
} |
if($tailleXY[0] == 0) { |
$tailleXY[0] = $tailleOr; |
} |
$maxTaille = max($tailleXY[1],$tailleXY[0]) ; |
if($maxTaille == $tailleXY[1]) { |
$rapport = $tailleXY[1]/$tailleXY[0] ; |
$tailleXY[1] = 75 ; |
$tailleXY[0] = round($tailleXY[1]/$rapport,0) ; |
}else { |
$rapport = $tailleXY[0]/$tailleXY[1] ; |
$tailleXY[0] = 75 ; |
$tailleXY[1] = round($tailleXY[0]/$rapport,0) ; |
} |
return $tailleXY ; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryLocationList.php |
---|
New file |
0,0 → 1,55 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* @author David Delon <david@tela-botanica.org> |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2010, David Delon, Aurélien Peronnet |
*/ |
/** |
* InventoryLocationList.php |
* |
* in : utf8 |
* out : utf8 |
* Cas d'utilisation : |
* Service listage des zones géographiques d'un utilisateur |
*/ |
class InventoryLocationList extends Cel { |
function getElement($uid){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
$retour = array(); |
$requete_zones_geo = 'SELECT DISTINCT ce_zone_geo, zone_geo, lieudit, station FROM cel_obs '. |
'WHERE ce_utilisateur = '.$this->proteger($uid[0]).' '. |
'ORDER BY ce_zone_geo ASC, zone_geo ASC, lieudit ASC, station ASC'; |
$resultat_zones_geo = $this->requeter($requete_zones_geo); |
if (is_array($resultat_zones_geo)) { |
$retour = $resultat_zones_geo; |
} |
$this->envoyerJson($retour); |
return true; |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.6 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.5 2007-05-22 12:54:09 ddelon |
* Securisation acces utilisateur |
* |
* |
* |
*/ |
?> |
/branches/v1.6-croc/jrest/services/InventoryObservationCount.php |
---|
New file |
0,0 → 1,51 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david.delon@clapas.net> |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* InventoryObservationCount.php |
* |
* in : utf8 |
* out : utf8 |
* |
* Cas d'utilisation : |
* Service recherche du nombre a partir de divers critères |
* |
* 2: Le service recherche le nombre d'images correspondant au critères demandé |
* 3: Le service renvoie le nombre calcule |
*/ |
class InventoryObservationCount extends Cel { |
/** |
* renvoie le nombre d' observations correspondant aux criteres |
* uid[0] : utilisateur obligatoire |
* uid[1] : criteres de filtrage de la forme critere1=valeur1&critere2=valeur2 |
* |
*/ |
function getElement($uid) |
{ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
$chercheur_observations = new RechercheObservation($this->config); |
$criteres = $_GET; |
$retour = $chercheur_observations->compterObservations($uid[0], $criteres); |
$this->envoyerJson($retour); |
return true; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/SelfRefList.php |
---|
New file |
0,0 → 1,80 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
// in utf8 |
// out utf8 |
// Fournit un référentiel relatif à l'utilisateur sur l'un des champs demandes |
class SelfRefList extends Cel { |
private $referentiels = array('station', 'lieudit', 'milieu'); |
/** |
* Suivant le type de référentiel donné en paramètre, renvoie les liste de ses éléments |
* |
* uid[0] : utilisateur obligatoire |
* uid[1] : referentiel demandé (obligatoire) |
* $_GET["start"] et $GET_["limit"] : selection intervalle |
* $_GET["recherche"] : cherche les noms qui commmencent selon la valeur |
* |
*/ |
function getElement($uid){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if (!$this->paramObligatoiresSontPresents($uid)) { |
return; |
} |
if($_GET['recherche'] == '*') { |
$_GET['recherche'] = '%'; |
} |
$referentiel_demande = $uid[1]; |
$value=array(); |
$requete_referentiel = "SELECT DISTINCT ".$referentiel_demande." " . |
"FROM cel_obs WHERE ce_utilisateur = '".$uid[0]."' "; |
if($this->filtreRechercheEstDemande()) { |
$requete_referentiel .= " AND ".$referentiel_demande." LIKE '".$_GET["recherche"]."%'"; |
} |
if ($this->limiteEstDemandee()) { |
$requete_referentiel .= " ORDER BY '.$referentiel_demande.' LIMIT ".$_GET["start"].",".$_GET["limit"]; |
} |
$referentiel_resultat = $this->executerRequete($requete_referentiel); |
$referentiel = array(); |
foreach($referentiel_resultat as $cle => $valeur) { |
if($this->estUneValeurValide($valeur[$referentiel_demande])) { |
$referentiel[] = $valeur[$referentiel_demande]; |
} |
} |
$this->envoyerJson($referentiel); |
return true; |
} |
function paramObligatoiresSontPresents($uid) { |
return (isset($uid[1]) && in_array($uid[1],$this->referentiels) && (isset($uid[0]) && $uid[0] != "")); |
} |
function filtreRechercheEstDemande() { |
return (isset($_GET["recherche"]) && trim($_GET["recherche"]) != ""); |
} |
function limiteEstDemandee() { |
return isset($_GET["start"]) && is_numeric($_GET["start"]) && isset($_GET["limit"]) && is_numeric($_GET["limit"]); |
} |
function estUneValeurValide($chaine) { |
return ($chaine != null && $chaine != "000null" && trim($chaine) != ""); |
} |
} |
?> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v1.6-croc/jrest/services/NameImage.php |
---|
New file |
0,0 → 1,85 |
<?php |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david.delon@clapas.net> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* NameImage.php |
* |
* in : utf8 |
* out : 8859 |
* |
* Cas d'utilisation : |
* Service recherche d'image a partir d'un numero nomenclatural |
* |
* 1: Le service recoit un numero nomenclatural |
* 2: Le service calcul le numero taxonomique associe |
* 3: Le service recherche une image disponible pour ce numero taxonomique |
* 4: Le service redimensionne l'image et la renvoie |
*/ |
class NameImage extends Cel { |
function getElement($uid){ |
$image = array("",""); |
if(isset($uid[0]) && isset($uid[1])) { |
$uid[0] = $uid[0] != '' ? $uid[0] : 'bdtfx'; |
$image = $this->obtenirIllustration($uid[0], $uid[1]); |
} |
$this->envoyerJson($image); |
return true; |
} |
function obtenirIllustration($referentiel_taxo, $nn) { |
// TODO: gérer ici les images d'autres référentiels si celles si sont disponibles |
$retour = array("",""); |
switch($referentiel_taxo) { |
case 'bdtfx': |
$retour = $this->effectuerRequetePhotoFlora($nn); |
break; |
default: |
break; |
} |
return $retour; |
} |
private function effectuerRequetePhotoFlora($nn) { |
$url_photoflora = $this->config['eflore']['url_service_photoflora']; |
$url = $url_photoflora.'?masque.nn='.$nn.'&navigation.limite=1'; |
$resultat = @file_get_contents($url); |
$resultat = json_decode($resultat); |
if(is_object($resultat) && isset($resultat->resultats)) { |
$element = (array)$resultat->resultats; |
$element = array_pop($element); |
if(is_object($element)) { |
$image = array($element->{'binaire.href'}, $element->{'binaire.hrefmax'}); |
} else { |
$image = array('',''); |
} |
} |
return $image; |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.4 2008-11-13 11:29:12 ddelon |
* Reecriture gwt-ext |
* |
* Revision 1.2 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.1 2007-06-06 13:31:16 ddelon |
* v0.09 |
* |
*/ |
?> |
/branches/v1.6-croc/jrest/services/InventoryDateList.php |
---|
New file |
0,0 → 1,89 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurelien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* Liste les date de releves par utilisateur |
* |
* in=utf8 |
* out=utf8 |
* |
**/ |
class InventoryDateList extends Cel { |
private $correspondance_fonction = array(1 => 'year', 2 => 'month', 3 => 'day'); |
/** |
* @param int uid[0] : utilisateur obligatoire |
* @param int uid[1] : si absent : valeur 'all' (annee) |
* @param int uid[2] : si absent : valeur 'all' (mois) |
* @param int uid[3] : si absent : valeur 'all' (jour) |
*/ |
function getElement($uid){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
$condition_requete = $this->traiterParametresEtConstruireRequete($uid); |
$requete_liste_dates = 'SELECT DISTINCT '. |
'date_observation AS id '. |
'FROM cel_obs WHERE '.$condition_requete.' '. |
'ORDER BY date_observation'; |
$liste_dates = $this->executerRequete($requete_liste_dates); |
$liste_dates = $this->formaterListeResultats($liste_dates); |
$this->envoyerJson($liste_dates); |
return true; |
} |
private function formaterListeResultats($liste_dates) { |
if (!$liste_dates) { |
$liste_dates = array(); |
} |
foreach($liste_dates as &$date) { |
$date_heures = explode(' ',$date['id']); |
if(count($date_heures) > 1) { |
$date = $date_heures[0]; |
} |
$date = $date; |
} |
return $liste_dates; |
} |
private function traiterParametresEtConstruireRequete($params) { |
$requete_condition = ' ce_utilisateur = '.$this->proteger($params[0]); |
$taille_tableau_parametres = count($params); |
for($i=1; $i < $taille_tableau_parametres; $i++) { |
if($this->estUnParametreDate($params[$i])) { |
$fonction_date = $this->correspondance_fonction[$i]; |
$requete_condition .= ' AND '.$fonction_date.'(date_observation) = '.$this->proteger($params[$i]); |
} |
} |
return $requete_condition; |
} |
private function estUnParametreDate($valeur) { |
return is_numeric($valeur) && $valeur != "all"; |
} |
} |
?> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v1.6-croc/jrest/services/InventoryContributionList.php |
---|
New file |
0,0 → 1,76 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package papyrus_bp |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/ |
*/ |
/** |
* Classe renvoyant fragment html constitué à partir d'une liste très succinte des contributions de l'utilisateur |
* |
*/ |
class InventoryContributionList extends Cel { |
function getRessource() { |
echo ''; |
} |
function getElement($uid){ |
if(!isset($uid[0])) { |
echo ''; |
} |
$requete_contributions = "SELECT * FROM cel_obs ". |
"WHERE ce_utilisateur = ".$this->proteger($uid[0])." ". |
"ORDER BY date_modification DESC LIMIT 0,5"; |
$resultat_contributions = $this->requeter($requete_contributions); |
$resume = ''; |
if (is_array($resultat_contributions)) { |
foreach ($resultat_contributions as $ligne) { |
$ligne['nom_sel'] = htmlspecialchars($ligne['nom_sel']); |
$ligne['ce_utilisateur'] = htmlspecialchars($ligne['ce_utilisateur']); |
$ligne['zone_geo'] = htmlspecialchars($ligne['zone_geo']); |
$ligne['id_zone_geo'] = htmlspecialchars($this->convertirCodeZoneGeoVersDepartement($ligne['ce_zone_geo'])); |
$ligne['station'] = htmlspecialchars($ligne['station']); |
$ligne['milieu'] = htmlspecialchars($ligne['milieu']); |
$ligne['commentaire'] = htmlspecialchars($ligne['commentaire']); |
$ligne['transmission'] = htmlspecialchars($ligne['transmission']); |
$resume.= '<p>'.$ligne['nom_sel'] ." (".$ligne['nom_sel_nn'].") ". |
'Location : '. $ligne['zone_geo']." (".$ligne['id_zone_geo']."),". $ligne['station'] . "," . |
$ligne['milieu'] . "," . $ligne['commentaire'] . "," . $ligne['transmission'] . |
'</p>'; |
} |
} |
header("Content-Type: text/html; charset=ISO-8859-1"); |
print $resume; |
exit; |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.5 2008-11-13 11:29:12 ddelon |
* Reecriture gwt-ext |
* |
* Revision 1.4 2007-06-06 13:31:16 ddelon |
* v0.09 |
* |
* Revision 1.3 2007-05-22 12:54:09 ddelon |
* Securisation acces utilisateur |
* |
*/ |
?> |
/branches/v1.6-croc/jrest/services/InventoryCheck.php |
---|
New file |
0,0 → 1,82 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package papyrus_bp |
* @author David Delon <delon@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/ |
*/ |
/** |
* |
* Utilitaire mise a jour enregistrement inventaire |
* A voir avec David mais ne devrait plus être utilisé |
* |
*/ |
class InventoryCheck extends Cel { |
function getRessource(){ |
return; |
$requete_obs ="SELECT id_observation, zone_geo, ce_zone_geo, date_observation, ce_utilisateur, courriel_utilisateur FROM cel_obs"; |
$resultat_obs = $this->requeter($requete_obs); |
$observations = array(); |
if (is_array($resultat_obs)) { |
$observations = $resultat_obs; |
} |
foreach ($observations as $obs) { |
if ($obs['ce_zone_geo']!="000null") { |
$requete_lieu = "select * from cel_zones_geo where nom = '".mysql_escape_string($obs['zone_geo'])."' and id_zone_geo='".mysql_escape_string($obs['ce_zone_geo'])."' limit 1"; |
} |
else { |
$requete_lieu = "select * from cel_zones_geo where name = '".mysql_escape_string($obs['zone_geo'])."' limit 1"; |
} |
$res_loc = $this->requeter($requete_lieu); |
if (is_array($res_loc) && count($res_loc) > 0) { |
print $obs['id_observation']; |
print " "; |
print $obs['mail_utilisateur']; |
print " : "; |
print $obs['zone_geo']; |
print " - "; |
print $obs['ce_zone_geo']; |
print " - "; |
$lk="http://www.tela-botanica.org/cel/jrest/util/cel_inventory.php?PME_sys_fl=0&PME_sys_fm=0&PME_sys_sfn[0]=0&PME_sys_operation=PME_op_Change&PME_sys_rec=".$obs['id_observation']; |
$link_desc=' <a href="'.$lk.'">Correction</a>'; |
print $link_desc; |
print "<br>"; |
} |
} |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.2 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.1 2007-06-06 13:31:16 ddelon |
* v0.09 |
* |
* Revision 1.3 2007-05-22 12:54:09 ddelon |
* Securisation acces utilisateur |
* |
* |
* |
*/ |
?> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v1.6-croc/jrest/services/TestNameParser.php |
---|
New file |
0,0 → 1,123 |
<?php |
require_once('NameParser.php'); |
$parse = new NameParser(); |
$str=array(); |
$str[]='Paris quadrifolia L.'; |
$str[]='Phyteuma spicatum L.'; |
$str[]='Pinus sylvestris L.'; |
$str[]='Polygonatum multiflorum (L.) All.'; |
$str[]='Polygonatum multiflorum (L.) All.'; |
$str[]='Potentilla sterilis (L.) Garcke'; |
$str[]='Potentilla sterilis (L.) Garcke'; |
$str[]='Primula elatior (L.) Hill'; |
$str[]='Primula elatior (L.) Hill'; |
$str[]='Ranunculus ficaria L.'; |
$str[]='Ranunculus ficaria L.'; |
$str[]='Ranunculus ficaria L.'; |
$str[]='Ranunculus ficaria L.'; |
$str[]='Salvia pratensis L.'; |
$str[]='Sanguisorba officinalis L.'; |
$str[]='Sanicula europaea L.'; |
$str[]='Scrophularia nodosa L.'; |
$str[]='Securigera varia (L.) P. Lassen'; |
$str[]='Silene latifolia Poiret'; |
$str[]='Sonchus asper (L.) Hill'; |
$str[]='Stachys recta L.'; |
$str[]='Stachys sylvatica L.'; |
$str[]='Stellaria holostea L.'; |
$str[]='Symphytum officinale L.'; |
$str[]='Symphytum officinale L.'; |
$str[]='Teucrium scorodonia L.'; |
$str[]='Tilia platyphyllos Scop.'; |
$str[]='Tussilago farfara L.'; |
$str[]='Urtica dioica L.'; |
$str[]='Urtica dioica L.'; |
$str[]='Urtica dioica L.'; |
$str[]='Vaccinium myrtillus L.'; |
$str[]='Valeriana officinalis subsp. repens (Host) O. Bolòs and Vigo'; |
$str[]='Valeriana officinalis subsp. repens (Host) O. Bolòs & Vigo'; |
$str[]='Viburnum lantana L.'; |
$str[]='Viburnum opulus L.'; |
$str[]='Viola reichenbachiana Jordan ex Boreau'; |
$str[]='Viscum album L.'; |
$str[]='Aegopodium podagraria L.'; |
$str[]='Ajuga reptans L.'; |
$str[]='Alisma plantago-aquatica L.'; |
$str[]='Alliaria petiolata (M. Bieb.) Cavara & Grande'; |
$str[]='Alnus glutinosa (L.) Gaertn.'; |
$str[]='Bidens frondosa L.'; |
$str[]='Bidens tripartita L.'; |
$str[]='Callitriche palustris L.'; |
$str[]='Campanula trachelium L.'; |
$str[]='Carex brizoides L.'; |
$str[]='Carex vesicaria L.'; |
$str[]='Circaea lutetiana L.'; |
$str[]='Dryopteris filix-mas (L.) Schott'; |
$str[]='Elatine hexandra (Lapierre) DC.'; |
$str[]='Fragaria vesca L.'; |
$str[]='Glechoma hederacea L.'; |
$str[]='Glyceria fluitans (L.) R. Br.'; |
$str[]='Gnaphalium uliginosum L.'; |
$str[]='Iris pseudacorus L.'; |
$str[]='Lathyrus pratensis L.'; |
$str[]='Lemna minor L.'; |
$str[]='Leucanthemum vulgare Lam.'; |
$str[]='Lotus pedunculatus Cav.'; |
$str[]='Lycopus europaeus L.'; |
$str[]='Lysimachia nemorum L.'; |
$str[]='Lythrum portula (L.) D.A. Webb'; |
$str[]='Lythrum salicaria L.'; |
$str[]='Milium effusum L.'; |
$str[]='Oxalis acetosella L.'; |
$str[]='Phalaris arundinacea L.'; |
$str[]='Phyteuma spicatum L.'; |
$str[]='Potamogeton natans L.'; |
$str[]='Primula elatior (L.) Hill'; |
$str[]='Ranunculus flammula L.'; |
$str[]='Ranunculus sceleratus L.'; |
$str[]='Sagittaria sagittifolia L.'; |
$str[]='Scrophularia nodosa L.'; |
$str[]='Silene dioica (L.) Clairv.'; |
$str[]='Sparganium emersum Rehmann'; |
$str[]='Sparganium erectum L.'; |
$str[]='Valeriana officinalis L. subsp. tenuifolia Schübler & Martens'; |
$str[]='Veronica montana L.'; |
$str[]='Vinca minor L.'; |
$str[]='Acer campestre L.'; |
$str[]='Acer campestre L.'; |
$str[]='Achillea millefolium L.'; |
$str[]='Achillea millefolium L.'; |
$str[]='Achillea ptarmica L.'; |
$str[]='Achillea ptarmica L.'; |
$str[]='Achillea ptarmica L.'; |
foreach ($str as $st) { |
$data = $parse->parse($st); |
print 'nom : '; |
print $st; |
print ', genus : '; |
print $data['genus']; |
print ', species : '; |
print $data['species']; |
print ', authority : '; |
print $data['authority']; |
if (isset ($data['infra']) && $data['infra']!='') { |
print ', infra : '; |
print $data['infra']; |
} |
if (isset ($data['infra_authority']) && $data['infra_authority']!='') { |
print ', infra authority : '; |
print $data['infra_authority']; |
} |
if (isset ($data['infra_type']) && $data['infra_type']!='') { |
print ', infra type : '; |
print $data['infra_type']; |
} |
print "</br>"; |
} |
?> |
/branches/v1.6-croc/jrest/services/Inventory.php |
---|
New file |
0,0 → 1,148 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david@tela-botanica.org> |
* @author Aurelien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* CRUD observation |
* |
* in=utf8 |
* out=utf8 |
* |
**/ |
class Inventory extends Cel { |
// TODO: faire un descriptif du service |
function getRessource(){ |
} |
function getElement($uid){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
$value=array(); |
if(!isset($uid[0])) { |
return; |
} |
$parametres_recherche = array(array('ce_utilisateur',$uid[0]),array('ordre',$uid[1])); |
$chercheur_observations = new RechercheObservation($this->config); |
$retour_recherche = $chercheur_observations->rechercherObservations($uid[0], $parametres_recherche, 0, 1); |
$observation = array(); |
if(is_array($retour_recherche) && count($retour_recherche) > 0) { |
$observation = $retour_recherche[0]; |
} |
$observation = $this->formaterObservationVersTableauSequentiel(&$observation); |
$output = json_encode($observation); |
$this->envoyerJson($output); |
return true; |
} |
private function formaterObservationVersTableauSequentiel($observation) { |
if ($observation['date_observation']!="0000-00-00 00:00:00") { |
list($year,$month,$day)= explode('-',$observation['date_observation']); |
list($day)= explode(' ',$day); |
$observation['date_observation']=$day."/".$month."/".$year; |
} |
$observation = array($observation['nom_sel'], $observation['nom_sel_nn'], |
$observation['nom_ret'], $observation['nom_ret_nn'], |
$observation['nt'], $observation['famille'], $observation['zone_geo'], |
$observation['ce_zone_geo'], $observation['ordre'], |
$observation['date_observation'], $observation['lieudit'], |
$observation['station'], $observation['milieu'], |
$observation['commentaire'], $observation['latitude'], |
$observation['longitude']); |
return $observation; |
} |
function updateElement($uid,$pairs) { |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if (!isset($uid[1])) { |
//TODO: envoyer un message d'erreur |
return; |
} |
$uid[1] = rtrim($uid[1],','); |
$gestionnaire_observation = new GestionObservation($this->config); |
$modification_observation = $gestionnaire_observation->modifierObservation($uid[0],$uid[1],$pairs); |
return true; |
} |
function createElement($pairs){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($pairs['ce_utilisateur']); |
$gestionnaire_observation = new GestionObservation($this->config); |
$gestionnaire_observation->ajouterObservation($pairs['ce_utilisateur'], $pairs); |
return true; |
} |
/** |
* Supprime une observation |
* |
* uid[0] : utilisateur obligatoire |
* uid[1] : ordres de l'observation à supprimer |
*/ |
function deleteElement($uid){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if (!isset($uid[1])) { |
//TODO: envoyer un message d'erreur |
return; |
} |
$uid[1] = rtrim($uid[1],','); |
$gestionnaire_observation = new GestionObservation($this->config); |
$suppression_observation = $gestionnaire_observation->supprimerObservation($uid[0],$uid[1]); |
if ($suppression_observation) { |
echo "OK"; |
} |
exit() ; |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.11 2008-11-13 11:29:12 ddelon |
* Reecriture gwt-ext |
* |
* Revision 1.10 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.9 2007-05-22 12:54:09 ddelon |
* Securisation acces utilisateur |
* |
*/ |
?> |
/branches/v1.6-croc/jrest/services/LocationSearch.php |
---|
New file |
0,0 → 1,99 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* Classe gérant la completion des noms de lieux |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* @author David Delon <david.delon@clapas.net> |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2010, David Delon |
*/ |
/** |
* Cas d'utilisation : |
* Service completion nom de commune (plus tard de lieu en général) |
* |
* 1 : L'application recoit un debut de nom de lieu |
* 2 : Si la longueur du prefixe est > 2, l'application retourne les 50 premieres lieux |
* commencant par ce prefixe |
**/ |
class LocationSearch extends Cel { |
function getElement($uid){ |
$retour = array(); |
if (isset($uid[0])) { |
$retour = $this->executerRequeteLieu($uid[0]); |
} |
$this->envoyerJson($retour); |
return true; |
} |
function getRessource(){ |
print "[]"; |
return; |
} |
private function executerRequeteLieu($lieu) { |
$lieu_formate = $this->formaterChaineLieuPourRequete($lieu); |
$retour = array(); |
if ($this->estUneChaineRequeteValide($lieu_formate)) { |
$requete_information_lieu = 'SELECT DISTINCT nom, code '. |
'FROM cel_zones_geo '. |
'WHERE '. |
'nom LIKE '.$this->proteger($lieu_formate.'%').' '. |
'ORDER BY nom LIMIT 50'; |
$liste_lieux = $this->requeter($requete_information_lieu); |
if($liste_lieux) { |
foreach($liste_lieux as $lieu_trouve) { |
$retour[] = $this->formaterLigneResultat($lieu_trouve); |
} |
} |
} |
return $retour; |
} |
private function formaterChaineLieuPourRequete($params) { |
$lieu = $params; |
$lieu=ltrim($lieu); |
$lieu=preg_replace('/\*+/','%',$lieu); |
$lieu = str_replace(' ','_',$lieu); |
$lieu = str_replace('-','_',$lieu); |
return $lieu; |
} |
private function estUneChaineRequeteValide($lieu) { |
return (strlen($lieu) > 0) && ($lieu != '%'); |
} |
private function formaterLigneResultat($ligne) { |
return array($ligne['nom']." (".substr(sprintf("%02s",$ligne['code']),0,2).")",$ligne['code']); |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.4 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.3 2007-05-21 18:13:03 ddelon |
* Correction bug recherche commune du type "la canourgue" |
* |
* |
*/ |
?> |
/branches/v1.6-croc/jrest/services/InventoryKeyWordList.php |
---|
New file |
0,0 → 1,434 |
<?php |
// declare(encoding='UTF-8'); |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* Service de recherche et modification de l'arbre des mots clés associés à un id. |
* 1: Le service recoit un mot clé à ajouter à l'arbre |
* 2: Le service recherche l'arbre ou sous arbre correspondant au critères demandé |
* 3: Le service renvoie l'arbre au format json |
* |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* Cas d'utilisation : |
* |
* @author Aurélien PERONNET <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2011, Tela-Botanica |
*/ |
class InventoryKeyWordList extends Cel { |
protected $suffixe = ''; |
protected $suffixe_table = null; |
protected $suffixe_champ = null; |
private function setChampsEtTablePourSuffixe($suffixe) { |
$this->suffixe = $suffixe; |
switch($suffixe) { |
case 'obs': |
$this->suffixe_table = '_obs'; |
$this->suffixe_champ = '_obs'; |
break; |
case 'images': |
$this->suffixe_table = '_images'; |
$this->suffixe_champ = '_image'; |
break; |
} |
} |
public function getElement($uid) { |
// Controle detournement utilisateur |
$id_utilisateur = $uid[1] ; |
$this->controleUtilisateur($uid[1]); |
$this->setChampsEtTablePourSuffixe($uid[0]); |
$requete = 'SELECT mot_cle, id_mot_cle'.$this->suffixe_champ.', ce_mot_cle'.$this->suffixe_champ.'_parent '. |
'FROM cel_mots_cles'.$this->suffixe_table.' '. |
'WHERE id_utilisateur = '.$this->proteger($id_utilisateur).' '. |
'ORDER BY niveau '; |
$resultats_mots_cles = $this->requeter($requete); |
if (is_array($resultats_mots_cles)) { |
$mots_cles = array(); |
foreach($resultats_mots_cles as $mot_cle) { |
$mots_cles[] = $mot_cle; |
} |
$this->envoyerJson($mots_cles); |
return true; |
} |
} |
public function updateElement($uid, $pairs) { |
$id_utilisateur = $uid[1]; |
$this->controleUtilisateur($uid[1]); |
$this->setChampsEtTablePourSuffixe($uid[0]); |
$id_mot_cle = $pairs['id']; |
$action = $pairs['action']; |
if ($action == 'modification') { |
$nouveau_nom = $pairs['motcle']; |
$nouvel_id_general = md5(mb_strtolower($nouveau_nom)); |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET mot_cle = '.$this->proteger($nouveau_nom).' , '. |
' md5 = '.$this->proteger($nouvel_id_general).' '. |
'WHERE id_mot_cle'.$this->suffixe_champ.' = '.$this->proteger($id_mot_cle).' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur) ; |
$reussite = $this->executer($requete); |
if ($reussite !== false) { |
echo 'OK'; |
} |
} else if ($action == 'deplacement') { |
$this->commencerTransaction(); |
$transaction_reussie_1 = true; |
$id_pere = $pairs['parent']; |
$bornes = $this->calculerBornesEtNiveau($id_mot_cle, $id_utilisateur); |
$bg = $bornes['bg']; |
$bd = $bornes['bd']; |
$niveau = $bornes['niveau']; |
// on inverse l'intervalle de l'élément déplacé et du sous arbre |
$transaction_reussie_2 = $this->exclureIntervalle($bg, $bd, $id_utilisateur); |
$bg_negative = $bg - $bd - 1; |
$bd_negative = $bd - $bd - 1; |
// on recalcule les intervalles de l'arbre privé de ce sous arbre |
$transaction_reussie_3 = $this->decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur); |
$bornes_pere = $this->calculerBornesEtNiveau($id_pere, $id_utilisateur); |
$bg_pere = $bornes_pere['bg']; |
$bd_pere = $bornes_pere['bd']; |
$niveau_pere = $bornes_pere['niveau']; |
$decalage = $bd - $bg + 1; |
// on decale les bornes droite du pere pour préparer l'insertion |
$transaction_reussie_4 = $this->decalerBornesPlusIntervalle($bd_pere, $decalage, $id_utilisateur); |
$nouvelle_bd = $bd_pere + $decalage; |
$modif_niveau = $niveau_pere - $niveau + 1; |
$transaction_reussie_5 = $this->inclureIntervalle($bg_negative, $bd_negative, $nouvelle_bd, $modif_niveau, $id_utilisateur); |
$transaction_reussie_6 = $this->changerPere($id_mot_cle, $id_pere, $id_utilisateur); |
if ($transaction_reussie_1 !== false && $transaction_reussie_2 !== false && |
$transaction_reussie_3 !== false && $transaction_reussie_4 !== false && |
$transaction_reussie_5 !== false && $transaction_reussie_6 !== false) { |
$this->completerTransaction(); |
} else { |
$this->annulerTransaction(); |
} |
} |
} |
public function createElement($pairs) { |
// Controle detournement utilisateur |
$this->controleUtilisateur($pairs['identifiant']); |
$this->setChampsEtTablePourSuffixe($pairs['mode']); |
$id_utilisateur = $pairs['identifiant']; |
$mot_cle = $pairs['motcle']; |
// TODO supprimer accents |
$id_mot_cle_general = md5(mb_strtolower($mot_cle)); |
$id_mot_cle = $pairs['id']; |
$id_parent = $pairs['parent']; |
$this->ajouterMotCleRacine($id_utilisateur); |
$this->commencerTransaction(); |
$bornes = $this->calculerBornesEtNiveau($id_parent, $id_utilisateur); |
$borne_pere = $bornes['bd']; |
$niveau = $bornes['niveau'] + 1; |
$bg = $bornes['bd']; |
$bd = $bg + 1; |
$transaction_reussie_1 = $this->decalerBornesPlusDeux($borne_pere,$id_utilisateur) ? true : false; |
$requete = 'INSERT INTO cel_mots_cles'.$this->suffixe_table.' '. |
'VALUES ( '. |
$this->proteger($id_mot_cle).', '. |
$this->proteger($id_utilisateur).', '. |
$this->proteger($mot_cle).', '. |
$this->proteger($id_mot_cle_general).', '. |
$this->proteger($bg).', '. |
$this->proteger($bd).', '. |
$this->proteger($niveau).', '. |
$this->proteger($id_parent).') ' ; |
$transaction_reussie_2 = $this->executer($requete); |
if ($transaction_reussie_1 && $transaction_reussie_2) { |
$this->completerTransaction(); |
} else { |
$this->annulerTransaction(); |
} |
} |
public function deleteElement($uid) { |
$this->setChampsEtTablePourSuffixe($uid[0]); |
$id_utilisateur = $uid[1]; |
$id_mot_cle = $uid[2]; |
$tableau_ids_mots_cles = array(); |
$tableau_ids_mots_cles[] = $id_mot_cle; |
$this->controleUtilisateur($id_utilisateur); |
$this->commencerTransaction(); |
$bornes = $this->calculerBornesEtNiveau($id_mot_cle, $id_utilisateur); |
if($bornes) { |
$bg = $bornes['bg']; |
$bd = $bornes['bd']; |
$requete_mots_cles_fils = 'SELECT id_mot_cle'.$this->suffixe_champ.' as id FROM cel_mots_cles'.$this->suffixe_table.' '. |
'WHERE bg >= '.$this->proteger($bg).' '. |
' AND bd <= '.$this->proteger($bd).' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$mots_cles_fils = $this->requeter($requete_mots_cles_fils); |
foreach ($mots_cles_fils as $fils) { |
$tableau_ids_mots_cles[] = $fils['id']; |
} |
$requete = 'DELETE FROM cel_mots_cles'.$this->suffixe_table.' '. |
'WHERE bg >= '.$this->proteger($bg).' '. |
' AND bd <= '.$this->proteger($bd).' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$transaction_reussie_1 = $this->executer($requete); |
$transaction_reussie_2 = $this->decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur) ? true : false; |
if ($transaction_reussie_1 !== false && $transaction_reussie_2 !== false) { |
$this->completerTransaction(); |
} else { |
$this->annulerTransaction(); |
} |
} |
// Suppression des liaisons associées à ce mot clé |
$gestion_liaisons = new LiaisonMotsCles($this->config, $this->suffixe); |
$gestion_liaisons->supprimerToutesLiaisonsPourIdMotCle($id_utilisateur, $tableau_ids_mots_cles); |
} |
private function ajouterMotCleRacine($id) { |
$requete = 'SELECT COUNT(*) as nb_mc '. |
'FROM cel_mots_cles'.$this->suffixe_table.' '. |
'WHERE id_utilisateur = '.$this->proteger($id).' '; |
$resultat = $this->requeter($requete); |
if (is_array($resultat) && count($resultat) > 0) { |
$valeurs = $resultat[0]['nb_mc']; |
switch ($this->suffixe) { |
case 'obs' : |
$nom_racine = 'Projets'; |
$id_racine = 'racine_obs'; |
break; |
case 'images' : |
$nom_racine = 'Mots clés'; |
$id_racine = 'racine'; |
break; |
default: |
$nom_racine = $this->suffixe; |
$id_racine = $this->suffixe; |
} |
$md5_racine = $this->proteger(md5($nom_racine)); |
$id_racine = $this->proteger($id_racine); |
$nom_racine = $this->proteger($nom_racine); |
$id_utilisateur = $this->proteger($id); |
if ($valeurs == 0) { |
$requete = "INSERT INTO cel_mots_cles{$this->suffixe_table} ". |
"VALUES ($id_racine, $id_utilisateur, $nom_racine, $md5_racine, ". |
"1, 2, 0, '') "; |
$this->executer($requete); |
} |
} |
} |
/** |
* Désactive l'auto-commit puis débute la transaction |
*/ |
private function commencerTransaction() { |
// Désactive l'autocommit le temps de la manipulation de l'arbre |
$requete = 'SET AUTOCOMMIT = 0 '; |
$reussite_autocommit = $this->executer($requete); |
// Débute une nouvelle transaction |
$requete = 'BEGIN '; |
$reussite_begin = $this->executer($requete); |
} |
/** |
* Termine la transaction puis réactive l'auto-commit |
*/ |
private function completerTransaction() { |
// Complète la transaction |
$requete = 'COMMIT '; |
$reussite_commit = $this->executer($requete); |
// Réactive l'autocommit le temps de la manipulation de l'arbre |
$requete = 'SET AUTOCOMMIT = 1 '; |
$reussite_autocommit = $this->executer($requete); |
echo 'OK'; |
} |
/** |
* Annule la transaction et réactive l'auto-commit |
*/ |
private function annulerTransaction() { |
// Annule la transaction |
$requete = 'ROLLBACK '; |
$reussite_rollback = $this->executer($requete); |
// Réactive l'autocommit le temps de la manipulation de l'arbre |
$requete = 'SET AUTOCOMMIT = 1 '; |
$reussite_autocommit = $this->executer($requete); |
echo 'ERROR'; |
} |
/** |
* Renvoie les bornes d'un noeud de l'arbre des mots clés |
*/ |
private function calculerBornesEtNiveau($id_mot_cle,$id_utilisateur) { |
$requete = 'SELECT bd, bg, niveau '. |
'FROM cel_mots_cles'.$this->suffixe_table.' '. |
'WHERE id_mot_cle'.$this->suffixe_champ.' = '.$this->proteger($id_mot_cle).' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$resultat = $this->requeter($requete); |
$valeurs = null; |
if(is_array($resultat) && count($resultat) > 0) { |
$valeurs = $resultat[0]; |
} |
return $valeurs; |
} |
/** |
* Décale les bornes de deux pour insérer un nouvel élément |
*/ |
private function decalerBornesPlusDeux($valeur, $id_utilisateur) { |
// Décalage borne droite |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bd = bd + 2 WHERE bd >= '.$valeur.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_1 = $this->executer($requete); |
// Décalage borne gauche |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bg = bg + 2 '. |
'WHERE bg >= '.$valeur.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_2 = $this->executer($requete); |
return $reussi_1 !== false && $reussi_2 !== false; |
} |
/** |
* Décale les bornes d'un intervalle negatif donne (pour la suppression d'un sous arbre). |
*/ |
private function decalerBornesMoinsIntervalle($bg, $bd, $id_utilisateur) { |
$decalage = $bd - $bg + 1; |
// Décalage borne droite |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bd = bd - '.$decalage.' '. |
'WHERE bd >= '.$bg.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_1 = $this->executer($requete); |
// Décalage borne gauche |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bg = bg - '.$decalage.' '. |
'WHERE bg > '.$bg.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_2 = $this->executer($requete); |
return $reussi_1 !== false && $reussi_2 !== false; |
} |
/** |
* Décale à droite des bornes donées d'un intervalle positif donne (pour l'ajout d'un sous arbre). |
*/ |
private function decalerBornesPlusIntervalle($valeur_bornes, $largeur, $id_utilisateur) { |
$decalage = $largeur; |
// decalage borne droite |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bd = bd + '.$decalage.' '. |
'WHERE bd >= '.$valeur_bornes.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_1 = $this->executer($requete); |
// decalage borne gauche |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bg = bg + '.$decalage.' '. |
'WHERE bg >= '.$valeur_bornes.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
$reussi_2 = $this->executer($requete); |
return $reussi_1 !== false && $reussi_2 !== false; |
} |
/** |
* Inverse les bornes d'un intervalle pour l'exclure des modifications sur l'arbre sans changer la hiérarchie. |
*/ |
private function exclureIntervalle($bg, $bd, $id_utilisateur) { |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bd = bd - '.$bd.' - 1 , '. |
' bg = bg - '.$bd.' - 1 '. |
'WHERE bd <= '.$bd.' '. |
' AND bg >= '.$bg.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
return $this->executer($requete); |
} |
/** |
* Recale les bornes dun intervalle pour l'inclure dans l'arbre à la bonne place. |
* Décalage borne droite |
*/ |
private function inclureIntervalle($bg, $bd, $decalage,$modif_niveau, $id_utilisateur) { |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET bg = bg + '.$decalage.' , '. |
' bd = bd + '.$decalage.', '. |
' niveau = niveau + '.$modif_niveau.' '. |
' WHERE bg >= '.$bg.' '. |
' AND bd <= '.$bd.' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
return $this->executer($requete); |
} |
private function changerPere($id_mot_cle, $id_pere, $id_utilisateur) { |
$requete = 'UPDATE cel_mots_cles'.$this->suffixe_table.' '. |
'SET ce_mot_cle'.$this->suffixe_champ.'_parent = '.$this->proteger($id_pere).' '. |
'WHERE id_mot_cle'.$this->suffixe_champ.' = '.$this->proteger($id_mot_cle).' '. |
' AND id_utilisateur = '.$this->proteger($id_utilisateur).' '; |
return $this->executer($requete); |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/Resume.php |
---|
New file |
0,0 → 1,129 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package papyrus_bp |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/papyrus_bp/ |
*/ |
/** |
* Classe renvoyant un petit bout de json contenant les dernières obs publiques d'un utilisateur |
* Utilisée par l'annuaire appelant les web services résumé de chaque application |
* |
*/ |
class Resume extends Cel { |
function getElement($uid){ |
$requete_dernieres_obs = 'SELECT * FROM cel_obs'. |
' WHERE ce_utilisateur = '.$this->proteger($uid[1]). |
' AND transmission = 0'. |
' ORDER BY date_modification DESC LIMIT 0,5'; |
$resultat_dernieres_obs = $this->requeter($requete_dernieres_obs); |
$dernieres_obs = array(); |
$resume = array(); |
if (is_array($resultat_dernieres_obs)) { |
$dernieres_obs = $resultat_dernieres_obs; |
} |
$resume['titre'] = 'Vos dernières observations publiées'; |
$resume['lien_appli'] = '<a href="www.tela-botanica.org/appli:cel2"> Accéder au carnet en ligne </a>'; |
if (count($dernieres_obs) == 0) { |
$resume['message'] = 'Aucune observation saisie pour le moment'; |
} |
foreach ($dernieres_obs as $obs) { |
$chemin_sur_serveur = $this->config['cel']['url_images']; |
$date = 'Datée du '.$obs['date_modification'].'<br/>' ; |
$lieu = 'Lieu : '.trim($obs['zone_geo'],'000null').' ('.$this->convertirCodeZoneGeoVersDepartement(trim($obs['ce_zone_geo']),'000null').') '.trim($obs['station'],'000null').' '.trim($obs['lieudit'],'000null').'<br/>' ; |
$image =''; |
$cible_lien = ''; |
$req_liaison = 'SELECT * FROM cel_images WHERE id_image IN (SELECT id_image FROM cel_obs_images WHERE id_observation = "'.$obs['id_observation'].'") AND ce_utilisateur = "'.$obs['ce_utilisateur'].'"' ; |
$res_liaison = $this->requeter($req_liaison); |
$ligne_image = null; |
foreach ($res_liaison as $img) { |
$row = $img; |
} |
if($row != null) { |
$row['nom_original'] = htmlspecialchars($row['nom_original']); |
$row['id_image'] = htmlspecialchars($row['id_image']); |
$id = $row['id_image']; |
$tailleXY = $this->calculerDimensions(array($row['largeur'], $row['hauteur'])); |
$id = sprintf('%09s', $id) ; |
$id = wordwrap($id, 3 , '_', true) ; |
$id_fichier = $id.".jpg" ; |
$niveauDossier = explode("_", $id) ; |
$dossierNiveau1 = $niveauDossier[0] ; |
$dossierNiveau2 = $niveauDossier[1] ; |
$chemin_sur_serveur_final = $chemin_sur_serveur.'/'.$dossierNiveau1.'/'.$dossierNiveau2 ; |
$chemin_fichier = $chemin_sur_serveur_final.'/L/'.$id."_L.jpg" ; |
$chemin_fichier_s = $chemin_sur_serveur_final.'/M/'.$id."_M.jpg" ; |
$image = '<img src="'.$chemin_fichier_s.'" alt="'.$row['nom_original'].'" height="'.$tailleXY[1].'px" width="'.$tailleXY[0].'px"></img>'; |
$cible_lien = $chemin_fichier; |
} |
$resume_item = array('element' => $obs['nom_ret'].$date.$lieu, 'lien' => $cible_lien,'image' => $image); |
$resume['elements'][] = $resume_item; |
} |
$this->envoyerJson($resume); |
return true; |
} |
public function calculerDimensions($tailleXY) { |
$tailleOr = 75 ; |
if($tailleXY[1] == 0) { |
$tailleXY[1] = $tailleOr; |
} |
if($tailleXY[0] == 0) { |
$tailleXY[0] = $tailleOr; |
} |
$maxTaille = max($tailleXY[1],$tailleXY[0]) ; |
if($maxTaille == $tailleXY[1]) { |
$rapport = $tailleXY[1]/$tailleXY[0] ; |
$tailleXY[1] = 75 ; |
$tailleXY[0] = round($tailleXY[1]/$rapport,0) ; |
}else { |
$rapport = $tailleXY[0]/$tailleXY[1] ; |
$tailleXY[0] = 75 ; |
$tailleXY[1] = round($tailleXY[0]/$rapport,0) ; |
} |
return $tailleXY ; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryImageExport.php |
---|
New file |
0,0 → 1,393 |
<?php |
//TODO migrer cette classe lorsqu'elle deviendra utile à nouveau |
/**** |
* |
* Attention classe non migrée !!!! |
*/ |
Class InventoryImageExport extends DBAccessor { |
private $extendSpreadsheetProductor; |
private $archive; |
private $workbook; |
private $worksheet; |
private $chemin_export_liste; |
function InventoryImageExport($config) { |
parent::__construct($config); |
$this->config=$config; |
$this->extendSpreadsheetProductor = new SpreadsheetProductor(); |
$this->extendSpreadsheetProductor->initSpreadsheet(); |
} |
function getElement($uid){ |
$this->authentifier(); |
$tableau = array(); |
$tag = $uid[0]; |
$limite = 0; |
$pas = 0; |
//ini_set('max_execution_time',120); |
/*if(isset($uid[1]) && isset($uid[2])) { |
$limite = $uid[] |
}*/ |
$taille_archive_courante = 0; |
$index_archive_courante = 0; |
$taille_max_archive = $this->config['cel']['taille_max_archive']; |
$liens_archives = array(); |
$DB=$this->connectDB($this->config,'cel'); |
$query_id_id_img = 'SELECT cmc_id_mot_cle_utilisateur, cmc_id_proprietaire FROM cel_mots_cles_images WHERE cmc_id_mot_cle_general = md5("'.$DB->escapeSimple($tag).'")' ; |
$res =& $DB->query($query_id_id_img); |
if (DB::isError($res)) { |
$this->logger("InventoryImageExport",'Erreur de requete '.$query_id_id_img); |
die($res->getMessage()); |
} |
$query='SELECT * FROM cel_images'; |
$premier_item = true ; |
while ($row =& $res->fetchrow(DB_FETCHMODE_ASSOC)) { |
$tableau['mots cles'] = array('utilisateur' => $row['cmc_id_proprietaire'], 'mot cle' => $row['cmc_id_mot_cle_utilisateur']); |
if($premier_item) { |
$query .= ' WHERE '; |
$premier_item = false ; |
} |
else{ |
$query .= ' OR '; |
} |
$query .= '(ci_meta_mots_cles LIKE "%'.$row['cmc_id_mot_cle_utilisateur'].'%" AND ci_ce_utilisateur ="'.$row['cmc_id_proprietaire'].'")' ; |
} |
$query .= ' ORDER BY ci_meta_date_ajout' ; |
$res =& $DB->query($query); |
if (DB::isError($res)) { |
die($res->getMessage()); |
} |
$this->logger('Requetes',$query); |
// création d'un objet 'zipfile' |
$this->archive = new zipfile(); |
$i = 1; |
$this->initialiserWorkBook($index_archive_courante); |
while ($image =& $res->fetchrow(DB_FETCHMODE_ASSOC)) { |
$image['ci_nom_original'] = htmlspecialchars($image['ci_nom_original']); |
$image['ci_id_image'] = htmlspecialchars($image['ci_id_image']); |
$image['ci_meta_date_ajout'] = htmlspecialchars($image['ci_meta_date_ajout']); |
$image['ci_ce_utilisateur'] = htmlspecialchars($image['ci_ce_utilisateur']); |
$image['ci_meta_user_comment'] = htmlspecialchars($image['ci_meta_user_comment']); |
$image['ci_note_image'] = htmlspecialchars($image['ci_note_image']); |
$id = $image['ci_id_image']; |
$tableau[$id]['image'] = $image; |
if($filename = $this->renvoyerCheminSurServeur($id,false)) { |
// appel de la classe |
// nom du fichier à ajouter dans l'archive |
// contenu du fichier |
$fp = fopen ($filename, 'r'); |
$content = fread($fp, filesize($filename)); |
fclose ($fp); |
// ajout du fichier dans cet objet |
if(preg_match('/\.(?:jpg|jpeg)$/i',$image['ci_nom_original'])) { |
$nom_fichier_image = preg_replace('/\.(?:jpg|jpeg)$/i','_'.$id.'.jpg', $image['ci_nom_original']); |
} else { |
$nom_fichier_image = $image['ci_nom_original'].'_'.$id.'.jpg'; |
} |
$chemin_sur_serveur = $this->config['cel']['url_images']; |
$id = sprintf('%09s', $id) ; |
$id = wordwrap($id, 3 , '_', true) ; |
$niveauDossier = explode("_", $id) ; |
$dossierNiveau1 = $niveauDossier[0] ; |
$dossierNiveau2 = $niveauDossier[1] ; |
$chemin_sur_serveur_final = $chemin_sur_serveur.'/'.$dossierNiveau1.'/'.$dossierNiveau2 ; |
$chemin_fichier = $chemin_sur_serveur_final.'/O/'.$id."_O.jpg" ; |
$obs_liee['url_image_liee'] = $chemin_fichier; |
$taille_fichier = filesize($filename); |
$req_liaison = 'SELECT * FROM cel_inventory WHERE ordre IN (SELECT coi_ce_observation FROM cel_obs_images WHERE coi_ce_image = "'.$image['ci_id_image'].'") AND identifiant = "'.$image['ci_ce_utilisateur'].'"' ; |
$res_liaison =& $DB->query($req_liaison); |
if (DB::isError($res_liaison)) { |
die($res_liaison->getMessage()); |
} |
if (DB::isError($res_liaison)) { |
die($res_liaison->getMessage()); |
} |
while($obs_liee = & $res_liaison->fetchrow(DB_FETCHMODE_ASSOC)) { |
$tableau[$id]['obs'] = $obs_liee; |
$obs_liee['nom_image_liee'] = $nom_fichier_image; |
$obs_liee['url_image_liee'] = $chemin_fichier; |
$this->ecrireLigneWorkBook($i,$obs_liee); |
$i++; |
} |
//$this->archive->addfile($content, $nom_fichier_image); |
//$taille_archive_courante += $taille_fichier; |
if($taille_archive_courante <= $taille_max_archive) { |
} else { |
// fermeture du workbook |
$this->workbook->close(); |
$i = 1; |
// ajout du fichier liste dans cet objet |
// contenu du fichier |
$fp = fopen($this->chemin_export_liste, 'r'); |
$contenu = fread($fp, filesize($this->chemin_export_liste)); |
fclose ($fp); |
$this->archive->addfile($contenu,'liste.'.md5($tag).'_'.$index_archive_courante.'.xls'); |
$liens_archives[] = $this->enregistrerArchive($this->archive,$index_archive_courante,$tag); |
$index_archive_courante++; |
$taille_archive_courante = 0; |
$this->archive = new zipfile(); |
$this->initialiserWorkBook($index_archive_courante); |
} |
} |
//$this->verifierOuRelancerExecution(); |
//$this->logger('InventoryImageExport'," Temps d'éxécution à l'image ".$id." : ".$this->getTempsEcoule()); |
} |
// fermeture du workbook |
$this->workbook->close(); |
$i = 1; |
// ajout du fichier liste dans cet objet |
// contenu du fichier |
$fp = fopen($this->chemin_export_liste, 'r'); |
$contenu = fread($fp, filesize($this->chemin_export_liste)); |
fclose ($fp); |
$this->archive->addfile($contenu,'liste.'.md5($tag).'_'.$index_archive_courante.'.xls'); |
$liens_archives[] = $this->enregistrerArchive($this->archive,$index_archive_courante,$tag); |
$index_archive_courante++; |
$j = 1; |
$sortie = '<div><ul>'; |
foreach($liens_archives as $lien) { |
$sortie .= '<li> <a href = "'.$lien.'"> Partie '.$j.'</a></li>'; |
$j++; |
} |
$sortie .= '</div></ul>'; |
//$this->logger('InventoryImageExport',count($tableau)); |
//$this->logger('InventoryImageExport',print_r($tableau,true)); |
header('Content-Type: text/html'); |
echo $sortie; |
} |
function getRessource(){ |
//$this->getElement(); |
} |
public function authentifier() { |
if (!isset($_SERVER['PHP_AUTH_USER'])) { |
header('WWW-Authenticate: Basic realm="www.tela-botanica.org"'); |
header('HTTP/1.0 401 Unauthorized'); |
header('Content-type: text/html; charset=UTF-8'); |
echo 'Accès interdit'; |
exit; |
} else { |
if($this->verifierAcces($_SERVER['PHP_AUTH_USER'])) { |
return ; |
} |
else |
{ |
header('WWW-Authenticate: Basic realm="www.tela-botanica.org"'); |
header('HTTP/1.0 401 Unauthorized'); |
header('Content-type: text/html; charset=UTF-8'); |
echo 'Accès interdit'; |
exit ; |
} |
} |
} |
public function verifierAcces($id) { |
$DB=$this->connectDB($this->config,'database_ident'); |
$query="SELECT ".$this->config['database_ident']['ann_id']." as name FROM ".$this->config['database_ident']['annuaire']." WHERE ".$this->config['database_ident']['ann_id']." ='".$DB->escapeSimple($id) |
."' AND ".$this->config['database_ident']['ann_pwd']." = ".$this->config['database_ident']['pass_crypt_funct']."('".$DB->escapeSimple($_SERVER['PHP_AUTH_PW'])."')" ; |
$res =& $DB->getOne($query); |
if($res == "") { |
return false ; |
} |
if (DB::isError($res)) { |
die($res->getMessage()); |
} |
return $this->isAdmin($id) ; |
} |
private function renvoyerCheminSurServeur($id,$url = true) { |
if($url) { |
$chemin_sur_serveur = $this->config['cel']['url_images']; |
} else { |
$chemin_sur_serveur = $this->config['cel']['chemin_images']; |
} |
$id = sprintf('%09s', $id) ; |
$id = wordwrap($id, 3 , '_', true) ; |
$id_fichier = $id.".jpg" ; |
$niveauDossier = explode("_", $id) ; |
$dossierNiveau1 = $niveauDossier[0] ; |
$dossierNiveau2 = $niveauDossier[1] ; |
$chemin_sur_serveur_final = $chemin_sur_serveur.'/'.$dossierNiveau1.'/'.$dossierNiveau2 ; |
$chemin_fichier = $chemin_sur_serveur_final.'/L/'.$id."_L.jpg" ; |
return $chemin_fichier; |
} |
private function renvoyerCheminExport($url = true) { |
if($url) { |
return $this->config['cel']['url_export']; |
} else { |
return $this->config['cel']['chemin_export']; |
} |
} |
private function enregistrerArchive($zip,$index,$tag) { |
// production de l'archive' Zip |
$this->archive = $zip->file(); |
$chemin_export = $this->renvoyerCheminExport(false); |
$url_export = $this->renvoyerCheminExport(true); |
$chemin_archive = $chemin_export.'/'.md5($tag).'_'.$index.'.zip'; |
$url_archive = $url_export.'/'.md5($tag).'_'.$index.'.zip'; |
$fp = fopen($chemin_archive,'w+'); |
$ecriture = fwrite($fp,$this->archive); |
fclose($fp); |
if($ecriture) { |
return $url_archive; |
} else { |
return false; |
} |
} |
private function initialiserWorkBook($index) { |
// Creating a workbook |
$this->chemin_export_liste = $this->renvoyerCheminExport(false).'/liste'.$index.'.xls'; |
$this->workbook = new Spreadsheet_Excel_Writer($this->chemin_export_liste); |
// Creating a worksheet |
$this->worksheet = $this->workbook->addWorksheet('Liste'); |
$this->worksheet->write(0,0,'url de l\'image'); |
$this->worksheet->write(0,1,'Nom original de l\'image'); |
//$this->worksheet->write(0,1,'Nom saisi'); |
//$this->worksheet->write(0,2,'Numero nomenclatural'); |
$this->worksheet->write(0,2,'Nom retenu'); |
$this->worksheet->write(0,3,'Numero nomenclatural nom retenu'); |
$this->worksheet->write(0,4,'Numero taxonomique'); |
$this->worksheet->write(0,5,'Famille'); |
//$this->worksheet->write(0,7,'Commune'); |
//$this->worksheet->write(0,8,'Identifiant Commune'); |
$this->worksheet->write(0,6,'Date Observation'); |
// $this->worksheet->write(0,10,'Lieu dit'); |
//$this->worksheet->write(0,11,'Station'); |
//$this->worksheet->write(0,12,'Milieu'); |
$this->worksheet->write(0,7,'Contributeur'); |
$this->worksheet->write(0,8,'Commentaire'); |
} |
private function ecrireLigneWorkBook($index, $observation) { |
$this->worksheet->write($index,0,$observation['url_image_liee']); |
$this->worksheet->write($index,1,$observation['nom_image_liee']); |
//$this->worksheet->write($index,1,$observation['nom_sel']); |
//$this->worksheet->write($index,2,$observation['num_nom_sel']); |
$this->worksheet->write($index,2,$observation['nom_ret']); |
$this->worksheet->write($index,3,$observation['num_nom_ret']); |
$this->worksheet->write($index,4,$observation['num_taxon']); |
$this->worksheet->write($index,5,$observation['famille']); |
//$this->worksheet->write($index,7,$observation['location']); |
//$this->worksheet->write($index,8,$observation['id_location']); |
$this->worksheet->write($index,6,$observation['date_observation']); |
//$this->worksheet->write($index,10,$observation['lieudit']); |
//$this->worksheet->write($index,11,$observation['station']); |
//$this->worksheet->write($index,12,$observation['milieu']); |
$this->worksheet->write($index,7,$observation['identifiant']); |
$this->worksheet->write($index,8,$observation['commentaire']); |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.5 2008-11-13 11:29:12 ddelon |
* Reecriture gwt-ext |
* |
* Revision 1.4 2007-06-06 13:31:16 ddelon |
* v0.09 |
* |
* Revision 1.3 2007-05-22 12:54:09 ddelon |
* Securisation acces utilisateur |
* |
* |
* |
*/ |
?> |
/branches/v1.6-croc/jrest/services/CelStatistiqueTxt.php |
---|
New file |
0,0 → 1,407 |
<?php |
/** |
* Service fournissant des statistiques de l'application CEL au format texte (JSON). |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* Cas d'utilisation : |
* /CelStatistiqueTxt/TypeDeStat : retourne les statistiques demandées |
* Paramêtres : |
* utilisateur=courriel : retourne les statistiques d'un utilisateur donné. |
* |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright Copyright (c) 2011, Tela Botanica (accueil@tela-botanica.org) |
*/ |
class CelStatistiqueTxt extends Cel { |
/** |
* Méthode appelée avec une requête de type GET. |
*/ |
public function getElement($ressources) { |
$graph = null; |
$serveur = ''; |
if (isset($ressources[0])) { |
$this->analyserParametresUrl(); |
$stat_demande = array_shift($ressources); |
$methode = 'get'.$stat_demande; |
if (method_exists($this, $methode)) { |
$this->ressources = $ressources; |
$stats = $this->$methode($ressources); |
} else { |
$this->messages[] = "Ce type de statistiques '$stat_demande' n'est pas disponible."; |
} |
} else { |
$this->messages[] = "La ressource du service CEL StatistiqueTxt doit indiquer le type de statistique. Ex. : .../CelStatistiqueTxt/Nombres"; |
} |
if (!is_null($stats)) { |
$this->envoyerJson($stats); |
} |
} |
private function analyserParametresUrl() { |
$this->parametres['utilisateur'] = isset($_GET['utilisateur']) ? $this->bdd->quote($this->verifierSecuriteParametreUrl($_GET['utilisateur'])) : null; |
$this->parametres['num_taxon'] = isset($_GET['num_taxon']) ? $this->bdd->quote($this->verifierSecuriteParametreUrl($_GET['num_taxon'])) : null; |
$this->parametres['taxon'] = isset($_GET['taxon']) ? $this->bdd->quote($this->verifierSecuriteParametreUrl($_GET['taxon'].'%')) : null; |
$this->parametres['tag'] = isset($_GET['tag']) ? $this->verifierSecuriteParametreUrl($_GET['tag']) : null; |
$this->parametres['start'] = isset($_GET['start']) ? $this->verifierSecuriteParametreUrl($_GET['start']) : null; |
$this->parametres['limit'] = isset($_GET['limit']) ? $this->verifierSecuriteParametreUrl($_GET['limit']) : null; |
} |
private function getListeUtilisateursNbrePhotos() { |
$liste = array(); |
$requete = $this->construireRequeteListeUtilisateurNbrePhoto(); |
if ($requete != null) { |
$resultats = $this->executerRequete($requete); |
if ($resultats != false) { |
foreach ($resultats as $resultat) { |
$liste[$resultat['courriel_utilisateur']] = $resultat['nbre']; |
} |
} |
} |
return $liste; |
} |
private function construireRequeteListeUtilisateurNbrePhoto() { |
$select = 'SELECT co.courriel_utilisateur, COUNT(DISTINCT ci.id_image) AS nbre '; |
$from = 'FROM cel_obs co '. |
' LEFT JOIN cel_obs_images coi ON (coi.id_observation = co.id_observation) '. |
' LEFT JOIN cel_images ci ON (coi.id_image = ci.id_image) '; |
$where = 'WHERE transmission = 1 '; |
$groupBy = 'GROUP BY co.courriel_utilisateur '; |
$orderBy = 'ORDER BY nbre DESC '; |
$limitSql = 'LIMIT 0,150 '; |
$zero_images = false; |
if (count($this->parametres) != 0) { |
extract($this->parametres); |
$filtres = array(); |
if (isset($utilisateur)) { |
$filtres[] = "co.courriel_utilisateur = $utilisateur "; |
} |
if (isset($num_taxon)) { |
$filtres[] = "nt = $num_taxon "; |
} |
if (isset($taxon)) { |
$filtres[] = "nom_ret LIKE $taxon "; |
} |
if (isset($tag)) { |
$limitation = $this->construireWhereTags(); |
if ($limitation != null) { |
$filtres[] = $limitation; |
} else { |
$zero_images = true; |
} |
} |
$where .= ((count($filtres) > 0) ? 'AND '.implode(' AND ', $filtres) : ''); |
if (isset($start)) { |
$limitSql = str_replace('0,', "$start,", $limitSql); |
} |
if (isset($limit)) { |
$limitSql = str_replace('150', $limit, $limitSql); |
} |
} |
if ($zero_images) { |
$requete = null; |
} else { |
$requete = $select.$from.$where.$groupBy.$orderBy.$limitSql; |
//echo $requete; |
} |
return $requete; |
} |
private function construireWhereTags() { |
$where = null; |
if (isset($this->parametres['tag'])) { |
$tag = $this->parametres['tag']; |
$tag_encode = $this->bdd->quote($this->encoderMotCle(trim($tag))); |
// Construction de la requête |
$requete = 'SELECT cmc_id_mot_cle_utilisateur, cmc_id_proprietaire '. |
'FROM cel_mots_cles_images '. |
"WHERE cmc_id_mot_cle_general = $tag_encode "; |
$elements = $this->executerRequete($requete); |
if ($elements != false && count($elements) > 0) { |
// Pré-construction du where de la requête |
$tpl_where = '(ci_meta_mots_cles LIKE "%%%s%%" AND ci_ce_utilisateur = %s )'; |
$requete_where = array(); |
foreach ($elements as $occurence) { |
$requete_where[] = sprintf($tpl_where, $occurence['cmc_id_mot_cle_utilisateur'], $this->bdd->quote($occurence['cmc_id_proprietaire'])); |
} |
$where = ' ('.implode(" \nOR ", $requete_where).') '; |
} else { |
$this->debug[] = "Aucune image ne correspond à ce mot clé."; |
} |
} |
return $where; |
} |
private function getListeTaxonsNbrePhotos() { |
$requete = $this->construireRequeteListeTaxonNbrePhoto(); |
$resultats = $this->executerRequete($requete); |
$liste = array(); |
if ($resultats != false) { |
foreach ($resultats as $resultat) { |
$liste[$resultat['nom_ret']] = $resultat['nbre']; |
} |
} |
return $liste; |
} |
private function construireRequeteListeTaxonNbrePhoto() { |
$select = 'SELECT nom_ret, COUNT(DISTINCT ci.id_image) AS nbre '; |
$from = 'FROM cel_obs co '. |
' LEFT JOIN cel_obs_images coi ON (coi.id_observation = co.id_observation) '. |
' LEFT JOIN cel_images ci ON (coi.id_image = ci.id_image) '; |
$where = 'WHERE transmission = 1 '. |
" AND nom_ret != '' "; |
$groupBy = 'GROUP BY nom_ret '; |
$orderBy = 'ORDER BY nbre DESC '; |
$limitSql = 'LIMIT 0,150 '; |
if (count($this->parametres) != 0) { |
extract($this->parametres); |
$filtres = array(); |
if (isset($utilisateur)) { |
$filtres[] = "co.courriel_utilisateur = $utilisateur "; |
} |
if (isset($num_taxon)) { |
$filtres[] = "nt = $num_taxon "; |
} |
if (isset($taxon)) { |
$filtres[] = "nom_ret LIKE $taxon "; |
} |
$where .= ((count($filtres) > 0) ? 'AND '.implode(' AND ', $filtres) : ''); |
if (isset($start)) { |
$limitSql = str_replace('0,', "$start,", $limitSql); |
} |
if (isset($limit)) { |
$limitSql = str_replace('150', $limit, $limitSql); |
} |
} |
$requete = $select.$from.$where.$groupBy.$orderBy.$limitSql; |
return $requete; |
} |
private function getNombres() { |
$requete = $this->construireRequeteNbreObs(); |
$info['observations'] = (int) $this->executerRequete($requete, 'Column'); |
$requete = $this->construireRequeteNbreObsPubliques(); |
$info['observationsPubliques'] = (int) $this->executerRequete($requete, 'Column'); |
$requete = $this->construireRequeteNbreImg(); |
$info['images'] =(int) $this->executerRequete($requete, 'Column'); |
$requete = $this->construireRequeteNbreImgLiees(); |
$info['imagesLiees'] =(int) $this->executerRequete($requete, 'Column'); |
$requete = $this->construireRequeteNbreObsLiees(); |
$info['observationsLiees'] = (int) $this->executerRequete($requete, 'Column'); |
$info['moyImagesParObs'] = ($info['observationsLiees'] > 0 ? round($info['imagesLiees']/$info['observationsLiees'], 2) : ''); |
$requete = $this->construireRequeteNbreObsParCommune(); |
$info['communes'] = ($resultats = $this->executerRequete($requete)) ? count($resultats) : '' ; |
$info['observationsParCommunesMin'] = 1000; |
$info['observationsParCommunesMax'] = 0; |
$info['observationsParCommunesTotal'] = 0; |
foreach ($resultats as $resultat) { |
if ($resultat['nbre'] < $info['observationsParCommunesMin']) { |
$info['observationsParCommunesMin'] = $resultat['nbre']; |
} |
if ($resultat['nbre'] > $info['observationsParCommunesMax']) { |
$info['observationsParCommunesMax'] = $resultat['nbre']; |
} |
$info['observationsParCommunesTotal'] += $resultat['nbre']; |
} |
$info['observationsParCommunesMoyenne'] = ($info['communes'] > 0 ) ? round($info['observationsParCommunesTotal'] / $info['communes'], 2) : 0; |
return $info; |
} |
private function construireRequeteNbreObs() { |
$requete = 'SELECT COUNT(id_observation) AS nbre '. |
'FROM cel_obs '; |
if (count($this->parametres) != 0) { |
$filtres = array(); |
extract($this->parametres); |
if (isset($utilisateur)) { |
$filtres[] = "courriel_utilisateur = $utilisateur "; |
} |
if (isset($num_taxon)) { |
$filtres[] = "num_taxon = $num_taxon "; |
} |
if (isset($taxon)) { |
$filtres[] = "nom_ret LIKE $taxon "; |
} |
$requete .= ((count($filtres) > 0) ? 'WHERE '.implode(' AND ', $filtres) : ''); |
} |
return $requete; |
} |
private function construireRequeteNbreObsPubliques() { |
$requete = 'SELECT COUNT(id_observation) AS nbre '. |
'FROM cel_obs '. |
"WHERE transmission = 1 "; |
if (count($this->parametres) != 0) { |
$filtres = array(); |
extract($this->parametres); |
if (isset($utilisateur)) { |
$filtres[] = "courriel_utilisateur = $utilisateur "; |
} |
if (isset($num_taxon)) { |
$filtres[] = "num_taxon = $num_taxon "; |
} |
if (isset($taxon)) { |
$filtres[] = "nom_ret LIKE $taxon "; |
} |
$requete .= ((count($filtres) > 0) ? 'AND '.implode(' AND ', $filtres) : ''); |
} |
return $requete; |
} |
private function construireRequeteNbreObsParCommune() { |
$requete = 'SELECT COUNT(id_observation) AS nbre '. |
'FROM cel_obs '. |
"WHERE zone_geo IS NOT NULL ". |
" AND ce_zone_geo IS NOT NULL "; |
$groupBy = 'GROUP BY zone_geo, ce_zone_geo'; |
if (count($this->parametres) != 0) { |
$filtres = array(); |
extract($this->parametres); |
if (isset($utilisateur)) { |
$filtres[] = "courriel_utilisateur = $utilisateur "; |
} |
if (isset($num_taxon)) { |
$filtres[] = "nt = $num_taxon "; |
} |
if (isset($taxon)) { |
$filtres[] = "nom_ret LIKE $taxon "; |
} |
$requete .= ((count($filtres) > 0) ? 'AND '.implode(' AND ', $filtres) : ''); |
} |
$requete .= $groupBy; |
return $requete; |
} |
private function construireRequeteNbreImg() { |
$select = 'SELECT COUNT(DISTINCT ci.id_image) AS nbre '; |
$from = 'FROM cel_images ci '; |
if (count($this->parametres) != 0) { |
$filtres = array(); |
extract($this->parametres); |
if (isset($utilisateur)) { |
$filtres[] = "courriel_utilisateur = $utilisateur "; |
} |
if (isset($num_taxon)) { |
$filtres[] = "nt = $num_taxon "; |
} |
if (isset($taxon)) { |
$filtres[] = "nom_ret LIKE $taxon "; |
} |
if (isset($num_taxon) || isset($taxon)) { |
$from .= 'LEFT JOIN cel_obs_images coi ON (coi.id_image = ci.id_image) '. |
'LEFT JOIN cel_obs co ON (coi.id_observation = co.id_observation) '; |
} |
$where = ((count($filtres) > 0) ? 'WHERE '.implode(' AND ', $filtres) : ''); |
} |
$requete = $select.$from.$where; |
return $requete; |
} |
private function construireRequeteNbreImgLiees() { |
$select = 'SELECT COUNT(DISTINCT ci.id_image) AS nbre '; |
$from = 'FROM cel_obs_images coi '. |
' LEFT JOIN cel_images ci ON (coi.id_image = ci.id_image) '; |
if (count($this->parametres) != 0) { |
$filtres = array(); |
extract($this->parametres); |
if (isset($utilisateur)) { |
$filtres[] = "ci.courriel_utilisateur = $utilisateur "; |
} |
if (isset($num_taxon)) { |
$filtres[] = "nt = $num_taxon "; |
} |
if (isset($taxon)) { |
$filtres[] = "nom_ret LIKE $taxon "; |
} |
if (isset($num_taxon) || isset($taxon)) { |
$from .= 'LEFT JOIN cel_obs ON (coi.id_observation = co.id_observation) '; |
} |
$where = ((count($filtres) > 0) ? 'WHERE '.implode(' AND ', $filtres) : ''); |
} |
$requete = $select.$from.$where; |
return $requete; |
} |
private function construireRequeteNbreObsLiees() { |
$select = 'SELECT COUNT(DISTINCT coi.id_observation) AS nbre '; |
$from = 'FROM cel_obs_images coi '. |
' LEFT JOIN cel_obs co ON (coi.id_observation = co.id_observation) '; |
if (count($this->parametres) != 0) { |
$filtres = array(); |
extract($this->parametres); |
if (isset($utilisateur)) { |
$filtres[] = "courriel_utilisateur = $utilisateur "; |
} |
if (isset($num_taxon)) { |
$filtres[] = "nt = $num_taxon "; |
} |
if (isset($taxon)) { |
$filtres[] = "nom_ret LIKE $taxon "; |
} |
$where = ((count($filtres) > 0) ? 'WHERE '.implode(' AND ', $filtres) : ''); |
} |
$requete = $select.$from.$where; |
return $requete; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/CelStatistique.php |
---|
New file |
0,0 → 1,968 |
<?php |
/** |
* Service fournissant des urls vers des images de graphiques sur les statistiques de l'application CEL. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* Cas d'utilisation : |
* /CelStatistique/TypeDeGraph : retourne le graphique demandé |
* Paramêtres : |
* serveur=[0-9] : retourne le graphique demandé sur le serveur numéro 0 à 9 (voir http://code.google.com/intl/fr/apis/chart/docs/making_charts.html#enhancements ) |
* |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright 2009 |
*/ |
class CelStatistique extends Cel { |
/** |
* Méthode appelée avec une requête de type GET. |
*/ |
public function getElement($param) { |
$graph = null; |
$serveur = ''; |
if (isset($param[0])) { |
$graph_demande = array_shift($param); |
$methode = 'get'.$graph_demande; |
if (method_exists($this, $methode)) { |
$graph = $this->$methode($param); |
} else { |
$this->messages[] = "Ce type de graphique '$graph_demande' n'est pas disponible."; |
} |
} else { |
$this->messages[] = "Le premier paramêtre du service CEL Statistique doit correspondre au type de graphique."; |
} |
if (!is_null($graph)) { |
$serveur = (isset($_GET['serveur']) && preg_match('/^[0-9]$/', $_GET['serveur'])) ? $_GET['serveur'].'.' : ''; |
$url = "http://{$serveur}chart.apis.google.com/chart"; |
$contexte = stream_context_create( |
array('http' => array( |
'method' => 'POST', |
'content' => http_build_query($graph), |
'header' => 'Content-Type: application/x-www-form-urlencoded'))); |
$image = file_get_contents($url, false, $contexte); |
$this->envoyer($image, 'image/png', null, false); |
} else { |
$info = 'Un problème est survenu : '.print_r($this->messages, true); |
$this->envoyer($info); |
} |
} |
private function getEvolImgLieesParMois($param) { |
$utilisateur = isset($_GET['utilisateur']) ? $this->bdd->quote($_GET['utilisateur']) : null; |
// Récupération des données |
$requete = "SELECT DATE_FORMAT(date_creation, '%Y%m') AS periode, COUNT(ci.id_image) AS nbre ". |
"FROM cel_obs_images coi LEFT JOIN cel_images ci ON (coi.id_image = ci.id_image) ". |
"WHERE date_creation != '0000-00-00 00:00:00' ". |
((isset($utilisateur)) ? " AND courriel_utilisateur = $utilisateur " : ''). |
'GROUP BY periode '. |
'ORDER BY periode '; |
$resulats = $this->executerRequete($requete); |
$img_totale = array(); |
foreach ($resulats as $info) { |
$img_totale[$info['periode']] = $info['nbre']; |
} |
// Trie des dates pour les étiquettes des axes |
$dates = array(); |
$annees = array(); |
$les_mois = array(); |
$pas = 1; // intervalle de mois entre deux étiquettes |
$periode = 0; |
$cumul = 0; |
$img_totale_cumul = array(); |
foreach ($img_totale as $annee_mois => $nbre) { |
$annee = substr($annee_mois, 0, 4); |
$mois = substr($annee_mois, 4, 2); |
$mois_fmt_B = strftime('%b', strtotime("0000-$mois-01")); |
$cumul += $nbre; |
$img_totale_cumul[$annee_mois] = $cumul; |
if (!isset($dates[$annee][$mois])) { |
$annees[] = (!isset($dates[$annee]) ? $annee : ''); |
$les_mois[] = is_int($periode++ / $pas) ? $mois_fmt_B : ''; |
// Ajouter au tableau dates tjrs à la fin |
$dates[$annee][$mois] = 1; |
} |
} |
// Post traitement des données |
$titre = "Évolution des images liées aux observations par mois"; |
$valeurs_y = implode(',', $img_totale); |
$valeurs_r = implode(',', $img_totale_cumul); |
$valeurs_max_y = max($img_totale); |
$valeurs_max_r = max($img_totale_cumul); |
$y_val_fin = $valeurs_max_y; |
$y_pas = 200; |
$r_val_fin = $valeurs_max_r; |
$r_pas = 1000; |
$etiquettes_x1 = implode('|', $les_mois); |
$etiquettes_x2 = implode('|', $annees); |
$etiquettes_y = 'Images'; |
// Construire de l'url de l'image |
$graph = array('cht' => 'lc', |
'chtt' => $titre, |
'chs' => '600x200', |
'chco' => '007F00,99CC00', |
'chd' => 't:'.$valeurs_y.'|'.$valeurs_r, |
'chds' => "0,$valeurs_max_y,0,$valeurs_max_r", |
'chxt' => 'y,y,x,x,r', |
'chxl' => '1:|'.$etiquettes_y.'|3:|'.$etiquettes_x2.'|2:|'.$etiquettes_x1.'', |
'chxp' => '1,50|3,0', |
'chxr' => "0,0,$y_val_fin,$y_pas|4,0,$r_val_fin,$r_pas", |
'chm' => 'N ** ,000000,0,-1,8,1.0,ht', |
'chxs' => '0,007F00|4,99CC00'); |
return $graph; |
} |
private function getEvolImgParMois($param) { |
$utilisateur = isset($_GET['utilisateur']) ? $this->bdd->quote($_GET['utilisateur']) : null; |
// Récupération des données |
$requete = "SELECT DATE_FORMAT(date_creation, '%Y%m') AS periode, COUNT(id_image) AS nbre ". |
"FROM cel_images ". |
"WHERE date_creation != '0000-00-00 00:00:00' ". |
((isset($utilisateur)) ? " AND courriel_utilisateur = $utilisateur " : ''). |
'GROUP BY periode '. |
'ORDER BY periode '; |
$resulats = $this->executerRequete($requete); |
$img_totale = array(); |
foreach ($resulats as $info) { |
$img_totale[$info['periode']] = $info['nbre']; |
} |
// Trie des dates pour les étiquettes des axes |
$dates = array(); |
$annees = array(); |
$les_mois = array(); |
$pas = 1; // intervalle de mois entre deux étiquettes |
$periode = 0; |
$cumul = 0; |
$img_totale_cumul = array(); |
foreach ($img_totale as $annee_mois => $nbre) { |
$annee = substr($annee_mois, 0, 4); |
$mois = substr($annee_mois, 4, 2); |
$mois_fmt_B = strftime('%b', strtotime("0000-$mois-01")); |
$cumul += $nbre; |
$img_totale_cumul[$annee_mois] = $cumul; |
if (!isset($dates[$annee][$mois])) { |
$annees[] = (!isset($dates[$annee]) ? $annee : ''); |
$les_mois[] = is_int($periode++ / $pas) ? $mois_fmt_B : ''; |
// Ajouter au tableau dates tjrs à la fin |
$dates[$annee][$mois] = 1; |
} |
} |
// Post traitement des données |
$titre = "Évolution du dépôt d'images par mois"; |
$valeurs_y = implode(',', $img_totale); |
$valeurs_r = implode(',', $img_totale_cumul); |
$valeurs_max_y = max($img_totale); |
$valeurs_max_r = max($img_totale_cumul); |
$y_val_fin = $valeurs_max_y; |
$y_pas = 500; |
$r_val_fin = $valeurs_max_r; |
$r_pas = 1000; |
$etiquettes_x1 = implode('|', $les_mois); |
$etiquettes_x2 = implode('|', $annees); |
$etiquettes_y = 'Images'; |
// Construire de l'url de l'image |
$graph = array('cht' => 'lc', |
'chtt' => $titre, |
'chs' => '600x200', |
'chco' => '007F00,99CC00', |
'chd' => 't:'.$valeurs_y.'|'.$valeurs_r, |
'chds' => "0,$valeurs_max_y,0,$valeurs_max_r", |
'chxt' => 'y,y,x,x,r', |
'chxl' => '1:|'.$etiquettes_y.'|3:|'.$etiquettes_x2.'|2:|'.$etiquettes_x1.'', |
'chxp' => '1,50|3,0', |
'chxr' => "0,0,$y_val_fin,$y_pas|4,0,$r_val_fin,$r_pas", |
'chm' => 'h,C3C3C3,0,0.5,1,-1|N ** ,000000,0,-1,8,1.0,ht', |
'chxs' => '0,007F00|4,99CC00'); |
return $graph; |
} |
private function getEvolUtilisateurParMois($param) { |
// Récupération des données |
$requete = 'SELECT DISTINCT courriel_utilisateur , '. |
' MIN(date_creation) AS date_min, MAX(date_creation) AS date_max, '. |
' COUNT(id_observation) AS obs_nbre '. |
'FROM cel_obs '. |
"WHERE date_creation != '0000-00-00 00:00:00' ". |
" AND courriel_utilisateur LIKE '%@%' ". |
'GROUP BY courriel_utilisateur '. |
'ORDER BY date_min ASC '; |
$resultats = $this->executerRequete($requete); |
// Trie des données et des dates pour les étiquettes des axes |
$dates = array(); |
$annees = array(); |
$utilisateurs = array(); |
$les_mois = array(); |
$pas = 2; // intervalle de mois entre deux étiquettes |
$periode = 0; |
foreach ($resultats as $enrg) { |
$annee = substr($enrg['date_min'], 0, 4); |
$mois = substr($enrg['date_min'], 5, 2); |
$mois_fmt_B = strftime('%b', strtotime("0000-$mois-01")); |
if (!isset($dates[$annee][$mois])) { |
$annees[] = (!isset($dates[$annee]) ? $annee : ''); |
$les_mois[] = is_int($periode++ / $pas) ? $mois_fmt_B : ''; |
$utilisateurs["$annee-$mois"] = 1; |
// Ajouter au tableau dates tjrs à la fin |
$dates[$annee][$mois] = 1; |
} else { |
$utilisateurs["$annee-$mois"]++; |
} |
} |
// Post traitement des données |
$titre = 'Évolution des utilisateurs par mois'; |
$valeurs = implode(',', $utilisateurs); |
$valeurs_max = max($utilisateurs); |
$y_val_fin = $valeurs_max; |
$y_pas = 5; |
$etiquettes_x1 = implode('|', $les_mois); |
$etiquettes_x2 = implode('|', $annees); |
$etiquettes_y = 'Utilisateurs'; |
// Construire de l'url de l'image |
$graph = array('cht' => 'lc', |
'chtt' => $titre, |
'chs' => '600x200', |
'chco' => '0000FF',//4D89F9 |
'chd' => 't:'.$valeurs, |
'chds' => '0,'.$valeurs_max, |
'chxt' => 'y,y,x,x', |
'chxl' => '1:|'.$etiquettes_y.'|3:|'.$etiquettes_x2.'|2:|'.$etiquettes_x1.'', |
'chxp' => '1,50|3,0', |
'chxr' => "0,0,$y_val_fin,$y_pas", |
'chm' => 'h,C3C3C3,0,0.5,1,-1|N ** ,000000,0,2::2,8,1.0,ht', |
'chxs' => '0,0000FF|1,0000FF'); |
return $graph; |
} |
private function getEvolObsParMoisGlissant($param) { |
// Récupération des données |
$format_date = '%Y%m%d'; |
$where = 'date_creation > DATE_SUB(NOW(), INTERVAL 31 DAY)'; |
$obs_totale = $this->executerRequeteEvol('cel_obs', 'id_observation', $format_date, $where); |
// Tri des dates pour les étiquettes des axes |
$dates = array(); |
$annees = array(); |
$annees_mois = array(); |
$jours = array(); |
foreach ($obs_totale as $annee_mois_jours => $nbre) { |
$annee = substr($annee_mois_jours, 0, 4); |
$mois = substr($annee_mois_jours, 4, 2); |
$jour = substr($annee_mois_jours, 6, 2); |
$annee_mois_fmt_B = strftime('%B %Y', mktime(0, 0, 0, $mois, 1, $annee)); |
if (!isset($dates[$annee][$mois][$jour])) { |
$annees_mois[] = (!isset($dates[$annee][$mois]) ? $annee_mois_fmt_B : ''); |
$jours[] = $jour; |
// Ajouter au tableau dates tjrs à la fin |
$dates[$annee][$mois][$jour] = 1; |
} |
} |
// Post traitement des données |
$titre = 'Évolution des observations sur un mois glissant'; |
$valeurs_max = max($obs_totale); |
$valeurs = implode(',', $obs_totale); |
$y_val_fin = $valeurs_max; |
$y_pas = round($valeurs_max / 6); |
$etiquettes_x1 = implode('|', $jours); |
$etiquettes_x2 = implode('|', $annees_mois); |
$etiquettes_y2 = 'Observations'; |
// Construire de l'url de l'image |
$graph = array('cht' => 'lc', |
'chtt' => $titre, |
'chs' => '600x200', |
'chco' => '822013', |
'chd' => 't:'.$valeurs, |
'chds' => '0,'.$valeurs_max, |
'chxt' => 'y,y,x,x', |
'chxl' => '1:|'.$etiquettes_y2.'|2:|'.$etiquettes_x1.'|3:|'.$etiquettes_x2, |
'chxp' => '0,0|1,50', |
'chxr' => "0,0,$y_val_fin,$y_pas", |
'chm' => 'h,C3C3C3,0,0.5,1,-1|N,000000,0,1::1,8,1.0,ht', |
'chxs' => '0,822013|1,822013'); |
return $graph; |
} |
private function getEvolObsParMois($param) { |
// Récupération des données |
$obs_totale = $this->executerRequeteEvol('cel_obs', 'id_observation'); |
// Trie des dates pour les étiquettes des axes |
$dates = array(); |
$annees = array(); |
$les_mois = array(); |
$pas = 3; // intervalle de mois entre deux étiquettes |
$periode = 0; |
$cumul = 0; |
$obs_totale_cumul = array(); |
foreach ($obs_totale as $annee_mois => $nbre) { |
$annee = substr($annee_mois, 0, 4); |
$mois = substr($annee_mois, 4, 2); |
$mois_fmt_B = strftime('%b', strtotime("0000-$mois-01")); |
$cumul += $nbre; |
$obs_totale_cumul[$annee_mois] = $cumul; |
if (!isset($dates[$annee][$mois])) { |
$annees[] = (!isset($dates[$annee]) ? $annee : ''); |
$les_mois[] = is_int($periode++ / $pas) ? $mois_fmt_B : ''; |
// Ajouter au tableau dates tjrs à la fin |
$dates[$annee][$mois] = 1; |
} |
} |
// Post traitement des données |
$titre = 'Évolution des observations par mois'; |
$valeurs_y = implode(',', $obs_totale); |
$valeurs_r = implode(',', $obs_totale_cumul); |
$valeurs_max_y = max($obs_totale); |
$valeurs_max_r = max($obs_totale_cumul); |
$y_val_fin = $valeurs_max_y; |
$y_pas = round(($valeurs_max_y / 6), 0); |
$r_val_fin = $valeurs_max_r; |
$r_pas = round(($valeurs_max_r / 6), 0); |
$etiquettes_x1 = implode('|', $les_mois); |
$etiquettes_x2 = implode('|', $annees); |
$etiquettes_y2 = 'Observations'; |
$etiquettes_r2 = 'Cumul obs.'; |
// Construire de l'url de l'image |
$graph = array('cht' => 'lc', |
'chtt' => $titre, |
'chs' => '600x200', |
'chco' => '822013,F1841D', |
'chd' => 't:'.$valeurs_y.'|'.$valeurs_r, |
'chds' => "0,$valeurs_max_y,0,$valeurs_max_r", |
'chxt' => 'y,y,x,x,r,r', |
'chxl' => '1:|'.$etiquettes_y2.'|2:|'.$etiquettes_x1.'|3:|'.$etiquettes_x2.'|5:|'.$etiquettes_r2.'', |
'chxp' => '1,50|3,0|5,50', |
'chxr' => "0,0,$y_val_fin,$y_pas|4,0,$r_val_fin,$r_pas", |
'chm' => 'N ** ,000000,0,2::2,8,1.0,ht', |
'chxs' => '0,822013|1,822013|4,F1841D|5,F1841D'); |
return $graph; |
} |
private function getEvolObsParAn($param) { |
// Récupération des données |
$obs_totale = $this->executerRequeteEvol('cel_obs', 'id_observation', '%Y'); |
// Trie des dates pour les étiquettes des axes |
$dates = array(); |
$annees = array(); |
foreach ($obs_totale as $annee => $nbre) { |
if (!isset($dates[$annee])) { |
$annees[] = $annee; |
$dates[$annee] = 1; |
} |
} |
// Post traitement des données |
$titre = 'Évolution des observations par année'; |
$valeurs = implode(',', $obs_totale); |
$valeurs_max = max($obs_totale); |
$valeurs_min = min($obs_totale); |
$y_val_deb = preg_replace('/[0-9]{2}$/', '00', $valeurs_min); |
$y_val_fin = $valeurs_max; |
$y_pas = round(($valeurs_max / 6), 0); |
$etiquettes_x = implode('|', $annees);; |
$etiquettes_y = 'Observations'; |
// Construire de l'url de l'image |
$graph = array('cht' => 'lc', |
'chtt' => $titre, |
'chs' => '600x200', |
'chco' => '822013', |
'chd' => 't:'.$valeurs, |
'chds' => "$valeurs_min,$valeurs_max", |
'chxt' => 'y,y,x', |
'chxl' => '1:|'.$etiquettes_y.'|2:|'.$etiquettes_x.'', |
'chxp' => '0,0|1,50|2,0', |
'chxr' => "0,$y_val_deb,$y_val_fin,$y_pas", |
'chm' => 'h,C3C3C3,0,0.5,1,-1|N,000000,0,1::1,8,1.0,ht', |
'chxs' => '0,822013|1,822013'); |
return $graph; |
} |
private function getEvolObsHisto($param) { |
// Récupération des données |
$obs_totale = $this->executerRequeteEvol('cel_obs', 'id_observation'); |
$obs_identifiee = $this->executerRequeteEvol('cel_obs', 'id_observation', "courriel_utilisateur LIKE '%@%' "); |
$lignes = array('total', 'obs. identifiée'); |
// Post traitement des données |
$titre = 'Évolution des observations'; |
$valeurs = implode(',', $obs_totale).'|'.implode(',', $obs_identifiee); |
$valeurs_max = max($obs_totale); |
$etiquettes = implode('|', array_keys($lignes)); |
// Construire de l'url de l'image |
$graph = array('cht' => 'lc', |
'chtt' => $titre, |
'chs' => '500x300', |
'chco' => 'FF0000,00FF00', |
'chd' => 't:'.$valeurs, |
'chds' => "0,$valeurs_max", |
'chxt' => 'y', |
'chxl' => '0:|'.$etiquettes.'', |
'chm' => 'N,000000,0,-1,10'); |
return $graph; |
} |
private function getNbreObsIdVsTest($param) { |
// Récupération des données |
$obs_totale = $this->executerRequeteNombre('cel_obs', 'id_observation'); |
$obs_identifiee = $this->executerRequeteNombre('cel_obs', 'id_observation', "courriel_utilisateur LIKE '%@%' "); |
$obs_test = $obs_totale - $obs_identifiee; |
$pourcent_identifiee = round(($obs_identifiee / ($obs_totale / 100)), 2).'%'; |
$pourcent_anonyme = round(($obs_test / ($obs_totale / 100)), 2).'%'; |
// Post traitement des données de la base de données |
$titre = "Nombre d'observations|tests vs. identifiées"; |
$etiquette_obs_test = "tests ($obs_test - $pourcent_anonyme)"; |
$etiquette_obs_id = "identifiées ($obs_identifiee - $pourcent_identifiee)"; |
$donnees = array($etiquette_obs_test => $obs_test, $etiquette_obs_id => $obs_identifiee); |
$valeurs = implode(',', $donnees); |
$etiquettes = implode('|', array_keys($donnees)); |
// Construire les paramêtres de l'url de l'image |
$graph = array('cht' => 'p3', |
'chtt' => $titre, |
'chs' => '250x200', |
'chco' => 'FF0000,00FF00', |
'chd' => 't:'.$valeurs, |
'chds' => "0,$obs_totale", |
'chdl' => $etiquettes, |
'chdlp' => 'bv|r', |
'chts' => '000000,12'); |
return $graph; |
} |
private function getNbreObsPublicVsPrivee($param) { |
// Récupération des données |
$obs_totale = $this->executerRequeteNombre('cel_obs', 'id_observation'); |
$obs_public = $this->executerRequeteNombre('cel_obs', 'id_observation', 'transmission = 1'); |
$obs_privee = $obs_totale - $obs_public; |
$pourcent_privee = round(($obs_privee / ($obs_totale / 100)), 2).'%'; |
$pourcent_public = round(($obs_public / ($obs_totale / 100)), 2).'%'; |
// Post traitement des données de la base de données |
$titre = "Nombre d'observations|publiques vs. privées"; |
$etiquette_obs_public = "publiques ($obs_public - $pourcent_public)"; |
$etiquette_obs_privee = "privées ($obs_privee - $pourcent_privee)"; |
$donnees = array($etiquette_obs_privee => $obs_privee, $etiquette_obs_public => $obs_public); |
$valeurs = implode(',', $donnees); |
$etiquettes = implode('|', array_keys($donnees)); |
// Construire les paramêtres du graph |
$graph = array('cht' => 'p3', |
'chtt' => $titre, |
'chs' => '250x200', |
'chco' => 'FF0000,00FF00', |
'chd' => 't:'.$valeurs, |
'chds' => "0,$obs_totale", |
'chdl' => $etiquettes, |
'chdlp' => 'bv|r', |
'chts' => '000000,12'); |
return $graph; |
} |
private function getNbreObsDetermineeVsInconnue($param) { |
// Récupération des données |
$obs_totale = $this->executerRequeteNombre('cel_obs', 'id_observation'); |
$obs_determinee = $this->executerRequeteNombre('cel_obs', 'id_observation', 'nom_sel_nn != 0'); |
$obs_inconnue = $obs_totale - $obs_determinee; |
$pourcent_determinee = round(($obs_determinee / ($obs_totale / 100)), 2).'%'; |
$pourcent_inconnue = round(($obs_inconnue / ($obs_totale / 100)), 2).'%'; |
// Post traitement des données de la base de données |
$titre = "Nombre d'observations|determinées vs. inconnues"; |
$etiquette_obs_determinee = "determinées ($obs_determinee - $pourcent_determinee)"; |
$etiquette_obs_inconnue = "non déterminées ($obs_inconnue - $pourcent_inconnue)"; |
$donnees = array($etiquette_obs_inconnue => $obs_inconnue, $etiquette_obs_determinee => $obs_determinee); |
$valeurs = implode(',', $donnees); |
$etiquettes = implode('|', array_keys($donnees)); |
// Construire les paramêtres du graph |
$graph = array('cht' => 'p3', |
'chtt' => $titre, |
'chs' => '250x200', |
'chco' => 'FF0000,00FF00', |
'chd' => 't:'.$valeurs, |
'chds' => "0,$obs_totale", |
'chdl' => $etiquettes, |
'chdlp' => 'bv|r', |
'chts' => '000000,12'); |
return $graph; |
} |
private function getNbreObsAvecIndicationGeo($param) { |
// Récupération des données |
$total = $this->executerRequeteNombre('cel_obs', 'id_observation'); |
$where_commune = $this->creerWhereIndicationGeo('zone_geo'); |
$obs['commune'] = $this->executerRequeteNombre('cel_obs', 'id_observation', $where_commune); |
$where_commune_id = $this->creerWhereIndicationGeo('ce_zone_geo'); |
$obs['commune identifiée'] = $this->executerRequeteNombre('cel_obs', 'id_observation', $where_commune_id); |
$where_lieudit = $this->creerWhereIndicationGeo('lieudit'); |
$obs['lieu-dit'] = $this->executerRequeteNombre('cel_obs', 'id_observation', $where_lieudit); |
$where_station = $this->creerWhereIndicationGeo('station'); |
$obs['station'] = $this->executerRequeteNombre('cel_obs', 'id_observation', $where_station); |
$where_milieu = $this->creerWhereIndicationGeo('milieu'); |
$obs['milieu'] = $this->executerRequeteNombre('cel_obs', 'id_observation', $where_milieu); |
$where_xy = $this->creerWhereIndicationGeo('latitude').' AND '.$this->creerWhereIndicationGeo('longitude'); |
$obs['coordonnée'] = $this->executerRequeteNombre('cel_obs', 'id_observation', $where_xy); |
$donnees = array(); |
$num = 1; |
foreach ($obs as $etiquette => $nbre) { |
$pourcent = round(($obs[$etiquette] / ($total / 100)), 1).'%'; |
$legende = "$num : $etiquette ($nbre - $pourcent)"; |
$donnees['valeurs'][] = $nbre; |
$donnees['etiquettes'][] = $num++; |
$donnees['legendes'][] = $legende; |
} |
// Post traitement des données de la base de données |
$titre = "Nombre d'observations|avec indications géographiques"; |
$valeurs = implode(',', $donnees['valeurs']); |
$etiquettes = implode('|', $donnees['etiquettes']); |
$legendes = implode('|', $donnees['legendes']); |
// Construire les paramêtres du graph |
$graph = array('cht' => 'rs', |
'chtt' => $titre, |
'chs' => '600x300', |
'chco' => 'FFFFFF', |
'chd' => 't:'.$valeurs, |
'chds' => "0,$total", |
'chdl' => $legendes, |
'chxt' => 'x', |
'chxl' => "0:|$etiquettes", |
//'chxp' => '1,0,20,40,60,80,100',// Grille sous forme de cible |
'chm' => 'B,FF000080,0,1.0,5.0'); |
return $graph; |
} |
private function creerWhereIndicationGeo($champ) { |
$where = null; |
if (isset($champ)) { |
$where = "$champ != '000null' ". |
"AND $champ != '' ". |
"AND $champ IS NOT NULL "; |
} |
return $where; |
} |
private function getUtilisationJournaliere($param) { |
// Sur quel jour, voulons nous estimer l'utilisation |
$aujourdhui = date('Y-m-d'); |
if (isset($param[0]) && preg_match('/^[0-9]{4}(?:-[0-9]{2}){2}$/', $param[0])) { |
$aujourdhui = $param[0]; |
} |
$aujourdhui_fmt = strftime('%d %b %Y', strtotime($aujourdhui)); |
// Récupération des données |
$max_obs = array(); |
$max_obs[] = $this->executerRequeteEvol('cel_obs', 'id_observation', '%Y%m%d', |
"date_creation NOT LIKE '$aujourdhui%' ", 'date_creation'); |
$max_obs[] = $this->executerRequeteEvol('cel_obs', 'id_observation', '%Y%m%d', |
"date_modification NOT LIKE '$aujourdhui%' ", 'date_modification'); |
$max_obs[] = $this->executerRequeteEvol('cel_obs', 'id_observation', '%Y%m%d', |
"date_transmission NOT LIKE '$aujourdhui%' ", 'date_transmission'); |
$obs_aujourdhui = $this->executerRequeteNombre('cel_obs', 'id_observation', |
"(date_creation LIKE '$aujourdhui%' |
OR date_modification LIKE '$aujourdhui%' |
OR date_transmission LIKE '$aujourdhui%') "); |
// Cummul des obs crées, modifiées, transmises par jour |
$donnees = array(); |
foreach ($max_obs as $obs_par_jour) { |
foreach ($obs_par_jour as $annee_mois_jour => $nbre) { |
if (!isset($donnees[$annee_mois_jour])) { |
$donnees[$annee_mois_jour] = $nbre; |
} else { |
$donnees[$annee_mois_jour] += $nbre; |
} |
} |
} |
// Post traitement des données |
$valeur = $obs_aujourdhui; |
$valeur_max = 400; |
if ($valeur > $valeur_max) { |
$pourcentage = 100; |
} else { |
$pourcentage = round(($valeur / ($valeur_max / 100)), 0); |
} |
$etiquettes_x = $aujourdhui_fmt; |
$etiquettes_y = "faible|moyenne|forte"; |
$titre = "Intensité d'utilisation pour le $aujourdhui_fmt"; |
$legende = "$valeur changements"; |
// Construire de l'url de l'image |
$graph = array('cht' => 'gom', |
'chtt' => $titre, |
'chdl' => "$legende", |
'chdlp' => 'b', |
'chs' => '350x200', |
'chco' => 'FFFF00,0A7318', |
'chls' => '3|10', |
'chma' => '0,0,0,0|300,40', |
'chd' => 't:'.$pourcentage, |
'chxt' => 'x,y', |
'chxl' => '0:|'.$etiquettes_x.'|1:|'.$etiquettes_y.'', |
'chxp' => '0,50'); |
return $graph; |
} |
private function getNbreObsParUtilisateur($param) { |
// Récupération des données |
$requete = 'SELECT courriel_utilisateur, COUNT(id_observation) AS nbre '. |
'FROM cel_obs '. |
'GROUP BY courriel_utilisateur '; |
$utilisateurs = $this->executerRequete($requete); |
// Création des classes d'utilisateurs |
$classes = array('00->10' => 0, '11->50' => 0, '51->100' => 0, '101->500' => 0, '500->∞' => 0); |
$donnees['Utilisateurs'] = $classes; |
$valeur_max = 0; |
foreach ($utilisateurs as $utilisateur) { |
$id = $utilisateur['courriel_utilisateur']; |
$nbre = $utilisateur['nbre']; |
// Détermination de la classe |
$classe = ''; |
if (0 < $nbre && $nbre <= 10) { |
$classe = '00->10'; |
} else if (10 < $nbre && $nbre <= 50) { |
$classe = '11->50'; |
} else if (50 < $nbre && $nbre <= 100) { |
$classe = '51->100'; |
} else if (100 < $nbre && $nbre <= 500) { |
$classe = '101->500'; |
} else if (500 < $nbre) { |
$classe = '500->∞'; |
} |
// Détermination du type d'utilisateur |
if (strstr($id, '@')) { |
$type = 'Utilisateurs'; |
// Incrémentation du tableau de données et récupration de la valeur max |
$donnees[$type][$classe]++; |
if ($donnees[$type][$classe] > $valeur_max) { |
$valeur_max = $donnees[$type][$classe]; |
} |
} |
} |
// Post traitement des données |
$titre = "Nombre d'observations par utilisateur"; |
$y1_val_fin = $valeur_max; |
$y1_pas = '100'; |
$valeurs = implode(',', $donnees['Utilisateurs']); |
$etiquettes_x1 = implode('|', array_keys($classes)); |
$etiquettes_x2 = 'Observations'; |
$etiquettes_y2 = 'Utilisateurs'; |
$legendes = implode('|', array_keys($donnees)); |
// Construire de l'url de l'image |
$graph = array('cht' => 'bvg', |
'chtt' => $titre, |
'chs' => '400x200', |
'chco' => '00FF00,FF0000', |
'chbh' => 'r,0.3,1', |
'chd' => 't:'.$valeurs, |
'chds' => "0,$valeur_max", |
'chxt' => 'x,x,y,y', |
'chxl' => '0:|'.$etiquettes_x1.'|1:|'.$etiquettes_x2.'|3:|'.$etiquettes_y2.'', |
'chxp' => '1,100|3,100', |
'chxr' => "2,0,$y1_val_fin,$y1_pas", |
'chm' => 'h,C3C3C3,0,0.5,1,-1|N,000000,0,0::1,8,1.0,e'); |
//echo '<pre>'.print_r($graph,true).'</pre>'; |
return $graph; |
} |
private function getNbreObsParUtilisateurEtTest($param) { |
// Récupération des données |
$requete = 'SELECT courriel_utilisateur, COUNT(id_observation) AS nbre '. |
'FROM cel_obs '. |
'GROUP BY courriel_utilisateur '; |
$utilisateurs = $this->executerRequete($requete); |
// Création des classes d'utilisateurs |
$classes = array('00->10' => 0, '11->50' => 0, '51->100' => 0, '101->500' => 0, '500->∞' => 0); |
$donnees['Utilisateurs'] = $classes; |
$donnees['Tests'] = $classes; |
$valeur_max = 0; |
foreach ($utilisateurs as $utilisateur) { |
$id = $utilisateur['courriel_utilisateur']; |
$nbre = $utilisateur['nbre']; |
// Détermination de la classe |
$classe = ''; |
if (0 < $nbre && $nbre <= 10) { |
$classe = '00->10'; |
} else if (10 < $nbre && $nbre <= 50) { |
$classe = '11->50'; |
} else if (50 < $nbre && $nbre <= 100) { |
$classe = '51->100'; |
} else if (100 < $nbre && $nbre <= 500) { |
$classe = '101->500'; |
} else if (500 < $nbre) { |
$classe = '500->∞'; |
} |
// Détermination du type d'utilisateur |
if (strstr($id, '@')) { |
$type = 'Utilisateurs'; |
} else { |
$type = 'Tests'; |
} |
// Incrémentation du tableau de données et récupration de la valeur max |
$donnees[$type][$classe]++; |
if ($donnees[$type][$classe] > $valeur_max) { |
$valeur_max = $donnees[$type][$classe]; |
} |
} |
// Post traitement des données |
$titre = "Nombre d'observations par utilisateur et test"; |
$y1_val_fin = $valeur_max; |
$y1_pas = '100'; |
$valeurs = implode(',', $donnees['Utilisateurs']).'|'.implode(',', $donnees['Tests']); |
$etiquettes_x1 = implode('|', array_keys($classes)); |
$etiquettes_x2 = 'Observations'; |
$etiquettes_y2 = 'Utilisateurs'; |
$legendes = implode('|', array_keys($donnees)); |
// Construire de l'url de l'image |
$graph = array('cht' => 'bvg', |
'chtt' => $titre, |
'chs' => '400x200', |
'chco' => '00FF00,FF0000', |
'chbh' => 'r,0.3,1', |
'chd' => 't:'.$valeurs, |
'chds' => "0,$valeur_max", |
'chxt' => 'x,x,y,y', |
'chxl' => '0:|'.$etiquettes_x1.'|1:|'.$etiquettes_x2.'|3:|'.$etiquettes_y2.'', |
'chxp' => '1,100|3,100', |
'chxr' => "2,0,$y1_val_fin,$y1_pas", |
'chm' => 'h,C3C3C3,0,0.5,1,-1|N,000000,0,0::1,8,1.0,e|N,000000,1,0::1,8,1.0,e', |
'chdl' => $legendes, |
'chdlp' => 'b'); |
//echo '<pre>'.print_r($graph,true).'</pre>'; |
return $graph; |
} |
private function getNuagePointsObsParHeureEtJourSemaine($param) { |
$utilisateur = isset($_GET['utilisateur']) ? $this->bdd->quote($_GET['utilisateur']) : false; |
// Récupération des données de la base |
$requete = 'SELECT courriel_utilisateur, DATE_FORMAT(date_creation, "%w-%H") AS periode, (ROUND(LOG10(COUNT(id_observation))) + 1) AS nbre '. |
'FROM cel_obs '. |
'WHERE date_creation != "0000-00-00 00:00:00" '. |
' AND courriel_utilisateur '.($utilisateur ? "= $utilisateur " : 'LIKE "%@%" '). |
'GROUP BY periode, courriel_utilisateur '; |
$infos = $this->executerRequete($requete); |
// Traitement résulat requête |
$observations = array(); |
foreach ($infos as $info) { |
if (isset($observations[$info['periode']])) { |
$observations[$info['periode']] += $info['nbre']; |
} else { |
$observations[$info['periode']] = $info['nbre']; |
} |
} |
// Postraitement des données |
// Jour de la semaine |
$donnees['joursSemaine'] = array(); |
for ($njs = 0; $njs < 7; $njs++) { |
$donnees['joursSemaine'][] = strftime('%A', strtotime('2010-05-'.(16+$njs))); |
} |
// Heure |
$donnees['heures'] = array(); |
for ($h = 0; $h < 24; $h++) { |
$heure_fmt = sprintf('%02s', $h);// Format numérique 00 |
$donnees['heures'][] = strftime('%H', strtotime("0000-00-00 $heure_fmt:00:00")); |
} |
// Nbre |
$valeur_max = max($observations); |
for ($njs = 0; $njs < 7; $njs++) { |
for ($h = 0; $h < 24; $h++) { |
$hfmt = sprintf('%02s', $h);// Format numérique 00 |
$periode = $njs.'-'.$hfmt; |
$donnees['valeurs_x'][] = round(($h + 1) * (100 / 24), 0); |
$donnees['valeurs_y'][] = round(($njs + 1) * (100 / 7), 0); |
$ps = 0; |
if (isset($observations[$periode])) { |
$ps = round($observations[$periode] * (100 / $valeur_max), 0); |
} |
$donnees['valeurs_ps'][] = $ps; |
} |
} |
//echo '<pre>'.print_r($donnees,true).'</pre>'; |
// Préparation des paramêtres du graph |
$titre = "Nombre de création d'observation|par heure et jour de la semaine"; |
$valeurs = implode(',', $donnees['valeurs_x'])."|".implode(',', $donnees['valeurs_y'])."|".implode(',', $donnees['valeurs_ps']); |
$etiquettes_x1 = '|'.implode('|', $donnees['heures']); |
$etiquettes_x2 = 'Heures'; |
$etiquettes_y1 = '|'.implode('|', $donnees['joursSemaine']); |
$x_axis_step_size = str_replace(',', '.', (100 / 24)); |
$y_axis_step_size = str_replace(',', '.', (100 / 7)); |
// Construction du tableau des paramêtres du graph |
$graph = array('cht' => 's', |
'chtt' => $titre, |
'chs' => '400x200', |
'chco' => '00FF00', |
'chd' => 't:'.$valeurs, |
'chxt' => 'x,x,y', |
'chxr' => "0,-1,23,1|2,-1,6,1", |
'chxp' => '1,100', |
'chxl' => '0:|'.$etiquettes_x1.'|1:|'.$etiquettes_x2.'|2:|'.$etiquettes_y1.'', |
'chg' => "$x_axis_step_size,$y_axis_step_size,1,5"); |
//echo '<pre>'.print_r($graph,true).'</pre>'; |
return $graph; |
} |
private function getNuagePointsObsAnciennete($param) { |
// Récupération des données de la base |
$requete = 'SELECT DISTINCT courriel_utilisateur , '. |
' MIN(date_creation) AS date_min, MAX(date_creation) AS date_max, '. |
' COUNT(id_observation) AS obs_nbre '. |
'FROM cel_obs '. |
"WHERE date_creation != '0000-00-00 00:00:00' ". |
" AND courriel_utilisateur LIKE '%@%' ". |
'GROUP BY courriel_utilisateur '. |
'ORDER BY date_min ASC '; |
$resultats = $this->executerRequete($requete); |
// Trie des données |
$max_obs = 0; |
$max_obs_log = 0; |
$max_anciennete = 0; |
$donnees = array(); |
foreach ($resultats as $enrg) { |
$tps_deb = strtotime($enrg['date_min']); |
$tps_fin = strtotime($enrg['date_max']); |
$donnee = array(); |
if (($tps_fin - $tps_deb) == 0) { |
$donnee['anciennete'] = 1; |
} else { |
$donnee['anciennete'] = round((($tps_fin - $tps_deb) / 86400), 0); |
} |
$donnee['obs'] = $enrg['obs_nbre']; |
$donnee['obs_log'] = log10($enrg['obs_nbre']); |
$donnees[] = $donnee; |
$max_obs_log = ($donnee['obs_log'] > $max_obs_log) ? $donnee['obs_log'] : $max_obs_log; |
$max_obs = ($donnee['obs'] > $max_obs) ? $donnee['obs'] : $max_obs; |
$max_anciennete = ($donnee['anciennete'] > $max_anciennete) ? $donnee['anciennete'] : $max_anciennete; |
} |
// Postraitement des données |
foreach ($donnees as $donnee) { |
$donnees['valeurs_x'][] = round($donnee['anciennete'] * (100 / $max_anciennete), 0); |
$donnees['valeurs_y'][] = round($donnee['obs_log'] * (100 / $max_obs_log), 0); |
$donnees['valeurs_ps'][] = 20; |
} |
// Échelle log des obs |
$donnees['echelle_y1'] = array(); |
$pas = $max_obs_log / 100 ; |
for ($i = 0 ; $i < 5 ; $i++) { |
$donnees['echelle_y1'][] = round(pow(10, (($i*20) * $pas)), 0); |
} |
$donnees['echelle_y1'][] = $max_obs; |
//echo '<pre>'.print_r($donnees['valeurs_x'],true).'</pre>'; |
// Préparation des paramêtres du graph |
$titre = "Répartition des utilisateurs en fonction|du nombre d'observations et de l'ancienneté"; |
$valeurs = implode(',', $donnees['valeurs_x'])."|".implode(',', $donnees['valeurs_y'])."|".implode(',', $donnees['valeurs_ps']); |
$etiquettes_x2 = 'Ancienneté en jours'; |
$etiquettes_y1 = implode('|', $donnees['echelle_y1']); |
$etiquettes_y2 = 'Observations'; |
$x_axis_step_size = $max_anciennete; |
// Construction du tableau des paramêtres du graph |
$graph = array('cht' => 's', |
'chtt' => $titre, |
'chs' => '400x200', |
'chco' => '0000FF', |
'chxt' => 'x,x,y,y', |
'chd' => 't:'.$valeurs, |
'chxr' => "0,0,$x_axis_step_size|2,0,$max_obs",//|2,0,$y_axis_step_size,$pas |
'chxp' => '1,100|3,100', |
'chm' => 'h,C3C3C3,0,-0.2,0.2,-1', |
'chxl' => '1:|'.$etiquettes_x2.'|2:|'.$etiquettes_y1.'|3:|'.$etiquettes_y2.'');// |
//echo '<pre>'.print_r($graph,true).'</pre>'; |
return $graph; |
} |
private function executerRequeteEvol($table, $champ, $format_date = '%Y%m', $where = null, $champ_date = 'date_creation', $order_by = null, $limit = null) { |
$utilisateur = isset($_GET['utilisateur']) ? $this->bdd->quote($_GET['utilisateur']) : false; |
$requete = "SELECT DATE_FORMAT($champ_date, '$format_date') AS periode, COUNT($champ) AS nbre ". |
"FROM $table ". |
"WHERE $champ_date != '0000-00-00 00:00:00' ". |
(($utilisateur != false) ? " AND courriel_utilisateur = $utilisateur " : ''). |
((is_null($where)) ? '' : " AND $where "). |
'GROUP BY periode '. |
((is_null($order_by)) ? '' : "ORDER BY $order_by "); |
((is_null($limit)) ? '' : "LIMIT $limit "); |
$evolution = $this->executerRequete($requete); |
// Traitement du tableau |
$donnees_traitees = array(); |
foreach ($evolution as $info) { |
$donnees_traitees[$info['periode']] = $info['nbre']; |
} |
return $donnees_traitees; |
} |
private function executerRequeteNombre($table, $champ, $where = null) { |
$utilisateur = null; |
if (isset($_GET['utilisateur'])) { |
$utilisateur = $this->bdd->quote($_GET['utilisateur']); |
$where = isset($where) ? $where.' AND ' : ''; |
$where .= "courriel_utilisateur = $utilisateur "; |
} |
$requete = "SELECT COUNT($champ) AS nbre ". |
"FROM $table ". |
((isset($where)) ? "WHERE $where " : ''); |
$nbre = $this->executerRequete($requete, 'Column'); |
return $nbre; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryObservationList.php |
---|
New file |
0,0 → 1,123 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurelien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* InventoryObservationList.php |
* |
* in=utf8 |
* out=utf8 |
* |
* Cas d'utilisation : |
* 1: Service recherche d'observations a partir de divers critères |
* a: Le service recherche les observations correspondant aux critères demandés |
* b: Le service renvoie la liste des observations correspondantes |
* |
* 2: Service modification en masse d'observations |
* a: Le service recherche les observations correspondant aux identifiants donnés |
* b: Le service modifie les observations correspondantes avec les infos données en paramètres |
* |
* 3: Service de suppression d'observations en masse |
* a: Le service recherche les observations correspondant aux critères demandés |
* b: Le service supprime la liste des observations correspondantes |
*/ |
class InventoryObservationList extends Cel { |
/** |
* renvoie les observations correspondant au critères de filtrage |
* |
* uid[0] : utilisateur obligatoire |
* uid[1] : criteres de filtrage de la forme critere1=valeur1&critere2=valeur2 |
*/ |
function getElement($uid) |
{ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
$chercheur_observations = new RechercheObservation($this->config); |
$numero_page = 0; |
$taille_page = 50; |
$criteres = array(); |
$criteres = $_GET ; |
if (isset($criteres['numero_page']) && isset($criteres['limite'])) { |
$numero_page = $criteres['numero_page']; |
unset($criteres['numero_page']); |
$taille_page = $criteres['limite']; |
unset($criteres['limite']); |
} |
$debut = $taille_page*$numero_page ; |
$retour = $chercheur_observations->rechercherObservations($uid[0], $criteres, $debut, $taille_page); |
$retour_formate = $chercheur_observations->formaterPourEnvoiCel(&$retour); |
$this->envoyerJson($retour_formate); |
return true; |
} |
/** |
* met à jour les métadonnées d'une liste d'observations |
* |
* uid[0] : utilisateur obligatoire |
* uid[1] : ordres des observations à modifier séparés par des virgules |
* pairs : données à mettre à jour sous la forme de clés => valeurs |
*/ |
function updateElement($uid,$pairs) { |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if (!isset($uid[1])) { |
//TODO: envoyer un message d'erreur |
return; |
} |
$uid[1] = rtrim($uid[1],','); |
$gestionnaire_observation = new GestionObservation($this->config); |
$modification_observation = $gestionnaire_observation->modifierObservation($uid[0],$uid[1],$pairs); |
return true; |
} |
/** |
* Supprime une liste d'observations |
* |
* uid[0] : utilisateur obligatoire |
* uid[1] : ordres des observations à supprimer séparés par des virgules |
*/ |
function deleteElement($uid) |
{ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if (!isset($uid[1])) { |
//TODO: envoyer un message d'erreur |
return; |
} |
$uid[1] = rtrim($uid[1],','); |
$gestionnaire_observation = new GestionObservation($this->config); |
$modification_observation = $gestionnaire_observation->supprimerObservation($uid[0],$uid[1]); |
if ($modification_observation) { |
echo "OK"; |
} |
exit() ; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryByDept.php |
---|
New file |
0,0 → 1,146 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <delon@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/ |
*/ |
/** |
* |
* in=utf8 |
* out=iso3859 |
* |
* Liste des Nouvelles observations par departement |
* A voir avec David mais ne devrait plus être utilisé |
* ou fait autrement |
* |
*/ |
class InventoryByDept extends Cel { |
var $extendSpreadsheetProductor; |
function InventoryByDept($config) { |
parent::__construct($config); |
// Pas d'heritage multiple en php :( |
$this->extendSpreadsheetProductor = new SpreadsheetProductor(); |
$this->extendSpreadsheetProductor->initSpreadsheet(); |
} |
//TODO : faire une fonction qui prend en paramètre un departement |
function getRessource(){ |
$requete_obs = "SELECT ce_zone_geo, ce_utilisateur, courriel_utilisateur, ordre, nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, nt, famille, zone_geo, date_observation," . |
" lieudit, station, milieu, commentaire, transmission FROM cel_obs ". |
"WHERE ce_zone_geo != '000null' AND ce_zone_geo != '' AND transmission = 1 AND nt!=0 ORDER BY ce_zone_geo, nom_ret LIMIT 50"; |
$resultat_obs = $this->executerRequete($requete_obs); |
// Creating a workbook |
$workbook = new Spreadsheet_Excel_Writer(); |
// Creating a worksheet |
$worksheet = $workbook->addWorksheet('Liste'); |
$worksheet->write(0,0,'Departement'); |
$worksheet->write(0,1,'Nom saisi'); |
$worksheet->write(0,2,'Numero nomenclatural'); |
$worksheet->write(0,3,'Nom retenu'); |
$worksheet->write(0,4,'Numero nomenclatural nom retenu'); |
$worksheet->write(0,5,'Numero taxonomique'); |
$worksheet->write(0,6,'Famille'); |
$worksheet->write(0,7,'Commune'); |
$worksheet->write(0,8,'Date Observation'); |
$worksheet->write(0,9,'Lieu dit'); |
$worksheet->write(0,10,'Station'); |
$worksheet->write(0,11,'Milieu'); |
$worksheet->write(0,12,'Commentaire'); |
$worksheet->write(0,13,'Observateur'); |
$i=1; |
$observations = array(); |
$chercheur_infos_taxon = null; |
if (is_array($resultat_obs)) { |
$observations = &$resultat_obs; |
$chercheur_infos_taxon = new RechercheInfosTaxonBeta($this->config); |
} |
foreach ($observations as $obs) { |
$code_departement = $this->convertirCodeZoneGeoVersDepartement($obs['ce_zone_geo']); |
$taxon_deja_vu = $chercheur_infos_taxon->taxonEstPresentDansDepartement($obs['nt'], $code_departement); |
if (!$taxon_deja_vu) { |
// Denullifiage |
foreach($obs as $k=>$v) { |
if (($v=="null") || ($v=="000null")) { |
$obs[$k]=""; |
} |
else { |
$obs[$k]=utf8_decode($v); |
} |
} |
if ($obs['date_observation']!="0000-00-00 00:00:00") { |
list($year,$month,$day)= explode('-',$obs['date_observation']); |
list($day)= explode(' ',$day); |
$obs['date_observation']=$day."/".$month."/".$year; |
} |
else { |
$obs['date_observation']="00/00/0000"; |
} |
$worksheet->write($i,0,$code_departement); |
$worksheet->write($i,1,$obs['nom_sel']); |
$worksheet->write($i,2,$obs['nom_sel_nn']); |
$worksheet->write($i,3,$obs['nom_ret']); |
$worksheet->write($i,4,$obs['nom_ret_nn']); |
$worksheet->write($i,5,$obs['nt']); |
$worksheet->write($i,6,$obs['famille']); |
$worksheet->write($i,7,$obs['zone_geo']); |
$worksheet->write($i,8,$obs['date_observation']); |
$worksheet->write($i,9,$obs['lieudit']); |
$worksheet->write($i,10,$obs['station']); |
$worksheet->write($i,11,$obs['milieu']); |
$worksheet->write($i,12,$obs['commentaire']); |
$worksheet->write($i,13,$obs['courriel_utilisateur']); |
$i++; |
} |
} |
// sending HTTP headers |
$workbook->send('liste.xls'); |
$workbook->close(); |
exit(); |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.1 2008-11-13 11:29:12 ddelon |
* Reecriture gwt-ext |
* |
* Revision 1.2 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.1 2007-06-06 13:31:16 ddelon |
* v0.09 |
* |
* Revision 1.3 2007-05-22 12:54:09 ddelon |
* Securisation acces utilisateur |
* |
* |
* |
*/ |
?> |
/branches/v1.6-croc/jrest/services/squelettes/doublon_defaut.tpl.html |
---|
New file |
0,0 → 1,52 |
<!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"> |
<head> |
<title>Images en doublon - <?=$utilisateur?></title> |
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> |
<style type="text/css"> |
html, body{ |
margin:0; |
padding:0; |
height: 100%; |
font-family: Arial; |
font-size: 12px; |
} |
ul{ |
list-style-type:none; |
} |
.doublon{ |
float:left; |
} |
.doublon-liste{ |
clear:left; |
} |
</style> |
<!-- JavaScript --> |
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/1.4.4/jquery-1.4.4.min.js"></script> |
<script type="text/javascript" src="http://www.tela-botanica.org/commun/jquery/lazyload/1.5.0/jquery.lazyload.mini.js"></script> |
<script type="text/javascript"> |
$(document).ready(function(){ |
$("img").lazyload(); |
}); |
</script> |
</head> |
<body> |
<h1><?=count($doublons)?> images en doublon - <?=$utilisateur?></h1> |
<ul> |
<?php foreach ($doublons as $doublon) : ?> |
<li class="doublon-liste"> |
<?php foreach ($doublon as $img) : ?> |
<ul class="doublon"> |
<li>Image : <?=$img['img_ordre']?></li> |
<li>Observation(s) : <?=implode(', ', $img['obs_ordre'])?></li> |
<li><img src="<?=$img['url']?>" alt="Id #<?=$img['img_id']?>"/></li> |
</ul> |
<?php endforeach; ?> |
</li> |
<?php endforeach; ?> |
</ul> |
</body> |
</html> |
/branches/v1.6-croc/jrest/services/squelettes/atom.tpl.xml |
---|
New file |
0,0 → 1,35 |
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";?> |
<feed xmlns="http://www.w3.org/2005/Atom"> |
<title><?=$titre?></title> |
<link href="<?=$lien_cel?>" rel="alternate" type="text/html" hreflang="fr" /> |
<link href="<?=$lien_service?>" rel="self" type="application/atom+xml"/> |
<updated><?=$date_maj_ATOM?></updated> |
<author> |
<name><?=$editeur?></name> |
</author> |
<id><?=$guid?></id> |
<rights>Copyright (c) <?=$annee_courante?>, <?=$editeur?></rights> |
<generator uri="<?=$lien_service?>" version="<?=$generateur_version?>"><?=$generateur?></generator> |
<?php if (isset($items)) : ?> |
<?php foreach ($items as $item) : ?> |
<entry> |
<id><?=$item['guid']?></id> |
<title><?=$item['titre']?></title> |
<? if (isset($item['lien'])) : ?> |
<link href="<?=$item['lien']?>"/> |
<? endif; ?> |
<updated><?=$item['date_maj_ATOM']?></updated> |
<author><name><?=$item['modifier_par']?></name></author> |
<content type="xhtml" xml:lang="fr"> |
<div xmlns="http://www.w3.org/1999/xhtml"> |
<?=$item['description'];?> |
</div> |
</content> |
</entry> |
<?php endforeach; ?> |
<?php endif; ?> |
</feed> |
/branches/v1.6-croc/jrest/services/squelettes/opml.tpl.xml |
---|
New file |
0,0 → 1,18 |
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";?> |
<opml version="1.0"> |
<head> |
<text/> |
</head> |
<body> |
<outline text="CEL"> |
<?php foreach ($liste_flux as $flux) : ?> |
<outline title="<?=$flux['titre']?>" |
description="<?=$flux['description']?>" |
htmlUrl="<?=$flux['url_html']?>" |
xmlUrl="<?=$flux['url_xml']?>" |
type="<?=$flux['type']?>" |
text="<?=$flux['texte']?>"/> |
<?php endforeach; ?> |
</outline> |
</body> |
</opml> |
/branches/v1.6-croc/jrest/services/squelettes/rss1.tpl.xml |
---|
New file |
0,0 → 1,45 |
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";?> |
<!DOCTYPE rdf:RDF [ |
<!ENTITY % HTMLlat1 PUBLIC |
"-//W3C//ENTITIES Latin 1 for XHTML//EN" |
"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"> |
%HTMLlat1; |
]> |
<rdf:RDF |
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
xmlns:dc="http://purl.org/dc/elements/1.1/" |
xmlns="http://purl.org/rss/1.0/"> |
<channel rdf:about="<?=$guid?>"> |
<title><?=$titre?></title> |
<link><?=$lien_cel?></link> |
<description><?=$description?></description> |
<dc:publisher><?=$editeur?></dc:publisher> |
<dc:date><?=$date_maj_W3C?></dc:date> |
<?php if (isset($items)) : ?> |
<items> |
<rdf:Seq> |
<?php foreach ($items as $item) : ?> |
<rdf:li resource="<?=$item['guid']?>" /> |
<?php endforeach; ?> |
</rdf:Seq> |
</items> |
<?php endif; ?> |
</channel> |
<?php if (isset($items)) : ?> |
<?php foreach ($items as $item) : ?> |
<item rdf:about="<?=$item['guid']?>"> |
<title><?=$item['titre']?></title> |
<link><?=(isset($item['lien'])) ? $item['lien'] : 'http://www.tela-botanica.org/'?></link> |
<description><?=$item['description_encodee']?></description> |
<dc:date><?=$item['date_maj_W3C']?></dc:date> |
</item> |
<?php endforeach; ?> |
<?php endif; ?> |
</rdf:RDF> |
/branches/v1.6-croc/jrest/services/squelettes/rss2.tpl.xml |
---|
New file |
0,0 → 1,25 |
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";?> |
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> |
<channel> |
<title><?=$titre?></title> |
<link><?=$lien_cel?></link> |
<atom:link href="<?=$lien_service?>" rel="self" type="application/rss+xml" /> |
<description><?=$description?></description> |
<?php if (isset($items)) : ?> |
<?php foreach ($items as $item) : ?> |
<item> |
<guid><?=$item['guid']?></guid> |
<title><?=$item['titre']?></title> |
<? if (isset($item['lien'])) : ?> |
<link><?=$item['lien']?></link> |
<? endif; ?> |
<description><?=$item['description_encodee']?></description> |
<category><?= $item['categorie'] ?></category> |
<pubDate><?=$item['date_maj_RSS']?></pubDate> |
</item> |
<?php endforeach; ?> |
<?php endif; ?> |
</channel> |
</rss> |
/branches/v1.6-croc/jrest/services/InventoryImportExcel.php |
---|
New file |
0,0 → 1,682 |
<?php |
// In : utf8 |
// Out : utf8 |
// TODO : doublons |
/** |
Octobre 2010 David Delon. |
Import d'observations dans le carnet en ligne à partir d'un fichier excel chargé par l'utilisateur |
et liaison d'images déjà chargee aux observations ainsi crées. |
Nom des colonnes imposé, mais présence de toutes les colonnes non obligatoires, ordre non imposé |
Aucune valeur dans les colonnes n'est obligatoire |
Pour une ligne donnée, si tous les champs vides on ne fait rien, ou si seul le champ image est présent. |
Si la seule différence entre deux lignes est la valeur de la colonne image, on considère que c'est la même observation à laquelle on associe plusieurs images. |
Si au moins deux lignes (ou plus) sont complètement identiques on prend en compte une seule ligne (les doublons sont éliminés). |
**/ |
// Nom des colonnes |
define('COMMUNE','commune'); // soit un nom de commune, soit un code INSEE (5 chiffres), ou "nom de commune (numero departement)" |
define('LIEUDIT','lieu-dit'); // Texte libre |
define('STATION','station'); // Texte libre |
define('MILIEU','milieu'); // Texte libre |
define('LATITUDE','latitude'); // En decimal systeme WGS84 |
define('LONGITUDE','longitude'); // En decimal systeme WGS84 |
define('NOTES','notes'); // Texte libre |
define('DATEOBS','date'); // date au format jj/mm/aaaa |
define('ESPECE','espece'); // texte libre, nom latin, ou code nomenclatural (format BDNFFnn999999) |
define('IMAGE','image'); // nom des fichiers images préalablement uploadés sur le CEL séparés par des "/" |
define('DEPARTEMENT','departement'); // Texte libre |
define('TRANSMETTRE','transmettre'); // "1" ou "oui", toute autre valeur (y compris vide) sera consideree comme "non"" |
// Resultat de l'analyse d'une ligne |
define('LIGNE_VIDE',1); // |
define('LIGNE_NORMALE',2); // |
define('LIGNE_IMAGE_SEULEMENT',3); // |
//TODO: refactoriser entièrement cette classe |
class InventoryImportExcel extends Cel { |
// Element constituant une observation |
var $format_observation=array(COMMUNE ,LIEUDIT ,STATION , DEPARTEMENT, MILIEU ,LATITUDE ,LONGITUDE ,NOTES ,DATEOBS ,ESPECE ,TRANSMETTRE, IMAGE ); |
// Encapsulation classe lecture fichier excel |
var $extendExcelReader; |
// Dernier numero d'ordre utilise |
var $dernier_ordre = 1; |
var $cpt_images_liees = 0; |
var $utilisateur = array(); |
var $chercheur_infos_taxon; |
/** |
Constructeur |
**/ |
function InventoryImportExcel($config) { |
parent::__construct($config); |
// Pas d'heritage multiple en php :( |
$this->extendExcelReader = new ExcelReader(); |
$this->extendExcelReader->initExcelReader(); |
$this->chercheur_infos_taxon = new RechercheInfosTaxonBeta($config); |
} |
/** |
Sur post |
**/ |
function createElement($pairs) { |
if(!isset($pairs['utilisateur']) || trim($pairs['utilisateur']) == '') { |
echo '0'; exit; |
} |
if(!isset($_SESSION)) {session_start();} |
$this->controleUtilisateur($pairs['utilisateur']); |
$this->utilisateur = $this->getInfosComplementairesUtilisateur($pairs['utilisateur']); |
foreach($_FILES as $file) { // C'est le plus simple |
$infos_fichier = $file ; |
} |
// Chargement tableau en memoire |
$data = new Spreadsheet_Excel_Reader($infos_fichier['tmp_name'], true); // false : pour menager la memoire. |
$arr = array(); |
$rowcount=$data->rowcount(0); |
$colcount=$data->colcount(0); |
if ($rowcount<=1) { // TODO : retour erreur |
print "Tableau vide"; |
exit; |
} |
// Chargement tableau |
for($row=1;$row<=$rowcount;$row++) |
for($col=1;$col<=$colcount;$col++) |
$arr[$col][$row] = $data->val($row,$col,0); // Attention, inversion voulue |
// 1 : Traitement intitules |
$line = array(); |
/* Les colonnes ne sont pas forcemment dans l'ordre : on les extrait pour traitement futur */ |
for($col=1;$col<=$colcount;$col++) { |
$colonne=strtolower($arr[$col][1]); |
$colonne=trim($colonne); |
$colonne=cp1252_to_utf8($colonne); |
$colonne=remove_accent($colonne); |
switch ($colonne) { // On ne garde que les colonnes que l'on souhaite traiter |
case COMMUNE: |
case LIEUDIT: |
case STATION: |
case MILIEU: |
case DEPARTEMENT: |
case LATITUDE: |
case LONGITUDE: |
case NOTES: |
case DATEOBS: |
case ESPECE: |
case TRANSMETTRE: |
case IMAGE: |
$selection=array_values($arr[$col]); |
array_shift($selection); // On ne garde pas la premiere ligne, qui contient les intitules |
$line[$colonne]=$selection; |
break; |
} |
} |
// 1 : Traitement lignes |
$cpt_obs=0; |
$cpt_img=0; |
/* Recherche dernier numero d'ordre utilise : pas de mise a jour concurente a priori */ |
$requete = "SELECT MAX(ordre) AS ordre FROM cel_obs WHERE ce_utilisateur = ".$this->proteger($pairs['utilisateur'])." "; |
$resultat = $this->requeter($requete); |
if(is_array($resultat) && count($resultat) > 0) { |
$this->dernier_ordre = $resultat[0]['ordre']; // 1 par defaut |
} |
for ($i=0;$i<=$rowcount-1;$i++) { |
// On saute les eventuelles lignes vides du debut et les lignes contenant des information sur image uniquement |
while ((in_array($retour_analyse=$this->analyserLigne($line,$i),array(LIGNE_IMAGE_SEULEMENT, LIGNE_VIDE))) && ($i<=$rowcount)) { |
if ($retour_analyse==LIGNE_IMAGE_SEULEMENT) { |
// image non rattachée à une observation |
} |
else { |
// ligne vide |
} |
$i++; |
} |
while (($this->analyserLigne($line,$i)==LIGNE_NORMALE) && ($i<=$rowcount)) { |
$id_obs = $this->traiterLigne($line,$i,$pairs['utilisateur']); |
if ($this->dernier_ordre > 0) { |
$cpt_obs++; // Compteur d'observations crees |
} |
$i++; |
// On saute les lignes vide ou on traite les lignes suivantes contenant des informations sur image seulement |
while ((in_array($retour_analyse=$this->analyserLigne($line,$i),array(LIGNE_IMAGE_SEULEMENT, LIGNE_VIDE))) && ($i<=$rowcount)) { |
if ($retour_analyse==LIGNE_IMAGE_SEULEMENT) { |
$this->traiterLigneComplement($line,$i,$pairs['utilisateur'],$id_obs); // images supplementaires |
} |
else { |
// print "vide"; |
} |
$i++; |
} |
} |
} |
$message = ''; |
if($this->cpt_images_liees > 0) { |
$message = $this->cpt_images_liees.' images liees pour '; |
} |
$message .= $cpt_obs; |
print $message; |
} |
function analyserLigne($line,$i) { |
$ligne_vide=true; |
$ligne_image_seulement=true; |
$ligne_normale=true; |
$ligne_identique_sauf_image = true; |
foreach ($this->format_observation as $colonne) { |
if($i < 1) { |
$ligne_identique_sauf_image = false; |
} else { |
if($colonne!= IMAGE && isset($line[$colonne]) && isset($line[$colonne][$i - 1]) && isset($line[$colonne][$i]) |
&& $line[$colonne][$i - 1] != $line[$colonne][$i] && $line[$colonne][$i] != '') { |
$ligne_identique_sauf_image = false; |
} |
} |
if (isset ($line[$colonne][$i]) && $line[$colonne][$i]!='') { |
if ($colonne!=IMAGE) { |
$ligne_image_seulement=false; |
$ligne_vide=false; |
} |
$ligne_vide=false; |
} |
} |
if ($ligne_vide) { |
return LIGNE_VIDE; |
} |
else { |
if ($ligne_image_seulement || $ligne_identique_sauf_image) { |
return LIGNE_IMAGE_SEULEMENT; |
} |
else { |
return LIGNE_NORMALE; |
} |
} |
} |
function traiterLigne($line,$i,$utilisateur) { |
// Controle donnee et insertion |
$info_image=array(); |
$info_transmettre = "0"; |
$info_espece = array( |
'nom_sel' => '', |
'nom_sel_nn' => '', |
'nom_ret' => '', |
'nom_ret_nn' => '', |
'nt' => '', |
'famille' => '' |
); |
$info_commune = array('nom' => '', 'code' => ''); |
foreach ($this->format_observation as $colonne) { |
if (isset ($line[$colonne][$i]) && $line[$colonne][$i]!='') { |
switch ($colonne) { // On ne garde que les colonnes que l'on souhaite traiter |
case COMMUNE: |
$info_commune = $this->traiterCommune($line[COMMUNE][$i]); |
break; |
case LIEUDIT: |
$info_lieudit = $this->traiterLieudit($line[LIEUDIT][$i]); |
break; |
case STATION: |
$info_station = $this->traiterStation($line[STATION][$i]); |
break; |
case MILIEU: |
$info_milieu = $this->traiterMilieu($line[MILIEU][$i]); |
break; |
case DEPARTEMENT: |
$dpt = $this->traiterDepartement($line[DEPARTEMENT][$i]); |
if(is_numeric($dpt) && strlen($dpt == 5) && $info_commune['code'] == 'NULL') { |
$info_commune['code'] = $dpt; |
} |
break; |
case LATITUDE: |
$info_latitude = $this->traiterLatitude($line[LATITUDE][$i]); |
break; |
case LONGITUDE: |
$info_longitude = $this->traiterLongitude($line[LONGITUDE][$i]); |
break; |
case NOTES: |
$info_notes = $this->traiterNotes($line[NOTES][$i]); |
break; |
case DATEOBS: |
$info_dateobs = $this->traiterDateObs($line[DATEOBS][$i]); |
break; |
case TRANSMETTRE: |
$info_transmettre = $this->traiterTransmettre($line[TRANSMETTRE][$i]); |
break; |
case ESPECE: |
// suppression des accents éventuels |
$line[ESPECE][$i] = remove_accent(cp1252_to_utf8($line[ESPECE][$i])); |
$resultat_recherche_espece = $this->chercheur_infos_taxon->rechercherInfosSurTexteCodeOuNumTax($line[ESPECE][$i]); |
if (isset($resultat_recherche_espece['en_id_nom']) && $resultat_recherche_espece['en_id_nom'] != '') { |
$info_espece['nom_sel'] = $resultat_recherche_espece['nom_sel']; |
$info_espece['nom_sel_nn'] = $resultat_recherche_espece['en_id_nom']; |
$complement = $this->chercheur_infos_taxon->rechercherInformationsComplementairesSurNumNom($resultat_recherche_espece['en_id_nom']); |
$info_espece['nom_ret'] = $complement['Nom_Retenu']; |
$info_espece['nom_ret_nn'] = $complement['Num_Nom_Retenu']; |
$info_espece['nt'] = $complement['Num_Taxon']; |
$info_espece['famille'] = $complement['Famille']; |
} else { |
$info_espece['nom_sel'] = $line[ESPECE][$i]; |
} |
case IMAGE: |
if(isset($line[IMAGE])) { |
$info_image=$this->traiterImage($line[IMAGE][$i],$utilisateur); // Image separee par des / + utilisateur |
} |
break; |
} |
} |
else { |
switch($colonne) { |
case COMMUNE: |
$info_commune['nom']=""; |
break; |
case LIEUDIT: |
$info_lieudit=""; |
break; |
case STATION: |
$info_station=""; |
break; |
case MILIEU: |
$info_milieu=""; |
break; |
case DEPARTEMENT: |
if (!isset ($info_commune['code']) || $info_commune['code']=='') { |
$info_commune['code']=""; |
} |
break; |
case LATITUDE: |
$info_latitude = ""; |
break; |
case LONGITUDE: |
$info_longitude = ""; |
break; |
case NOTES: |
$info_notes=''; |
break; |
case TRANSMETTRE: |
$info_transmettre = "0"; |
break; |
} |
} |
} |
$this->dernier_ordre++; |
list($jour,$mois,$annee) = isset($info_dateobs) ? explode("/",$info_dateobs) : array(null,null,null); |
$info_dateobs=$annee."-".$mois."-".$jour." 0:0:0"; |
$requete = "INSERT INTO cel_obs (". |
"ce_utilisateur,prenom_utilisateur,nom_utilisateur,courriel_utilisateur,". |
"ordre,". |
"nom_sel,nom_sel_nn,nom_ret,nom_ret_nn,nt,famille,". |
"zone_geo,ce_zone_geo,". |
"date_observation,". |
"lieudit,station, milieu, commentaire, transmission, ". |
"date_creation,date_modification,latitude,longitude) ". |
" VALUES(".$this->proteger($utilisateur).",". |
$this->proteger($this->utilisateur['prenom']).",". |
$this->proteger($this->utilisateur['nom']).",". |
$this->proteger($this->utilisateur['courriel']).",". |
$this->proteger($this->dernier_ordre).",". |
$this->proteger($info_espece['nom_sel']).",". |
$this->proteger($info_espece['nom_sel_nn']).",". |
$this->proteger($info_espece['nom_ret']).",". |
$this->proteger($info_espece['nom_ret_nn']).",". |
$this->proteger($info_espece['nt']).",". |
$this->proteger($info_espece['famille']).",". |
$this->proteger($info_commune['nom']).",". |
$this->proteger('INSEE-C:'.$info_commune['code']).",". |
$this->proteger($info_dateobs).",". |
$this->proteger($info_lieudit).",". |
$this->proteger($info_station).",". |
$this->proteger($info_milieu).",". |
$this->proteger($info_notes).",". |
$this->proteger($info_transmettre).",". |
"now() , now(),". |
$this->proteger($info_latitude).",". |
$this->proteger($info_longitude).")"; |
$insertion = $this->executer($requete); |
$requete_id_obs = 'SELECT id_observation FROM cel_obs WHERE ordre = '.$this->proteger($this->dernier_ordre).' AND ce_utilisateur = '.$this->proteger($utilisateur); |
$resultat_id_obs = $this->requeter($requete_id_obs); |
$id_obs = $resultat_id_obs[0]['id_observation']; |
// creation lien image |
foreach ($info_image as $pic) { |
$requete_liaison = 'INSERT INTO cel_obs_images (id_image, id_observation ) VALUES ('.$this->proteger($pic['id_image']).', '.$id_obs.') ON DUPLICATE KEY UPDATE id_image = id_image '; |
$liaison = $this->executer($requete_liaison); |
if ($liaison !== false) { |
$this->cpt_images_liees++; |
} else { |
return false; |
} |
} |
return $id_obs; |
} |
function traiterLigneComplement($line,$i,$utilisateur, $id_obs = null) { |
if(isset($line[IMAGE])) { |
$info_image=$this->traiterImage($line[IMAGE][$i],$utilisateur); // Image separee par des / + utilisateur |
// creation lien image |
foreach ($info_image as $pic) { |
$requete = 'INSERT INTO cel_obs_images (id_image, id_observation) VALUES ('.$this->proteger($pic['id_image']).', '.$this->proteger($id_obs).') ON DUPLICATE KEY UPDATE id_image = id_image' ; |
$resultat_liaison = $this->executer($requete); |
if ($resultat_liaison !== false) { |
$this->cpt_images_liees++; |
} else { |
return false; |
} |
} |
} |
} |
function traiterCommune($identifiant_commune) { |
// Recherche correspondance sur nom, si pas unique, correspondance dep. sinon code insee |
$identifiant_commune=trim($identifiant_commune); |
$identifiant_commune=utf8_encode($identifiant_commune); // FIXME : devrait deja etre en utf8 a ce niveau |
preg_match('/(.*) \(([0-9][0-9]*)\)/',$identifiant_commune,$elements); |
if (isset($elements[1])) { // commune + departement : montpellier (34) |
$nom_commune=$elements[1]; |
$code_commune=$elements[2]; |
$requete="SELECT DISTINCT nom, code FROM cel_zones_geo WHERE nom = ".$this->proteger($nom_commune)." AND code LIKE ".$this->proteger($code_commune.'%'); |
} |
else { // Code insee seul |
preg_match('/([0-9][0-9]*)|(2A[0-9][0-9]*)|(2B[0-9][0-9]*)/',$identifiant_commune,$elements); |
if (isset($elements[1])) { // code insee commune |
$code_insee_commune=$elements[1]; |
$requete="SELECT DISTINCT nom, code FROM cel_zones_geo WHERE code = ".$this->proteger($code_insee_commune); |
} |
else { // Commune seule (le departement sera recupere dans la colonne departement si elle est presente, on prend le risque ici de retourner une mauvaise |
// Commune |
preg_match('/(.*)/',$identifiant_commune,$elements); |
if (isset($elements[1])) { // commune |
$nom_commune=$elements[1]; |
$nom_commune=trim($nom_commune); |
$nom_commune=utf8_decode($nom_commune); |
$nom_commune=cp1252_to_utf8($nom_commune); |
$nom_commune=remove_accent($nom_commune); |
$nom_commune=preg_replace("/ /","%",$nom_commune); |
$requete="SELECT DISTINCT nom, code FROM cel_zones_geo WHERE nom like ".$this->proteger($nom_commune.'%'); |
} |
} |
} |
$resultat_commune = $this->requeter($requete); |
// cas de la commune introuvable dans le référentiel |
if(!is_array($resultat_commune) || count($resultat_commune) == 0) { |
$resultat_commune['nom'] = fix_latin($identifiant_commune); |
$resultat_commune['code'] = 'NULL'; |
} else { |
$resultat_commune = $resultat_commune[0]; |
} |
return $resultat_commune; |
} |
function traiterLieudit($lieudit) { |
// texte libre |
$lieudit=fix_latin($lieudit); |
return trim($lieudit); |
} |
function traiterStation($station) { |
// texte libre |
$station=fix_latin($station); |
return trim($station); |
} |
function traiterMilieu($milieu) { |
// texte libre |
$milieu=fix_latin($milieu); |
return trim($milieu); |
} |
function traiterDepartement($departement) { |
// texte libre |
if(is_numeric($departement) && strlen($departement) == 4) { |
$departement = "0"+$departement; |
} |
if(is_numeric($departement) && $departement <= 9) { |
$departement = "0"+$departement; |
} |
return utf8_encode(trim($departement)); |
} |
function traiterLatitude($latitude) { |
// verifier formal decimal + limite france ? TODO |
return trim($latitude); |
} |
function traiterLongitude($longitude) { |
// verifier format decimal + limite france ? TODO |
return trim($longitude); |
} |
function traiterNotes($notes) { |
// texte libre |
$notes=remove_accent($notes); |
return utf8_encode(trim($notes)); |
} |
function traiterDateObs($dateobs) { |
// verifier jj/mm/aaaa sinon date vide TODO |
$date = trim($dateobs); |
if(!preg_match("#[0-9]{2}/[0-9]{2}/([0-9]{4}|[0-9]{2})#", $date)) { |
$date = '00/00/0000'; |
} |
return $date; |
} |
function traiterTransmettre($transmettre) { |
$transmission = '0'; |
if (trim($transmettre) == "1" || trim($transmettre) == "oui") { |
$transmission = '1'; |
} |
return $transmission; |
} |
function traiterImage($images,$utilisateur) { // recherche id image de ce nom |
$liste_images = explode("/",$images) ; |
$row =array(); |
foreach($liste_images as $image) { |
$image = remove_accent(fix_latin($image)); |
$requete = "SELECT * FROM cel_images WHERE ce_utilisateur = ".$this->proteger($utilisateur)." AND nom_original= ".$this->proteger($image); |
$ligne = $this->requeter($requete); |
if(is_array($ligne) && !empty($ligne)) { |
$row[] = $ligne[0]; |
} |
} |
return $row; |
} |
} |
function init_byte_map(){ |
$byte_map = array(); |
for($x=128;$x<256;++$x){ |
$byte_map[chr($x)]=utf8_encode(chr($x)); |
} |
$cp1252_map=array( |
"\x80"=>"\xE2\x82\xAC", // EURO SIGN |
"\x82" => "\xE2\x80\x9A", // SINGLE LOW-9 QUOTATION MARK |
"\x83" => "\xC6\x92", // LATIN SMALL LETTER F WITH HOOK |
"\x84" => "\xE2\x80\x9E", // DOUBLE LOW-9 QUOTATION MARK |
"\x85" => "\xE2\x80\xA6", // HORIZONTAL ELLIPSIS |
"\x86" => "\xE2\x80\xA0", // DAGGER |
"\x87" => "\xE2\x80\xA1", // DOUBLE DAGGER |
"\x88" => "\xCB\x86", // MODIFIER LETTER CIRCUMFLEX ACCENT |
"\x89" => "\xE2\x80\xB0", // PER MILLE SIGN |
"\x8A" => "\xC5\xA0", // LATIN CAPITAL LETTER S WITH CARON |
"\x8B" => "\xE2\x80\xB9", // SINGLE LEFT-POINTING ANGLE QUOTATION MARK |
"\x8C" => "\xC5\x92", // LATIN CAPITAL LIGATURE OE |
"\x8E" => "\xC5\xBD", // LATIN CAPITAL LETTER Z WITH CARON |
"\x91" => "\xE2\x80\x98", // LEFT SINGLE QUOTATION MARK |
"\x92" => "\xE2\x80\x99", // RIGHT SINGLE QUOTATION MARK |
"\x93" => "\xE2\x80\x9C", // LEFT DOUBLE QUOTATION MARK |
"\x94" => "\xE2\x80\x9D", // RIGHT DOUBLE QUOTATION MARK |
"\x95" => "\xE2\x80\xA2", // BULLET |
"\x96" => "\xE2\x80\x93", // EN DASH |
"\x97" => "\xE2\x80\x94", // EM DASH |
"\x98" => "\xCB\x9C", // SMALL TILDE |
"\x99" => "\xE2\x84\xA2", // TRADE MARK SIGN |
"\x9A" => "\xC5\xA1", // LATIN SMALL LETTER S WITH CARON |
"\x9B" => "\xE2\x80\xBA", // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK |
"\x9C" => "\xC5\x93", // LATIN SMALL LIGATURE OE |
"\x9E" => "\xC5\xBE", // LATIN SMALL LETTER Z WITH CARON |
"\x9F" => "\xC5\xB8" // LATIN CAPITAL LETTER Y WITH DIAERESIS |
); |
foreach($cp1252_map as $k=>$v){ |
$byte_map[$k]=$v; |
} |
return $byte_map; |
} |
function fix_latin($instr){ |
$byte_map = init_byte_map(); |
$ascii_char='[\x00-\x7F]'; |
$cont_byte='[\x80-\xBF]'; |
$utf8_2='[\xC0-\xDF]'.$cont_byte; |
$utf8_3='[\xE0-\xEF]'.$cont_byte.'{2}'; |
$utf8_4='[\xF0-\xF7]'.$cont_byte.'{3}'; |
$utf8_5='[\xF8-\xFB]'.$cont_byte.'{4}'; |
$nibble_good_chars = "@^($ascii_char+|$utf8_2|$utf8_3|$utf8_4|$utf8_5)(.*)$@s"; |
if(mb_check_encoding($instr,'UTF-8'))return $instr; // no need for the rest if it's all valid UTF-8 already |
$outstr=''; |
$char=''; |
$rest=''; |
while((strlen($instr))>0){ |
if(1==@preg_match($nibble_good_chars,$instr,$match)){ |
$char=$match[1]; |
$rest=$match[2]; |
$outstr.=$char; |
}elseif(1==@preg_match('@^(.)(.*)$@s',$instr,$match)){ |
$char=$match[1]; |
$rest=$match[2]; |
$outstr.=$byte_map[$char]; |
} |
$instr=$rest; |
} |
return $outstr; |
} |
function remove_accent($str) { |
return supprimerAccents($str); |
$a = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', |
'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß', |
'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', |
'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Ā', |
'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ', 'ĉ', 'Ċ', 'ċ', 'Č', 'č', 'Ď', 'ď', |
'Đ', 'đ', 'Ē', 'ē', 'Ĕ', 'ĕ', 'Ė', 'ė', 'Ę', 'ę', 'Ě', 'ě', 'Ĝ', 'ĝ', 'Ğ', |
'ğ', 'Ġ', 'ġ', 'Ģ', 'ģ', 'Ĥ', 'ĥ', 'Ħ', 'ħ', 'Ĩ', 'ĩ', 'Ī', 'ī', 'Ĭ', 'ĭ', |
'Į', 'į', 'İ', 'ı', 'IJ', 'ij', 'Ĵ', 'ĵ', 'Ķ', 'ķ', 'Ĺ', 'ĺ', 'Ļ', 'ļ', 'Ľ', |
'ľ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'Ń', 'ń', 'Ņ', 'ņ', 'Ň', 'ň', 'ʼn', 'Ō', 'ō', 'Ŏ', |
'ŏ', 'Ő', 'ő', 'Œ', 'œ', 'Ŕ', 'ŕ', 'Ŗ', 'ŗ', 'Ř', 'ř', 'Ś', 'ś', 'Ŝ', 'ŝ', |
'Ş', 'ş', 'Š', 'š', 'Ţ', 'ţ', 'Ť', 'ť', 'Ŧ', 'ŧ', 'Ũ', 'ũ', 'Ū', 'ū', 'Ŭ', |
'ŭ', 'Ů', 'ů', 'Ű', 'ű', 'Ų', 'ų', 'Ŵ', 'ŵ', 'Ŷ', 'ŷ', 'Ÿ', 'Ź', 'ź', 'Ż', |
'ż', 'Ž', 'ž', 'ſ', 'ƒ', 'Ơ', 'ơ', 'Ư', 'ư', 'Ǎ', 'ǎ', 'Ǐ', 'ǐ', 'Ǒ', 'ǒ', |
'Ǔ', 'ǔ', 'Ǖ', 'ǖ', 'Ǘ', 'ǘ', 'Ǚ', 'ǚ', 'Ǜ', 'ǜ', 'Ǻ', 'ǻ', 'Ǽ', 'ǽ', 'Ǿ', 'ǿ'); |
$b = array('A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', |
'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 's', |
'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', |
'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'A', 'a', |
'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd', |
'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', |
'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', |
'IJ', 'ij', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'l', 'l', |
'N', 'n', 'N', 'n', 'N', 'n', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'OE', 'oe', 'R', |
'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', |
'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y', |
'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's', 'f', 'O', 'o', 'U', 'u', 'A', 'a', 'I', |
'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'A', 'a', 'AE', 'ae', 'O', 'o'); |
return str_replace($a, $b, $str); |
} |
//TODO: déplacer les fonctions ci dessus et dessous dans une classe |
// utilitaire |
function supprimerAccents($str, $charset = 'UTF-8') |
{ |
$str = htmlentities($str, ENT_NOQUOTES, $charset); |
$str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str); |
$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. 'œ' |
$str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères |
return $str; |
} |
function cp1252_to_utf8($str) { |
$cp1252_map = array ("\xc2\x80" => "\xe2\x82\xac", |
"\xc2\x82" => "\xe2\x80\x9a", |
"\xc2\x83" => "\xc6\x92", |
"\xc2\x84" => "\xe2\x80\x9e", |
"\xc2\x85" => "\xe2\x80\xa6", |
"\xc2\x86" => "\xe2\x80\xa0", |
"\xc2\x87" => "\xe2\x80\xa1", |
"\xc2\x88" => "\xcb\x86", |
"\xc2\x89" => "\xe2\x80\xb0", |
"\xc2\x8a" => "\xc5\xa0", |
"\xc2\x8b" => "\xe2\x80\xb9", |
"\xc2\x8c" => "\xc5\x92", |
"\xc2\x8e" => "\xc5\xbd", |
"\xc2\x91" => "\xe2\x80\x98", |
"\xc2\x92" => "\xe2\x80\x99", |
"\xc2\x93" => "\xe2\x80\x9c", |
"\xc2\x94" => "\xe2\x80\x9d", |
"\xc2\x95" => "\xe2\x80\xa2", |
"\xc2\x96" => "\xe2\x80\x93", |
"\xc2\x97" => "\xe2\x80\x94", |
"\xc2\x98" => "\xcb\x9c", |
"\xc2\x99" => "\xe2\x84\xa2", |
"\xc2\x9a" => "\xc5\xa1", |
"\xc2\x9b" => "\xe2\x80\xba", |
"\xc2\x9c" => "\xc5\x93", |
"\xc2\x9e" => "\xc5\xbe", |
"\xc2\x9f" => "\xc5\xb8" |
); |
return strtr(utf8_encode($str), $cp1252_map); |
} |
?> |
/branches/v1.6-croc/jrest/services/CelWidgetExport.php |
---|
New file |
0,0 → 1,196 |
<?php |
/** |
* Service fournissant des informations concernant le CEL au format RSS1, RSS2 ou ATOM. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* Format du service : |
* /CelWidgetExport/format |
* /CelWidgetExport/csv |
* |
* Les paramêtres : |
* - "start" indique le numéro du premier item à afficher |
* - "limit" nombre d'items à afficher |
* |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright 2012 |
*/ |
class CelWidgetExport extends Cel { |
private $nom_fichier_export = 'cel_export'; |
private $champs_a_exclure = array('ce_utilisateur' => 'ce_utilisateur', |
'courriel_utilisateur' => 'courriel_utilisateur', |
'transmission' => 'transmission'); |
private $correspondance_champs = array( |
'id_observation' => 'Identifiant Observation', |
'ordre' => 'Ordre Observation', |
'prenom_utilisateur' => 'Prénom', |
'nom_utilisateur' => 'Nom', |
'nom_sel' => 'Nom Sélectionné', |
'nom_sel_nn' => 'Numéro Nomenclatural Nom Selectionné', |
'nom_ret' => 'Nom Retenu', |
'nom_ret_nn' => 'Numéro Nomenclatural Nom Retenu', |
'nt' => 'Numéro Taxonomique', |
'famille' => 'Famille', |
'nom_referentiel' => 'Référentiel Taxonomique', |
'ce_zone_geo' => 'Code Insee', |
'zone_geo' => 'Commune', |
'lieudit' => 'Lieu-Dit', |
'station' => 'Station', |
'milieu' => 'Milieu', |
'latitude' => 'Latitude', |
'longitude' => 'Longitude', |
'geodatum' => 'Référentiel Géographique', |
'date_observation' => 'Date Observation', |
'mots_cles_texte' => 'Mots Clés', |
'commentaire' => 'Commentaires', |
'date_creation' => 'Date Création', |
'date_modification' => 'Date Modification', |
'date_transmission' => 'Date Transmission' |
); |
private $parametres_autorises = array( |
'utilisateur' => 'courriel_utilisateur', |
'commune' => 'zone_geo', |
'dept' => 'departement', |
'projet' => 'mots_cles', |
'num_taxon' => 'nt', |
'date_debut' => 'date_debut', |
'date_fin' => 'date_fin', |
'taxon' => 'taxon' |
); |
private $format = 'csv'; |
/** |
* Méthode appelée avec une requête de type GET. |
*/ |
public function getElement($params = array()) { |
$criteres = $this->traiterParametres($_GET); |
// Seulement les observation publiques |
$criteres['transmission'] = 1; |
$chercheur_observations = new RechercheObservation($this->config); |
$numero_page = isset($criteres['debut']) ? $criteres['debut'] : 0; |
$limite = isset($criteres['limite']) ? $criteres['limite'] : 0; |
unset($criteres['limite']); |
unset($criteres['debut']); |
$observations = $chercheur_observations->rechercherObservations(null, $criteres, $numero_page, $limite); |
//echo count($observations);exit; |
switch($this->format) { |
case 'csv': |
$csv = $this->convertirEnCsv($observations); |
$this->envoyerCsv($csv); |
break; |
case 'xls': |
$observations = array_slice($observations, 0, 10000); |
$xls = $this->convertirEnXls($observations); |
$this->envoyerXls($xls); |
break; |
default: |
} |
} |
protected function traiterParametres(Array $parametres) { |
$parametres_traites = array(); |
$this->format = (isset($parametres['format']) && $parametres['format'] != '') ? $parametres['format'] : $this->format; |
foreach($parametres as $cle => $valeur) { |
if(trim($valeur) != '' && isset($this->parametres_autorises[$cle])) { |
$parametres_traites[$this->parametres_autorises[$cle]] = $valeur; |
} |
} |
return $parametres_traites; |
} |
private function envoyerCsv($csv) { |
header('Content-Type: text/csv; charset=UTF-8'); |
header('Content-Disposition: attachment;filename='.$this->nom_fichier_export.'.csv'); |
echo $csv; |
exit; |
} |
private function envoyerXls($workbook) { |
$workbook->close(); |
exit; |
} |
private function convertirEnCsv($data) |
{ |
$chemin_temp = "php://temp"; |
$outstream = fopen($chemin_temp, 'r+'); |
$intitule_champs = array(); |
foreach($data as $ligne) { |
$ligne = $this->filtrerDonneesSensibles($ligne); |
$ligne = array_diff_key($ligne, $this->champs_a_exclure); |
if(empty($intitule_champs)) { |
$intitule_champs = $this->creerEntetesChamps($ligne); |
fputcsv($outstream, $intitule_champs, ',', '"'); |
} |
fputcsv($outstream, $ligne, ',', '"'); |
} |
rewind($outstream); |
$csv = stream_get_contents($outstream); |
fclose($outstream); |
return $csv; |
} |
private function convertirEnXls($data) { |
$this->extendSpreadsheetProductor = new SpreadsheetProductor(); |
$this->extendSpreadsheetProductor->initSpreadsheet(); |
$workbook = new Spreadsheet_Excel_Writer(); |
$worksheet = $workbook->addWorksheet('Liste'); |
$workbook->send($this->nom_fichier_export.'.xls'); |
$nb_lignes = 1; |
foreach($data as $ligne) { |
$ligne = $this->filtrerDonneesSensibles($ligne); |
$ligne = array_diff_key($ligne, $this->champs_a_exclure); |
if(empty($intitule_champs)) { |
$intitule_champs = $this->creerEntetesChamps($ligne); |
$indice = 0; |
foreach ($intitule_champs as $intitule) { |
$colonne = $intitule_champs[$indice]; |
$colonne = mb_convert_encoding($colonne, 'ISO-8859-15', 'UTF-8'); |
$worksheet->write(0,$indice,$colonne); |
$indice++; |
} |
} |
$indice = 0; |
foreach($ligne as $champ) { |
$champ = mb_convert_encoding($champ, 'ISO-8859-15', 'UTF-8'); |
$worksheet->write($nb_lignes,$indice,$champ); |
$indice++; |
} |
$nb_lignes++; |
} |
return $workbook; |
} |
private function creerEntetesChamps($noms_colonnes) { |
$champs_presents = array_intersect_key($this->correspondance_champs, $noms_colonnes); |
return array_values($champs_presents); |
} |
private function filtrerDonneesSensibles($ligne) { |
if(stripos($ligne['mots_cles_texte'], 'sensible') !== false) { |
$ligne['latitude'] = ''; |
$ligne['longitude'] = ''; |
} |
return $ligne; |
} |
private function nettoyerChaine($chaine) { |
$chaine = str_replace("\n",' ',$chaine); |
$chaine = str_replace("\t",'',$chaine); |
return $chaine; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/NameMap.php |
---|
New file |
0,0 → 1,64 |
<?php |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david.delon@clapas.net> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* NameMap.php |
* |
* in utf8 |
* out utf8 |
* |
* Cas d'utilisation : |
* Service recherche d'image a partir d'un numero nomenclatural |
* |
* 1: Le service recoit un référentiell et un numero nomenclatural |
* 2: Le service recherche une carte disponible |
*/ |
class NameMap extends Cel { |
function getElement($uid){ |
$retour = array(''); |
if(isset($uid[0]) && isset($uid[1])) { |
$uid[0] = $uid[0] != '' ? $uid[0] : 'bdtfx'; |
$retour = $this->obtenirCarteChorologie($uid[0], $uid[1]); |
} |
$this->envoyerJson($retour); |
return true; |
} |
function obtenirCarteChorologie($referentiel_taxo, $nn) { |
// TODO: gérer ici les cartes d'autres référentiels si celles si sont disponibles |
$retour = array(''); |
switch($referentiel_taxo) { |
case 'bdtfx': |
$url_service_chorologie = $this->config['eflore']['url_service_chorologie_carte']; |
$file = $url_service_chorologie.'/nn%3A'.$nn.'?retour.format=587&retour=image%2Fpng'; |
$retour = array($file); |
break; |
default: |
break; |
} |
return $retour; |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.1 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.1 2007-06-06 13:31:16 ddelon |
* v0.09 |
*/ |
?> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v1.6-croc/jrest/services/CelWidgetMapPoint.php |
---|
New file |
0,0 → 1,1184 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Service fournissant une carte dynamique des obsertions publiques du CEL. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* Cas d'utilisation : |
* /CelWidgetMap/Carte/Utilisateur : carte des observations publiques d'un utilisateur. |
* /CelWidgetMap/Carte/Utilisateur/Projet : carte des observations publiques d'un utilisateur pour un projet. |
* /CelWidgetMap/Carte/Utilisateur/Projet/dept : carte des observations publiques d'un utilisateur pour un projet sur un département. |
* /CelWidgetMap/Carte/Utilisateur/Projet/dept/nt : carte des observations publiques d'un utilisateur pour un projet sur un département pour un taxon. |
* |
* Carte = Type de carte. Valeurs possible : defaut, |
* Utilisateur = identifiant (= courriel) de l'utilisateur ou * pour tous les utilisateurs. |
* Projet = mot-clé du projet |
* |
* @author Jean-Pascal MILCENT <jpm@clapas.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2010, Jean-Pascal MILCENT |
*/ |
// TODO : supprimer le TRIM quand les obs seront reliées correctements aux localisations (sur le code INSEE par exemple) |
class CelWidgetMapPoint extends Cel { |
const MARQUEUR_GROUPE = 'GROUPE'; |
const MARQUEUR_COMMUNE = 'COMMUNE'; |
const MARQUEUR_STATION = 'STATION'; |
/** |
* Méthode appelée avec une requête de type GET. |
*/ |
public function getElement($ressources) { |
$retour = null; |
if($this->parametres == null) { |
$this->parametres = array(); |
} |
extract($this->parametres); |
//Chronometre::chrono("Avant groupage"); |
$action = array_shift($ressources); |
if (isset($action)) { |
$methode = $this->traiterNomMethodeGet($action); |
if (method_exists($this, $methode)) { |
$retour = $this->$methode($ressources); |
} else { |
$this->messages[] = "Ce type de ressource '$methode' n'est pas disponible."; |
} |
} else { |
$this->messages[] = "Vous devez indiquer le type de ressource."; |
} |
//Chronometre::chrono("Apres traitement"); |
//echo Chronometre::afficherChrono(); |
if (is_null($retour)) { |
$info = 'Un problème est survenu : '.print_r($this->messages, true); |
$this->envoyer($info); |
} else if (isset($retour['type']) && $retour['type'] == 'jsonVar') { |
$this->envoyerJsonVar($retour['variable_js'], $retour['donnees']); |
} else if (isset($retour['type']) && $retour['type'] == 'jsonP') { |
$this->envoyerJsonp($retour['donnees']); |
} else if (isset($retour['type']) && $retour['type'] == 'png') { |
header("Content-type: image/png"); |
imagepng($retour['img']); |
imagedestroy($retour['img']); |
} else { |
$this->envoyerJson($retour); |
} |
} |
/** |
* Les icones des groupes de stations |
*/ |
public function getIconeGroupe($params) { |
extract($this->parametres); |
$chemin_marqueur = sprintf($this->config['settings']['cheminCelMarkerObsTpl'], $type); |
$img = imagecreatefrompng($chemin_marqueur); |
$noir = imagecolorallocate($img, 0, 0, 0); |
$texte = (String) $nbre; |
$x = (imagesx($img) - 6.0 * strlen($texte)) / 2; |
$y = (imagesy($img) - 16) / 2; |
imagestring($img, 3, $x, $y, $texte, $noir); |
imagealphablending($img, false); |
imagesavealpha($img, true); |
return array('type' => 'png', 'img' => $img); |
} |
public function getTout($params) { |
$emplacements = null; |
$concatenation_id = "CONCAT(IFNULL(latitude,''),IFNULL(longitude,''), IFNULL(wgs84_latitude,''),IFNULL(wgs84_longitude,'')) "; |
$requete = 'SELECT ce_zone_geo, zone_geo, station, '. |
"mots_cles_texte, ". |
"latitude, ". |
"wgs84_latitude, ". |
"longitude, ". |
"wgs84_longitude, ". |
$concatenation_id." as id_coord ". |
'FROM cel_obs AS co '. |
' LEFT JOIN cel_zones_geo AS l '. |
' ON (l.nom = co.zone_geo AND l.id_zone_geo = co.ce_zone_geo) '. |
"WHERE transmission = '1' ". |
" AND (". |
$this->construireWhereRectangleStationOR()." OR ". |
$this->construireWhereRectangleCommuneOR().") ". |
$this->construireWhereDept(). |
$this->construireWhereCommune(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereReferentiel(). |
$this->construireWhereDate(). |
$this->construireWhereCommentaire(). |
$this->construireWherePhotosSeulement(). |
$this->construireWhereProjet(). |
$this->construireWhereTag(). |
$this->construireWhereNombreDeJours(). |
' GROUP BY id_coord'; |
$resultats_emplacements = $this->executerRequete($requete); |
$emplacements = $this->traiterEmplacements($resultats_emplacements, $this->compterObservations($params)); |
return $emplacements; |
} |
private function afficherRequeteFormatee($requete) { |
$requete = str_replace(')',')<br />',$requete); |
$requete = str_replace('(',' <br /> (',$requete); |
echo '<pre>'.$requete.'</pre>'; |
exit; |
} |
private $nb_obs = 0; |
private function compterObservations($params) { |
$requete = 'SELECT COUNT(*) as nb '. |
'FROM cel_obs AS co '. |
' LEFT JOIN cel_zones_geo AS l '. |
' ON (l.nom = co.zone_geo AND l.id_zone_geo = co.ce_zone_geo) '. |
"WHERE transmission = '1' ". |
" AND (". |
$this->construireWhereRectangleStationOR()." OR ". |
$this->construireWhereRectangleCommuneOR().") ". |
$this->construireWhereDept(). |
$this->construireWhereCommune(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereReferentiel(). |
$this->construireWhereDate(). |
$this->construireWhereCommentaire(). |
$this->construireWherePhotosSeulement(). |
$this->construireWhereProjet(). |
$this->construireWhereTag(). |
$this->construireWhereNombreDeJours(); |
//echo $requete;exit; |
$resultats_nb_obs = $this->executerRequete($requete); |
return $resultats_nb_obs[0]['nb']; |
} |
private function traiterEmplacements(&$emplacements, $nb_total_observation) { |
$zoom = (int) array_key_exists('zoom', $this->parametres) ? $this->parametres['zoom'] : 11; |
$distance = (int) array_key_exists('distance', $this->parametres) ? $this->parametres['distance'] : 20; |
$marqueurs = array( |
'stats' => array('stations' => 0, 'communes' => 0, 'observations' => 0), |
'points' => null |
); |
if (isset($this->parametres['ne']) && $this->parametres['sw'] && ! $this->etreNull($this->parametres['ne']) && ! $this->etreNull($this->parametres['sw'])) { |
$ne = $this->decomposerLatLng($this->parametres['ne']); |
$sw = $this->decomposerLatLng($this->parametres['sw']); |
$marqueurs['points'] = CartoGroupage::creerGroupesQuadtree($emplacements, $ne['lat'], $ne['lng'], $sw['lat'], $sw['lng'], $zoom); |
// laisser la classe cartoGroupage compter les élements simplifie le comptage |
// et permet de ne pas reparser le tableau pour compter les différents éléments |
$nb_elements = CartoGroupage::getNbElements(); |
// les bornes servent à centrer la carte dans le cas ou l'on demande des paramètres précis |
$marqueurs['stats']['coordmax'] = CartoGroupage::getBornes(); |
$marqueurs['stats']['stations'] = $nb_elements['stations']; |
$marqueurs['stats']['communes'] = $nb_elements['communes']; |
$marqueurs['stats']['observations'] = (int)$nb_total_observation; |
} else { |
$marqueurs['points'] = $emplacements; |
} |
return $marqueurs; |
} |
private function traiterStations($communes, $stations) { |
$zoom = (int) array_key_exists('zoom', $this->parametres) ? $this->parametres['zoom'] : 11; |
$distance = (int) array_key_exists('distance', $this->parametres) ? $this->parametres['distance'] : 20; |
$marqueurs = array( |
'stats' => array('stations' => 0, 'communes' => 0, 'observations' => 0), |
'points' => null |
); |
$marqueurs['stats']['observations'] = $this->traiterNbreObs($communes) + $this->traiterNbreObs($stations); |
$points = array(); |
if ($communes !== false) { |
foreach ($communes as $commune) { |
if (is_numeric($commune['lat']) && is_numeric($commune['lng'])) { |
extract($commune); |
$id = self::MARQUEUR_COMMUNE.':'.$lat.'|'.$lng; |
$lata = round($lat, 5); |
$lnga = round($lng, 5); |
if (!isset($points[$id])) { |
$points[$id]['id'] = $id; |
$points[$id]['nom'] = $nom; |
$points[$id]['lat'] = $lata; |
$points[$id]['lng'] = $lnga; |
$points[$id]['nbre'] = 1; |
$marqueurs['stats']['communes']++; |
} else { |
$points[$id]['nbre']++; |
} |
} |
} |
} |
if ($stations !== false) { |
foreach ($stations as $station) { |
if (is_numeric($station['lat']) && is_numeric($station['lng'])) { |
extract($station); |
$id = self::MARQUEUR_STATION.':'.$lat.'|'.$lng; |
$lata = round($lat, 5); |
$lnga = round($lng, 5); |
$nom = $this->etreNull($nom) ? $lata.','.$lnga : $nom; |
if (!isset($points[$id])) { |
$points[$id]['id'] = $id; |
$points[$id]['nom'] = $nom; |
$points[$id]['lat'] = $lata; |
$points[$id]['lng'] = $lnga; |
$points[$id]['nbre'] = 1; |
$marqueurs['stats']['stations']++; |
} else { |
$points[$id]['nbre']++; |
} |
} |
} |
} |
if (isset($this->parametres['ne']) && $this->parametres['sw'] && ! $this->etreNull($this->parametres['ne']) && ! $this->etreNull($this->parametres['ne']) && ! $this->etreNull($this->parametres['sw'])) { |
$ne = $this->decomposerLatLng($this->parametres['ne']); |
$sw = $this->decomposerLatLng($this->parametres['sw']); |
$marqueurs['points'] = CartoGroupage::creerGroupesQuadtree(&$points, $ne['lat'], $ne['lng'], $sw['lat'], $sw['lng'], $zoom); |
} else { |
$marqueurs['points'] = $points; |
} |
//$marqueurs['stats']['latDiff'] = abs($marqueurs['stats']['latMin'] - $marqueurs['stats']['latMax']); |
//$marqueurs['stats']['lngDiff'] = abs($marqueurs['stats']['lngMin'] - $marqueurs['stats']['lngMax']); |
return $marqueurs; |
} |
private function definirLatLngMaxMin(&$marqueurs, $lat, $lng) { |
if ($lat != null && $lng != null) { |
$marqueurs['stats']['latMin'] = $marqueurs['stats']['latMin'] > $lat ? $lat : $marqueurs['stats']['latMin']; |
$marqueurs['stats']['lngMin'] = $marqueurs['stats']['lngMin'] > $lng ? $lng : $marqueurs['stats']['lngMin']; |
$marqueurs['stats']['latMax'] = $marqueurs['stats']['latMax'] < $lat ? $lat : $marqueurs['stats']['latMax']; |
$marqueurs['stats']['lngMax'] = $marqueurs['stats']['lngMax'] < $lng ? $lng : $marqueurs['stats']['lngMax']; |
} |
} |
private function traiterNbreObs($resultats) { |
$obs_nbre = 0; |
if ($resultats !== false) { |
$obs_nbre = count($resultats); |
} |
return $obs_nbre; |
} |
private function verifierLatLng($lat, $lng) { |
$ok_lat = $this->etreLatitude($lat) ? true : false; |
$ok_lng = $this->etreLongitude($lng) ? true : false; |
$ok = $ok_lat && $ok_lng; |
return $ok; |
} |
private function etreLatitude($lat) { |
$ok = false; |
//$format = preg_match('/^[-]?[0-9]+(?:[.][0-9]+|)$/', $lat) ? true : false; |
$ok = ($lat >= -90 && $lat <= 90) ? true : false; |
return $ok; |
} |
private function etreLongitude($lng) { |
$ok = false; |
//$format = preg_match('/^[-]?[0-9]+(?:[.][0-9]+|)$/', $lng) ? true : false; |
$ok = ($lng >= -180 && $lng <= 180) ? true : false; |
return $ok; |
} |
private function etreObsSensible($tags) { |
$sensible = true; |
if (stristr($tags, 'sensible') === FALSE) { |
$sensible = false; |
} |
return $sensible; |
} |
private function communeEstDemandee() { |
$station_infos = $this->decomposerParametreStation(); |
$commune_demandee = true; |
if($station_infos['type'] == self::MARQUEUR_STATION) { |
$commune_demandee = false; |
} |
return $commune_demandee; |
} |
/** |
* Données pour l'affichage des obs d'une station |
*/ |
public function getObservations($params) { |
$resultats = array(); |
$total = 0; |
if (isset($this->parametres['station']) && !$this->etreNull($this->parametres['station'])) { |
$requete = 'SELECT SQL_CALC_FOUND_ROWS id_observation, ce_utilisateur, courriel_utilisateur, nom_utilisateur, prenom_utilisateur, '. |
' nom_sel, nom_ret, nom_sel_nn, nom_ret_nn, nt, famille, '. |
' lieudit, zone_geo, date_observation, milieu, commentaire, '. |
' utm_secteur, utm_x, utm_y, code, date_transmission '. |
'FROM cel_obs AS co '. |
' LEFT JOIN cel_zones_geo AS l '. |
" ON (l.nom = co.zone_geo AND l.id_zone_geo = co.ce_zone_geo) ". |
"WHERE transmission = '1' ". |
(($this->communeEstDemandee()) ? $this->construireWhereCommuneSansCoordonneesAvecSensibles() : $this->construireWhereCoordonneesSansSensibles()). |
$this->construireWhereDept(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereReferentiel(). |
$this->construireWhereDate(). |
$this->construireWhereCommentaire(). |
$this->construireWherePhotosSeulement(). |
$this->construireWhereProjet(). |
$this->construireWhereTag(). |
$this->construireWhereNombreDeJours(). |
'ORDER BY nom_sel ASC '. |
"LIMIT {$this->start},{$this->limit} "; |
//echo $requete;exit; |
$resultats = $this->requeter($requete, self::SQL_RETOUR_COMPLET, self::SQL_MODE_OBJET); |
$requete = 'SELECT FOUND_ROWS()'; |
$total = (int) $this->requeter($requete, self::SQL_RETOUR_COLONNE); |
} |
// Post-traitement |
$observations = $this->traiterObservations($resultats, $total); |
$observations = $this->ajouterImagesAuxObs($observations); |
$observations = $this->ajouterAuteursAuxObs($observations); |
$observations = $this->supprimerIdDesObs($observations); |
return $observations; |
} |
private function traiterObservations($donnees, $total) { |
$observations = array('commune' => '', 'observations' => array(), 'observateurs' => array()); |
$observations['total'] = (isset($total)) ? $total : 0; |
if (is_array($donnees) && count($donnees) > 0) { |
foreach ($donnees as $donnee) { |
//echo '<pre>'.print_r($donnee,true).'</pre>';exit; |
$observation = array(); |
$observation['idObs'] = $donnee->id_observation; |
$observation['nn'] = $this->etreNull($donnee->nom_sel_nn) ? null : $donnee->nom_sel_nn; |
$observation['nomSci'] = $this->nettoyerTexte($donnee->nom_sel); |
$observation['date'] = ($donnee->date_observation != '0000-00-00 00:00:00') ? $this->formaterDate($donnee->date_observation, '%d/%m/%Y') : ''; |
$observation['datePubli'] = $this->formaterDate($donnee->date_transmission); |
$observation['lieu'] = $this->traiterLieu($donnee); |
$observation['observateur'] = $donnee->courriel_utilisateur; |
$observation['observateurId'] = $donnee->ce_utilisateur; |
$observation['urlEflore'] = $this->getUrlEflore($donnee->nom_sel_nn); |
if (isset($donnee->zone_geo)) { |
$observations['commune'] = $this->nettoyerTexte($donnee->zone_geo); |
} |
$observations['observations'][$donnee->id_observation] = $observation; |
if (! array_key_exists($donnee->ce_utilisateur, $observations['observateurs'])) { |
$observations['observateurs'][$donnee->courriel_utilisateur] = $donnee->courriel_utilisateur; |
} |
} |
} |
return $observations; |
} |
private function getUrlEflore($nn) { |
$urlEflore = null; |
if (! $this->etreNull($nn)) { |
$urlEflore = sprintf($this->config['settings']['efloreUrlTpl'], $nn, 'illustration'); |
} |
return $urlEflore; |
} |
private function traiterLieu($donnee) { |
$lieu = array(); |
if (!$this->etreNull($donnee->lieudit)) { |
$lieu[] = $donnee->lieudit; |
} |
if (!$this->etreNull($donnee->milieu)) { |
$lieu[] = $donnee->milieu; |
} |
return implode(', ', $lieu); |
} |
private function chargerImages(Array $obs_ids) { |
// Récupération des données au format Json |
$service = 'CelImage/liste-ids?obsId='.implode(',', $obs_ids); |
$url = sprintf($this->config['settings']['baseURLServicesCelTpl'], $service); |
$json = $this->getRestClient()->consulter($url); |
$donnees = json_decode($json); |
// Post-traitement des données |
$images = $this->traiterImages($donnees); |
return $images; |
} |
private function traiterImages($donnees) { |
$images = array(); |
if (count($donnees) > 0) { |
foreach ($donnees as $id_obs => $id_images) { |
foreach ($id_images as $id_img) { |
$urls['idImg'] = $id_img; |
$urls['guid'] = sprintf($this->config['settings']['guidImgTpl'], $id_img); |
$urls['miniature'] = $this->getUrlImage($id_img, 'CXS'); |
$urls['normale'] = $this->getUrlImage($id_img, 'XL'); |
$images[$id_obs][] = $urls; |
} |
} |
} |
return $images; |
} |
private function ajouterImagesAuxObs($observations) { |
$images = $this->chargerImages(array_keys($observations['observations'])); |
foreach ($observations['observations'] as $id => $infos) { |
if(isset($images[$id])) { |
$infos['images'] = $images[$id]; |
$observations['observations'][$id] = $infos; |
} |
} |
return $observations; |
} |
private function ajouterAuteursAuxObs($observations) { |
$observateurs = $this->recupererUtilisateursIdentite(array_keys($observations['observateurs'])); |
unset($observations['observateurs']); |
foreach ($observations['observations'] as $id => $infos) { |
$courriel = strtolower($infos['observateur']); |
if(isset($observateurs[$courriel])) { |
$infos['observateur'] = $observateurs[$courriel]['intitule']; |
$infos['observateurId'] = $observateurs[$courriel]['id']; |
} |
$observations['observations'][$id] = $infos; |
} |
return $observations; |
} |
private function supprimerIdDesObs($observations) { |
// Le tableau de sortie ne doit pas avoir les id des obs en clé car sinon Jquery Template ne fonctionne pas |
$observationSansId = $observations; |
unset($observationSansId['observations']); |
foreach ($observations['observations'] as $id => $infos) { |
$observationSansId['observations'][] = $infos; |
} |
return $observationSansId; |
} |
/** |
* Liste des taxons présents sur la carte |
*/ |
public function getTaxons($params) { |
$json = null; |
$requete = 'SELECT SQL_CALC_FOUND_ROWS DISTINCT nom_ret, nom_ret_nn, nt, famille '. |
'FROM cel_obs AS co '. |
' LEFT JOIN cel_zones_geo AS l '. |
' ON (l.nom = co.zone_geo AND l.id_zone_geo = co.ce_zone_geo) '. |
"WHERE transmission = '1' ". |
" AND nom_ret != '' ". |
$this->construireWhereDept(). |
$this->construireWhereCommune(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereReferentiel(). |
$this->construireWhereDate(). |
$this->construireWhereCommentaire(). |
$this->construireWherePhotosSeulement(). |
$this->construireWhereProjet(). |
$this->construireWhereTag(). |
$this->construireWhereNombreDeJours(). |
'ORDER BY nom_ret ASC '. |
"LIMIT {$this->start},{$this->limit} "; |
//$this->debug[] = $requete; |
$resultats = $this->requeter($requete, self::SQL_RETOUR_COMPLET, self::SQL_MODE_OBJET); |
//echo $requete;exit; |
$requete = 'SELECT FOUND_ROWS()'; |
$taxons['total'] = (int) $this->requeter($requete, self::SQL_RETOUR_COLONNE); |
// Post-traitement |
$taxons['taxons'] = $this->traiterTaxons($resultats); |
return $taxons; |
} |
private function traiterTaxons($donnees) { |
$taxons = array(); |
if (is_array($donnees) && count($donnees) > 0) { |
foreach ($donnees as $donnee) { |
if (!isset($taxons[$donnee->nt]) && ! $this->etreNull($donnee->nom_ret)) { |
$taxon = array(); |
$taxon['nn'] = $donnee->nom_ret_nn; |
$taxon['nt'] = $donnee->nt; |
$taxon['nom'] = $this->nettoyerTexte($donnee->nom_ret); |
$taxon['famille'] = $this->nettoyerTexte($donnee->famille); |
$taxons[$donnee->nt] = $taxon; |
} |
} |
} |
$taxons = array_values($taxons); |
return $taxons; |
} |
private function construireWhereCoordonnees() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->decomposerParametreStation()); |
if (isset($type)) { |
if ($type == self::MARQUEUR_COMMUNE) { |
$lat = $this->proteger($lat.'%'); |
$lng = $this->proteger($lng.'%'); |
$sql = " AND wgs84_latitude LIKE $lat AND wgs84_longitude LIKE $lng "; |
} else if ($type == self::MARQUEUR_STATION) { |
$lat = $this->proteger($lat.'%'); |
$lng = $this->proteger($lng.'%'); |
$sql = " AND (latitude LIKE $lat AND longitude LIKE $lng) "; |
} |
} |
return $sql; |
} |
private function construireWhereCoordonneesSansSensibles() { |
$sql = '('; |
// Récupération des coordonnées depuis l'id station |
extract($this->decomposerParametreStation()); |
if (isset($type)) { |
if ($type == self::MARQUEUR_COMMUNE) { |
$lat = $this->proteger($lat); |
$lng = $this->proteger($lng); |
$sql = " AND wgs84_latitude LIKE $lat AND wgs84_longitude LIKE $lng "; |
} else if ($type == self::MARQUEUR_STATION) { |
$lat = $this->proteger($lat.'%'); |
$lng = $this->proteger($lng.'%'); |
$sql = " AND (latitude LIKE $lat AND longitude LIKE $lng) "; |
} |
} |
$sql .= ' AND (mots_cles_texte IS NULL OR mots_cles_texte NOT LIKE "%sensible%" ) '; |
return $sql; |
} |
private function construireWhereCommentaire() { |
$sql = ''; |
list($type, $commentaire) = $this->decomposerParametreCommentaire(); |
if (!$this->etreNull($commentaire)) { |
$commentaire = $this->proteger('%'.$commentaire.'%'); |
switch ($type) { |
case '*' : |
$sql = $this->obtenirConditionPourCommentaires($commentaire); |
$sql = " AND (commentaire LIKE $commentaire OR ($sql)) "; |
break; |
case 'observation' : |
$sql = " AND commentaire LIKE $commentaire "; |
break; |
case 'photo' : |
$sql = ' AND '.$this->obtenirConditionPourCommentaires($commentaire).' '; |
break; |
case 'photo.meta' : |
$sql = ' AND '.$this->obtenirConditionPourCommentaireMeta($commentaire).' '; |
break; |
case 'photo.utilisateur' : |
$sql = ' AND '.$this->obtenirConditionPourCommentaireUtilisateur($commentaire).' '; |
break; |
default: |
$sql = " AND commentaire LIKE $commentaire "; |
} |
} |
return $sql; |
} |
private function construireWhereNomTaxon() { |
$sql = ''; |
list($type, $nom) = $this->decomposerParametreTaxon(); |
if (!$this->etreNull($nom)) { |
$nom = $this->proteger($nom.'%'); |
switch ($type) { |
case '*' : |
$sql = " AND (nom_ret LIKE $nom OR nom_sel LIKE $nom OR famille LIKE $nom) "; |
break; |
case 'retenu' : |
$sql = " AND nom_ret LIKE $nom "; |
break; |
case 'selectionne' : |
$sql = " AND nom_sel LIKE $nom "; |
break; |
case 'famille' : |
$sql = " AND famille LIKE $nom "; |
break; |
default: |
$sql = " AND nom_ret LIKE $nom "; |
} |
} |
return $sql; |
} |
private function construireWhereReferentiel() { |
$sql = ''; |
extract($this->parametres); |
if (isset($referentiel) && !$this->etreNull($referentiel)) { |
$referentiel = $this->proteger($referentiel.'%'); |
$sql = ' AND co.nom_referentiel LIKE '.$referentiel.' '; |
} |
return $sql; |
} |
private function construireWhereDate() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
list($type, $date) = $this->decomposerParametreDate(); |
if (!$this->etreNull($date)) { |
$date = $this->proteger($date.'%'); |
switch ($type) { |
case '*' : |
$sql = " AND ( |
date_observation LIKE $date |
OR date_creation LIKE $date |
OR date_modification LIKE $date |
OR date_transmission LIKE $date) "; |
break; |
case 'observation' : |
$sql = " AND date_observation LIKE $date "; |
break; |
case 'creation' : |
$sql = " AND date_creation LIKE $date "; |
break; |
case 'modification' : |
$sql = " AND date_modification LIKE $date "; |
break; |
case 'transmission' : |
$sql = " AND date_transmission LIKE $date "; |
break; |
case 'photo' : |
$sql = $this->obtenirConditionPourDatePhoto($date); |
break; |
case 'ajout' : |
$sql = $this->obtenirConditionPourDateAjout($date); |
break; |
case 'liaison' : |
$sql = $this->obtenirConditionPourDateLiaison($date); |
break; |
default: |
$sql = " AND date_observation LIKE $date "; |
} |
} |
return $sql; |
} |
private function obtenirConditionPourDatePhoto($date) { |
$observations = $this->obtenirObsLieesImg('date.photo', $date); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'est liée à une photo prise à la date : $date"; |
} |
$sql = $this->assemblerObsEnConditionSql($observations); |
return $sql; |
} |
private function obtenirConditionPourDateLiaison($date) { |
$observations = $this->obtenirObsLieesImg('date.liaison', $date); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'a été liée à une image à à la date : $date"; |
} |
$sql = $this->assemblerObsEnConditionSql($observations); |
return $sql; |
} |
private function obtenirConditionPourDateAjout($date) { |
$observations = $this->obtenirObsLieesImg('date.ajout', $date); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'est liée à une image ajoutée à la date : $date"; |
} |
$sql = $this->assemblerObsEnConditionSql($observations); |
return $sql; |
} |
private function obtenirConditionPourCommentaireMeta($commentaire) { |
$observations = $this->obtenirObsLieesImg('commentaire.meta', $commentaire); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'est liée à une image dont le commentaire des méta-données correspond à : $commmentaire"; |
} |
$operateur = ''; |
$sql = $this->assemblerObsEnConditionSql($observations, $operateur); |
return $sql; |
} |
private function obtenirConditionPourCommentaireUtilisateur($commentaire) { |
$observations = $this->obtenirObsLieesImg('commentaire.utilisateur', $commentaire); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'est liée à une image dont le commentaire des utilisateur correspond à : $commmentaire"; |
} |
$operateur = ''; |
$sql = $this->assemblerObsEnConditionSql($observations, $operateur); |
return $sql; |
} |
private function obtenirConditionPourCommentaires($commentaire) { |
$observations = $this->obtenirObsLieesImg('commentaire.*', $commentaire); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'est liée à une image dont un des commentaires correspond à : $commmentaire"; |
} |
$operateur = ''; |
$sql = $this->assemblerObsEnConditionSql($observations, $operateur); |
return $sql; |
} |
/** |
* Récupération des identifiant d'utilisateur et des ordres des observations correspondant à une date. |
* Retour sous forme de tableau : array[identifiant] = array(ordre, ordre...); |
*/ |
private function obtenirObsLieesImg($type, $param) { |
// Construction de la requête |
$requete = 'SELECT DISTINCT co.id_obs, ci.ce_utilisateur AS utilisateur '. |
'FROM cel_images '. |
' LEFT JOIN cel_obs_images coi '. |
' ON (ci.id_image = coi.id_image) '. |
' LEFT JOIN cel_obs AS co '. |
' ON (coi.id_observation = co.id_observation) '. |
' LEFT JOIN cel_zones_geo AS l '. |
' ON (l.nom = co.zone_geo AND l.id_zone_geo = co.ce_zone_geo) '. |
"WHERE transmission = '1' ". |
($type == 'date.photo' ? " AND (ci_meta_date_time LIKE ".str_replace('-', ':', $param)." OR ci_meta_date LIKE $param) " : ''). |
($type == 'date.ajout' ? " AND ci_meta_date_ajout LIKE $param " : ''). |
($type == 'date.liaison' ? " AND coi_date_liaison LIKE $param " : ''). |
($type == 'commentaire.meta' ? " AND ci_meta_comment LIKE $param " : ''). |
($type == 'commentaire.utilisateur' ? " AND ci_meta_user_comment LIKE $param " : ''). |
($type == 'commentaire.*' ? " AND (ci_meta_comment LIKE $param OR ci_meta_user_comment LIKE $param) " : ''). |
$this->construireWhereCoordonnees(). |
$this->construireWhereDept(). |
$this->construireWhereCommune(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereReferentiel(). |
$this->construireWhereProjet(). |
$this->construireWhereTag(). |
'ORDER BY utilisateur ASC, ordre ASC'; |
//$this->debug[] = $requete; |
//die($requete); |
$resultats = $this->executerRequete($requete); |
$observations = null; |
if ($resultats != false) { |
$observations = array(); |
foreach ($resultats as $occurence) { |
$utilisateur = $occurence['utilisateur']; |
$ordre = $occurence['ordre']; |
if (!array_key_exists($utilisateur, $observations)) { |
$observations[$utilisateur] = array(); |
} |
if (!array_key_exists($ordre, $observations[$utilisateur])) { |
$observations[$utilisateur][$ordre] = $ordre; |
} |
} |
} |
return $observations; |
} |
private function assemblerObsEnConditionSql($observations, $operateur = 'AND') { |
$sql = ''; |
if ($observations != null) { |
// Pré-construction du where de la requête |
$tpl_where = "(identifiant = '%s' AND ordre IN (%s))"; |
foreach ($observations as $utilisateur => $ordres) { |
$morceaux_requete[] = sprintf($tpl_where, $utilisateur, implode(',', $ordres)); |
} |
if (count($morceaux_requete) > 0) { |
$sql = implode(" \nOR ", $morceaux_requete); |
} |
} else { |
// Nous voulons que la requête ne retourne rien |
$sql = "identifiant = '' AND ordre = ''"; |
} |
$sql = " $operateur ($sql) "; |
return $sql; |
} |
private function construireWhereRectangleStation() { |
$sql = ''; |
if (isset($this->parametres['ne']) && isset($this->parametres['sw']) && ! $this->etreNull($this->parametres['ne']) && ! $this->etreNull($this->parametres['sw'])) { |
$ne = $this->decomposerLatLng($this->parametres['ne']); |
$sw = $this->decomposerLatLng($this->parametres['sw']); |
$latMin = $sw['lat']; |
$lngMin = $sw['lng']; |
$latMax = $ne['lat']; |
$lngMax = $ne['lng']; |
// ATTENTION : latitude correspond bien à la LATITUDE! |
$sql = " AND (latitude != 0 AND longitude != 0) ". |
" AND latitude > $latMin ". |
" AND latitude < $latMax ". |
" AND longitude > $lngMin ". |
" AND longitude < $lngMax "; |
} |
return $sql; |
} |
private function construireWhereRectangleStationOR() { |
$sql = ''; |
if (isset($this->parametres['ne']) && isset($this->parametres['sw']) && ! $this->etreNull($this->parametres['ne']) && ! $this->etreNull($this->parametres['sw'])) { |
$ne = $this->decomposerLatLng($this->parametres['ne']); |
$sw = $this->decomposerLatLng($this->parametres['sw']); |
$latMin = $sw['lat']; |
$lngMin = $sw['lng']; |
$latMax = $ne['lat']; |
$lngMax = $ne['lng']; |
$sql = "( (latitude != 0 AND longitude != 0) ". |
" AND latitude BETWEEN $latMin AND $latMax ". |
" AND longitude BETWEEN $lngMin AND $lngMax )"; |
/*$sql = " MBRWithin(mon_point, GeomFromText('POLYGON((".$latMin.' '.$lngMin.','. |
$latMax.' '.$lngMin.','. |
$latMax.' '.$lngMax.','. |
$latMax.' '.$lngMin.','. |
$latMin.' '.$lngMin."))')) "; */ |
} |
return $sql; |
} |
private function construireWhereRectangleCommune() { |
$sql = ''; |
if (isset($this->parametres['ne']) && isset($this->parametres['sw']) && ! $this->etreNull($this->parametres['ne']) && ! $this->etreNull($this->parametres['sw'])) { |
$ne = $this->decomposerLatLng($this->parametres['ne']); |
$sw = $this->decomposerLatLng($this->parametres['sw']); |
$latMin = $sw['lat']; |
$lngMin = $sw['lng']; |
$latMax = $ne['lat']; |
$lngMax = $ne['lng']; |
$sql = "AND wgs84_longitude != 0 AND wgs84_latitude != 0 ". |
" AND wgs84_latitude BETWEEN $latMin AND $latMax ". |
" AND wgs84_longitude BETWEEN $lngMin AND $lngMax "; |
} |
return $sql; |
} |
private function construireWhereRectangleCommuneOR() { |
$sql = ''; |
if (isset($this->parametres['ne']) && isset($this->parametres['sw']) && ! $this->etreNull($this->parametres['ne']) && ! $this->etreNull($this->parametres['sw'])) { |
$ne = $this->decomposerLatLng($this->parametres['ne']); |
$sw = $this->decomposerLatLng($this->parametres['sw']); |
$latMin = $sw['lat']; |
$lngMin = $sw['lng']; |
$latMax = $ne['lat']; |
$lngMax = $ne['lng']; |
$sql = "( wgs84_longitude != 0 AND wgs84_latitude != 0 ". |
" AND wgs84_latitude BETWEEN $latMin AND $latMax ". |
" AND wgs84_longitude BETWEEN $lngMin AND $lngMax )"; |
/*$sql = " MBRWithin(point_commune, GeomFromText('POLYGON((".$latMin.' '.$lngMin.','. |
$latMax.' '.$lngMin.','. |
$latMax.' '.$lngMax.','. |
$latMax.' '.$lngMin.','. |
$latMin.' '.$lngMin."))')) ";*/ |
} |
return $sql; |
} |
private function construireWhereDept() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->parametres); |
if (isset($dept) && !$this->etreNull($dept)) { |
$valeurs_a_proteger = explode(',',trim($dept)); |
foreach ($valeurs_a_proteger as $valeur) { |
$valeurs_protegees[] = '(ce_zone_geo LIKE '.$this->bdd->quote('INSEE-C:'.$valeur.'%').') '; |
} |
$valeurs = implode(' OR ', $valeurs_protegees); |
$sql = " AND ($valeurs) "; |
} |
return $sql; |
} |
private function construireWhereCommune() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->parametres); |
if (isset($this->parametres['commune']) && !$this->etreNull($commune)) { |
$commune = $this->proteger($commune); |
$sql = " AND zone_geo LIKE $commune "; |
} |
return $sql; |
} |
private function construireWhereCommuneSansCoordonneesAvecSensibles() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->parametres); |
if (isset($this->parametres['commune']) && !$this->etreNull($commune)) { |
$commune = $this->proteger($commune); |
$sql = " AND zone_geo LIKE $commune "; |
$sql .= " AND ( |
( |
(latitude = '000null' OR latitude = '' OR latitude = 0 OR latitude IS NULL) ". |
" AND (longitude = '000null' OR longitude = '' OR longitude = 0 OR longitude IS NULL)". |
')'. |
' OR mots_cles_texte LIKE "%sensible%"'. |
') '; |
} |
return $sql; |
} |
private function construireWherePhotosSeulement() { |
$sql = ''; |
if (isset($this->parametres['photos']) && $this->parametres['photos'] == 1) { |
$sql = 'AND co.id_observation IN (SELECT DISTINCT id_observation FROM cel_obs_images) '; |
} |
return $sql; |
} |
private function construireWhereUtilisateur() { |
$sql = ''; |
// TODO tester si l'on recoit un id, un mail ou bien un nom ou prenom |
// pour en faire une fonction polyvalente |
extract($this->parametres); |
if (isset($this->parametres['utilisateur']) && !$this->etreNull($utilisateur)) { |
$utilisateur = $this->proteger($utilisateur); |
$sql = " AND co.courriel_utilisateur = $utilisateur "; |
} |
return $sql; |
} |
private function construireWhereNumTaxon() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->parametres); |
if (isset($this->parametres['num_taxon']) && !$this->etreNull($num_taxon)) { |
$num_taxon = $this->proteger($num_taxon); |
$sql = " AND nt = $num_taxon "; |
} |
return $sql; |
} |
private function construireWhereProjet() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->parametres); |
$projet_sql = isset($projet) ? $this->getSqlWhereProjet($projet) : null; |
if (!$this->etreNull($projet_sql)) { |
$sql = " AND ($projet_sql) "; |
} |
return $sql; |
} |
/** |
* Traitement de $projet pour construction du filtre dans la requête |
*/ |
private function getSqlWhereProjet($projet) { |
$sql = null; |
if (isset($projet) && !$this->etreNull($projet)) { |
$sql = 'co.mots_cles_texte LIKE '.$this->proteger('%'.$projet.'%'); |
} |
return $sql; |
} |
private function construireWhereTag() { |
$sql = ''; |
extract($this->parametres); |
$tag_sql = isset($tag) ? $this->getSqlWhereObsAvecImagesTaguees($tag) : null; |
if (!$this->etreNull($tag_sql)) { |
$sql = " AND ($tag_sql) "; |
} |
return $sql; |
} |
private function construireWhereNombreDeJours() { |
$sql = null; |
extract($this->parametres); |
if (isset($nbjours) && !$this->etreNull($nbjours)) { |
$sql = ' AND DATEDIFF(CURDATE(),co.date_creation) <= '.$this->proteger($nbjours).' '; |
} |
return $sql; |
} |
/** |
* Traitement de $tag pour construction du filtre dans la requête |
*/ |
private function getSqlWhereObsAvecImagesTaguees($tag) { |
$sql = null; |
if (isset($tag) && !$this->etreNull($tag)) { |
$tag_sql = $this->getSqlWhereMotsCles($tag); |
// Construction de la requête |
$requete = 'SELECT DISTINCT coi.id_observation AS id_obs, ci.ce_utilisateur AS utilisateur '. |
'FROM cel_images ci'. |
' LEFT JOIN cel_obs_images coi'. |
' ON (ci.id_image = coi.id_image) '. |
' LEFT JOIN cel_obs AS co '. |
' ON (coi.id_observation = co.id_observation) '. |
' LEFT JOIN cel_zones_geo AS l '. |
" ON (l.nom = co.zone_geo AND l.id_zone_geo = co.ce_zone_geo) ". |
"WHERE transmission = '1' ". |
$this->construireWhereCoordonnees(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereReferentiel(). |
$this->construireWhereProjet(). |
(!$this->etreNull($tag_sql) ? "AND ($tag_sql) " : ''). |
'ORDER BY utilisateur ASC, ci.ordre ASC'; |
//$this->debug[] = $requete; |
//die($requete); |
$elements_tag = $this->executerRequete($requete); |
$requete_tag = array(); |
if ($elements_tag != false && count($elements_tag) > 0) { |
$filtres = array(); |
foreach ($elements_tag as $occurence) { |
$utilisateur = $occurence['utilisateur']; |
$id_obs = $occurence['id_obs']; |
if (!array_key_exists($utilisateur, $filtres)) { |
$filtres[$utilisateur] = array(); |
} |
if (!array_key_exists($id_obs, $filtres[$utilisateur])) { |
$filtres[$utilisateur][$id_obs] = $id_obs; |
} |
} |
// Pré-construction du where de la requête |
$tpl_where = "(id_observation IN (%s))"; |
foreach ($filtres as $utilisateur => $id_obs) { |
$requete_tag[] = sprintf($tpl_where, implode(',', $id_obs)); |
} |
} else { |
$this->messages[] = "Aucune observation ne possède d'images avec ce mot-clé."; |
} |
if (count($requete_tag) > 0) { |
$sql = implode(" \nOR ", $requete_tag); |
} |
} |
return $sql; |
} |
/** |
* Traitement de $tag pour construction du filtre dans la requête |
*/ |
private function getSqlWhereMotsCles($tag) { |
$sql = null; |
$mots_cles = $this->decomposerParametreTag($tag); |
$requete_projet = $this->getSqlWhereMotsClesImages($mots_cles); |
$sql = $requete_projet; |
//$this->debug[] = $sql; |
return $sql; |
} |
/** |
* Traitement de $tag pour construction du filtre dans la requête |
*/ |
private function getSqlWhereMotsClesImages($mots_cles_encodes) { |
$where_mots_cles_images = array(); |
foreach ($mots_cles_encodes['motsClesEncodesProteges'] as $mot_cle_encode) { |
$where_mots_cles_images[] = "ci.mots_cles_texte LIKE $mot_cle_encode"; |
} |
$where_mots_cles_images = implode(' '.$mots_cles_encodes['type'].' ', $where_mots_cles_images); |
return $where_mots_cles_images; |
} |
private function decomposerParametreTag($tags) { |
$mots_cles = array('type' => null, 'motsCles' => null, 'motsClesEncodesProteges' => null); |
if (preg_match('/.+OU.+/', $tags)) { |
$mots_cles['type'] = 'OR'; |
$mots_cles['motsCles'] = explode('OU', $tags); |
} else if (preg_match('/.+ET.+/', $tags)) { |
$mots_cles['type'] = 'AND'; |
$mots_cles['motsCles'] = explode('ET', $tags); |
} else { |
$mots_cles['motsCles'][] = $tags; |
} |
foreach ($mots_cles['motsCles'] as $mot) { |
$mots_cles['motsClesEncodesProteges'][] = $this->bdd->quote('%'.$mot.'%'); |
} |
$this->debug[] = $mots_cles; |
return $mots_cles; |
} |
private function decomposerLatLng($coord) { |
$lat_lng = array(); |
if (isset($coord)) { |
list($lat, $lng) = explode('|', $coord); |
$lat_lng = array('lat' => $lat, 'lng' => $lng); |
} |
return $lat_lng; |
} |
private function decomposerParametreStation() { |
$station_infos = array(); |
if (isset($this->parametres['station'])) { |
$station = $this->parametres['station']; |
$this->debug[] = $station; |
@list($type, $coord) = explode(':', $station); |
@list($lat, $lng) = explode('|', $coord); |
$station_infos = array('type' => $type, 'lat' => $lat, 'lng' => $lng); |
} |
return $station_infos; |
} |
private function decomposerParametreDate() { |
$date_infos = array(null,null); |
if (isset($this->parametres['date'])) { |
$date = $this->parametres['date']; |
if (strpos($date, ':')) { |
list($type, $date) = explode(':', $date); |
} else { |
$type = 'observation'; |
} |
$date = str_replace('/', '-', $date); |
if (preg_match('/(^[0-9]{2})-([0-9]{2})-([0-9]{4}$)/', $date, $matches)) { |
$date = $matches[3].'-'.$matches[2].'-'.$matches[1]; |
} |
$date_infos = array($type, $date); |
} |
return $date_infos; |
} |
private function decomposerParametreTaxon() { |
$nom_infos = array(null,null); |
if (isset($this->parametres['taxon'])) { |
$taxon = $this->parametres['taxon']; |
if (strpos($taxon, ':')) { |
$nom_infos = explode(':', $taxon); |
} else { |
$nom_infos = array('retenu', $taxon); |
} |
} |
return $nom_infos; |
} |
private function decomposerParametreCommentaire() { |
$commentaire_infos = array(null,null); |
if (isset($this->parametres['commentaire'])) { |
$commentaire = $this->parametres['commentaire']; |
if (strpos($commentaire, ':')) { |
$commentaire_infos = explode(':', $commentaire); |
} else { |
$commentaire_infos = array('observation', $commentaire); |
} |
} |
return $commentaire_infos; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryKeyWordImageLink.php |
---|
New file |
0,0 → 1,81 |
<?php |
// declare(encoding='UTF-8'); |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurélien Peronnet <aurelien@tela-botania.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* in : utf8 |
* out : utf8 |
* |
* Service de liaisons de mots clés à des images. |
* Le service lie une ou plusieurs mots clés à une ou plusieurs images |
* |
*/ |
class InventoryKeyWordImageLink extends Cel { |
public function getElement($uid) { |
} |
public function createElement($pairs) { |
// Controle detournement utilisateur |
$this->controleUtilisateur($pairs['ce_utilisateur']); |
if (!isset($pairs['mots_cles']) || !isset($pairs['images']) || !isset($pairs['ce_utilisateur'])) { |
return; |
} |
$pairs['images'] = rtrim($pairs['images'],','); |
$id_images = explode(',',$pairs['images']); |
$pairs['mots_cles'] = rtrim($pairs['mots_cles'],','); |
$mots_cles = explode(',',$pairs['mots_cles']); |
// Pour le moment on ne peut que supprimer les mots clés et ajouter les nouveaux à cause du fonctionnement |
// de l'arbre de mots clés des images |
$gestionnaire_mots_cles = new LiaisonMotsCles($this->config,'images'); |
$suppression_liaison_mot_cle = $gestionnaire_mots_cles->supprimerToutesLiaisonsPourIdImageOuObs($pairs['ce_utilisateur'], $id_images); |
$liaison_mot_cle = $gestionnaire_mots_cles->ajouterLiaisonMotsCles($pairs['ce_utilisateur'],$id_images, $mots_cles); |
return $liaison_mot_cle; |
} |
public function deleteElement($uid){ |
$retour = false; |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if (!isset($uid[0]) || !isset($uid[1]) || !isset($uid[2]) || !$this->estUnIdentifiantMotCle($uid[2])) { |
return; |
} |
$id_images = explode(',',$uid[1]); |
$id_utilisateur = $uid[0]; |
$gestionnaire_mots_cles = new LiaisonMotsCles($this->config,'images'); |
$mots_cles = $gestionnaire_mots_cles->nettoyerMotsCles($uid[2]); |
$mots_cles = explode(',',$mots_cles); |
$suppression_liaison_mot_cle = $gestionnaire_mots_cles->supprimerLiaisonMotsClesEtRegenererIndexTexte($id_utilisateur, $id_images, $mots_cles); |
return $suppression_liaison_mot_cle; |
} |
private function estUnIdentifiantMotCle($chaine) { |
return trim($chaine) != '' && preg_match('/[0-9A-Z]+\.[0-9A-Z]+/i', $chaine); |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/CelSyndicationObservation.php |
---|
New file |
0,0 → 1,565 |
<?php |
/** |
* Service fournissant des informations concernant le CEL au format RSS1, RSS2 ou ATOM. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* Format du service : |
* /CelSyndicationObservation/liste-des-flux |
* /CelSyndicationObservation/opml |
* /CelSyndicationObservation/par-defaut/(rss1|rss2|atom)?start=0&limit=150 |
* /CelSyndicationObservation/pour-admin/(rss1|rss2|atom)?start=0&limit=150 |
* /CelSyndicationObservation/par-mots-cles/(rss1|rss2|atom)/mot-cle?start=0&limit=150 |
* /CelSyndicationObservation/par-commune/(rss1|rss2|atom)/nom-commune?start=0&limit=150 |
* |
* Les paramêtres : |
* - "start" indique le numéro du premier item à afficher |
* - "limit" nombre d'items à afficher |
* |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright 2010 |
*/ |
class CelSyndicationObservation extends Cel { |
private $parametres_origines = null; |
private $format = null; |
private $service = null; |
private $squelette = null; |
private $squelette_dossier = null; |
private $auteurs = array(); |
private $flux = array(); |
private $criteres = array( |
'utilisateur' => 'courriel_utilisateur', |
'commune' => 'zone_geo', |
'dept' => 'ce_zone_geo', |
'taxon' => 'nom_ret', |
'num_taxon' => 'nt', |
'commentaire' => 'commentaire', |
'date' => 'date_observation', |
'motcle' => 'tags', |
'projet' => 'mots-cles'); |
/** |
* Méthode appelée avec une requête de type GET. |
*/ |
public function getElement($params = array()) { |
// Initialisation des variables |
$this->parametres_origines = $params; |
$info = array(); |
$contenu = ''; |
if (! $this->etreFluxAdmin() || $this->authentifierAdmin()) { |
// Pré traitement des paramêtres |
$pour_bdd = false; |
$p = $this->traiterParametres(array('service', 'format'), $params, $pour_bdd); |
extract($p); |
$this->parametres = $params; |
$this->squelette_dossier = dirname(__FILE__).DIRECTORY_SEPARATOR.'squelettes'.DIRECTORY_SEPARATOR; |
// Récupération de la liste des flux |
$this->chargerListeDesFlux(); |
// Chargement du bon type de service demandé |
if (isset($service)) { |
$this->service = $this->traiterNomService($service); |
$methode = $this->getNomMethodeService(); |
if (method_exists($this, $methode)) { |
if (isset($format) && preg_match('/^(?:rss1|rss2|atom)$/i', $format)) { |
// Mise en minuscule de l'indication du format |
$this->format = strtolower($format); |
// Définition du fichier squelette demandé |
$this->squelette = $this->squelette_dossier.$this->format.'.tpl.xml'; |
} else if (isset($this->flux[$this->service])) { |
$this->format = ''; |
$this->messages[] = "Le service CEL Syndication nécessite d'indiquer en second paramètre le format : rss1, rss2 ou atom."; |
} |
if (!isset($this->flux[$this->service]) || isset($this->format)) { |
// Suppression des paramêtres inutile pour le reste des méthodes |
array_shift($this->parametres); |
array_shift($this->parametres); |
// Récupération du contenu à renvoyer |
$contenu = $this->$methode(); |
} |
} else { |
$this->messages[] = "Le type d'information demandé '$this->service' n'est pas disponible."; |
} |
} else { |
$this->messages[] = "Le service CEL Syndication Observation nécessite d'indiquer en premier paramètre le type d'information demandé."; |
} |
} |
// Envoie sur la sortie standard |
$encodage = 'utf-8'; |
$mime = $this->getTypeMime(); |
$formatage_json = $this->getFormatageJson(); |
$this->envoyer($contenu, $mime, $encodage, $formatage_json); |
} |
private function getUrlBase() { |
$url_base = sprintf($this->config['settings']['baseURLAbsolu'], get_class($this).'/'); |
return $url_base; |
} |
private function getUrlServiceBase() { |
$url_service = $this->getUrlBase().implode('/', $this->parametres_origines); |
return $url_service; |
} |
private function traiterNomService($nom) { |
$nom = strtolower($nom); |
return $nom; |
} |
private function getNomMethodeService() { |
$methode = ''; |
$service_formate = str_replace(' ', '', ucwords(implode(' ', explode('-', $this->service)))); |
$methode = 'getService'.$service_formate; |
return $methode; |
} |
private function getTypeMime() { |
$mime = ''; |
$test = isset($this->format) ? $this->format : $this->service; |
switch ($test) { |
case 'atom' : |
$mime = 'application/atom+xml'; |
break; |
case 'rss1' : |
case 'rss2' : |
$mime = 'application/rss+xml'; |
break; |
case 'opml' : |
$mime = 'text/x-opml'; |
break; |
default: |
$mime = 'text/html'; |
} |
return $mime; |
} |
private function getFormatageJson() { |
$json = false; |
switch ($this->service) { |
case 'liste-des-flux' : |
$json = true; |
break; |
default: |
$json = false; |
} |
return $json; |
} |
private function getFlux($nom) { |
return isset($this->flux[$nom]) ? $this->flux[$nom] : array(); |
} |
private function setFlux($nom, $titre, $description) { |
$url_base = $this->getUrlBase(); |
$formats = array('atom', 'rss2', 'rss1'); |
$flux = array(); |
foreach ($formats as $format) { |
$url = $url_base.$nom.'/'.$format; |
$flux[$format] = $url; |
} |
$this->flux[$nom] = array('titre' => $titre, 'description' => $description, 'urls' => $flux); |
} |
private function chargerListeDesFlux() { |
$this->setFlux('par-defaut', 'Flux de syndication des observations publiques du CEL', |
'Ce flux fournit des informations sur les observations du CEL.'); |
$this->setFlux('par-mots-cles', 'Flux de syndication obsolète', |
"Ce flux est désormais accessible via le flux multicriteres/atom/M?tag='mot-cle'."); |
$this->setFlux('par-commune','Flux de syndication obsolète', |
"Ce flux est désormais accessible via le flux multicriteres/atom/M?commune='commune'."); |
$this->setFlux('multicriteres','Flux de syndication des nouvelles observations publiques du CEL '. |
'filtrées par un ou plusieurs critères', |
"Ce flux fournit des informations sur les nouvelles observations du CEL filtrées par ". |
"auteur (mail), commune (nom), departement (code postal), taxon (nom scientifique), commentaire, projet ". |
"et/ou date."); |
} |
private function getServiceListeDesFlux() { |
return $this->flux; |
} |
private function getServiceOpml() { |
$donnees = array(); |
$id = 1; |
foreach ($this->flux as $flux_nom => $flux){ |
$info = array(); |
$info['type'] = 'atom'; |
$info['titre'] = $flux['titre']; |
$info['texte'] = "CEL - Obs - $flux_nom"; |
$info['description'] = $flux['description']; |
$info['url_xml'] = $this->getUrlBase().$flux_nom.'/atom'; |
$info['url_html'] = $this->config['settings']['aideCelUrl'].'FluxSyndication'; |
$donnees['liste_flux'][] = $info; |
} |
$this->squelette = $this->squelette_dossier.'opml.tpl.xml'; |
$contenu = Cel::traiterSquelettePhp($this->squelette, $donnees); |
return $contenu; |
} |
private function getServiceParDefaut() { |
// Construction de la requête |
$requete = (isset($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' * '. |
'FROM cel_obs '. |
(($this->etreFluxAdmin()) ? '' : 'WHERE transmission = 1 '). |
'ORDER BY '.(isset($this->orderby) && (!is_null($this->orderby)) ? $this->orderby : 'date_modification DESC').' '. |
"LIMIT $this->start,$this->limit "; |
$elements = $this->executerRequete($requete); |
// Création du contenu |
$contenu = $this->executerService($elements); |
return $contenu; |
} |
private function getServiceParMotsCles() { |
$infos=array(); |
$infos[0]['nom_sel_nn'] = ''; |
$infos[0]['date_modification'] = '2011-06-28'; |
$donnees = $this->construireDonneesCommunesAuFlux($infos); |
$donnees['items'][0]['guid'] = 0; |
$donnees['items'][0]['description'] = 'Ce flux est devenu obsolète. Veuillez utiliser le flux '. |
'<b>http://www.tela-botanica.org/eflore/cel2/jrest/CelSyndicationObservation/multicriteres/atom?projet='; |
if (isset($this->parametres[0])) { |
$donnees['items'][0]['description'] .= $this->parametres[0].'</b>'; |
} else { |
$donnees['items'][0]['description'] .= '</b>'; |
} |
$donnees['items'][0]['titre'] = ''; |
$contenu = Cel::traiterSquelettePhp($this->squelette, $donnees); |
return $contenu; |
} |
private function getServiceParCommune() { |
$infos=array(); |
$infos[0]['nom_sel_nn'] = ''; |
$infos[0]['date_modification'] = '2011-06-28'; |
$donnees = $this->construireDonneesCommunesAuFlux($infos); |
$donnees['items'][0]['guid'] = 0; |
$donnees['items'][0]['description'] = 'Ce flux est devenu obsolète. Veuillez utiliser le flux '. |
'<b>http://www.tela-botanica.org/eflore/cel2/jrest/CelSyndicationObservation/multicriteres/atom?commune='; |
if (isset($this->parametres[0])) { |
$donnees['items'][0]['description'] .= $this->parametres[0].'</b>'; |
} else { |
$donnees['items'][0]['description'] .= '</b>'; |
} |
$donnees['items'][0]['titre'] = ''; |
$contenu = Cel::traiterSquelettePhp($this->squelette, $donnees); |
return $contenu; |
} |
private function getServiceMultiCriteres() { |
$contenu = ''; |
if (isset($_GET['debut'])) $this->start = $_GET['debut']; |
if (isset($_GET['limite'])) $this->limite = $_GET['limite']; |
// Construction de la requête |
$requete = (isset($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' * '. |
'FROM cel_obs '. |
'WHERE 1 AND '.(($this->etreFluxAdmin()) ? '' : ' transmission = 1 AND '); |
if ($this->estUneRechercheGenerale()) { |
$chaine_requete = $_GET['recherche']; |
$requete .= $this->creerSousRequeteRechercheGenerale($chaine_requete); |
} else { |
$criteres = $this->traiterCriteresMultiples($_GET) ; |
if (!empty($criteres)) { |
$requete .= $this->creerSousRequeteRechercheParCriteres($criteres); |
} |
} |
$requete = rtrim($requete, 'AND '); |
$requete .= ' ORDER BY '.(isset($this->orderby) && (!is_null($this->orderby)) ? $this->orderby : |
'date_modification DESC, zone_geo ASC').' '. |
"LIMIT $this->start,$this->limit "; |
$elements = $this->executerRequete($requete); |
// Création du contenu |
if ($elements != false && count($elements) > 0) { |
$contenu = $this->executerService($elements); |
} else { |
$this->messages[] = "Aucune observation disponible."; |
} |
return $contenu; |
} |
private function creerSousRequeteRechercheParCriteres($criteres) { |
$requete = ''; |
foreach ($criteres as $pair) { |
$nom_valeur = explode("=",$pair); |
if (sizeof($nom_valeur) != 0) { |
switch ($nom_valeur[0]) { |
case "ci_limite" : $this->limite = $this->bdd->quote($nom_valeur[1]); break; |
case "commentaire" : $mots_comment_liste = explode(" " , $nom_valeur[1]); |
foreach($mots_comment_liste as $mot_comment) { |
$mot_comment = trim($mot_comment) ; |
$requete .= $nom_valeur[0].' LIKE '.$this->bdd->quote('%'.$mot_comment.'%').' AND '; |
} |
break; |
case "date_observation" : |
$nom_valeur[1] = str_replace('/', '-', $nom_valeur[1]); |
if (preg_match('/(^[0-9]{2})-([0-9]{2})-([0-9]{4}$)/', $nom_valeur[1], $matches)) { |
$nom_valeur[1] = $matches[3].'-'.$matches[2].'-'.$matches[1]; |
} |
$requete .= $nom_valeur[0].'='.$this->bdd->quote($nom_valeur[1]).' AND '; break; |
case "ce_zone_geo" : |
$requete .= ' ('.$nom_valeur[0].' LIKE "INSEE-C:'.$nom_valeur[1].'%") AND '; break; |
case "nom_ret" : |
if ($nom_valeur[1] == "indetermine") $nom_valeur[1] = 'null'; |
$requete .= ' ('.$nom_valeur[0].' LIKE "%'.$nom_valeur[1].'%" OR nom_sel LIKE "%'. |
$nom_valeur[1].'%") AND '; break; |
case "mots-cles" : $requete .= $this->creerSousRequeteMotsCles($nom_valeur[1]).' AND '; break; |
case "tags" : $requete .= $this->creerSousRequeteTags($nom_valeur[1]).' AND '; break; |
default : $requete .= $nom_valeur[0].' = "'.$nom_valeur[1].'" AND '; break; |
} |
} |
} |
$requete = rtrim($requete,' AND '); |
return $requete; |
} |
private function creerSousRequeteMotsCles($mot_cle) { |
$requete = ''; |
if (preg_match('/.*OU.*/', $mot_cle)) { |
$mots_cles_tab = explode('OU',$mot_cle); |
foreach($mots_cles_tab as $mot_cle_item) { |
$requete .= '(mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') OR '; |
} |
$requete = '('.rtrim($requete,'OR ').') '; |
} else if (preg_match('/.*ET.*/', $mot_cle)) { |
$mots_cles_tab = explode('ET',$mot_cle); |
foreach($mots_cles_tab as $mot_cle_item) { |
$requete .= '(mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') AND '; |
} |
$requete = '('.rtrim($requete, 'AND ').') '; |
} else { |
$requete = "(mots_cles_texte LIKE ".$this->proteger('%'.$mot_cle.'%').') '; |
} |
return $requete; |
} |
private function creerSousRequeteTags($tag) { |
$requete = '(id_observation IN (SELECT id_observation FROM cel_obs_images coi INNER JOIN cel_images ci ON coi.id_image = ci.id_image WHERE '; |
$where = ''; |
if (preg_match('/.*OU.*/', $tag)) { |
$mots_cles_tab = explode('OU',$tag); |
foreach($mots_cles_tab as $mot_cle_item) { |
$where .= '(ci.mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') OR '; |
} |
$where .= '('.rtrim($where,'OR ').') '; |
} else if (preg_match('/.*ET.*/', $tag)) { |
$mots_cles_tab = explode('ET',$tag); |
foreach($mots_cles_tab as $mot_cle_item) { |
$where .= '(ci.mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') AND '; |
} |
$where .= '('.rtrim($where, 'AND ').') '; |
} else { |
$where .= "(ci.mots_cles_texte LIKE ".$this->proteger('%'.$tag.'%').') '; |
} |
$requete .= $where.' ))'; |
return $requete; |
} |
private function traiterCriteresMultiples($tableau_criteres) { |
$tableau_criteres_pour_bdd = array(); |
foreach($tableau_criteres as $nom_critere => $valeur_critere) { |
if (isset($this->criteres[$nom_critere])) { |
$tableau_criteres_pour_bdd[] = $this->criteres[$nom_critere].'='.$valeur_critere; |
} |
} |
return $tableau_criteres_pour_bdd; |
} |
private function creerSousRequeteRechercheGenerale($chaine_requete) { |
$requete = ''; |
if (trim($chaine_requete) != '') { |
$chaine_requete = strtolower($chaine_requete); |
$chaine_requete = str_replace(' ', '_', $chaine_requete); |
$requete = ' ('. |
'nom_ret LIKE "'.$chaine_requete.'%"'. |
' OR '. |
'nom_sel LIKE "'.$chaine_requete.'%"'. |
' OR '. |
'zone_geo LIKE "'.$chaine_requete.'%" '. |
' OR '. |
'ce_zone_geo LIKE "'.$chaine_requete.'%" '. |
' OR '. |
'ce_zone_geo LIKE "INSEE-C:'.$chaine_requete.'%" '. |
' OR '. |
'courriel_utilisateur LIKE "'.$chaine_requete.'%" '. |
' OR '. |
'mots_cles_texte LIKE "'.$chaine_requete.'%" '. |
') '; |
} |
return $requete; |
} |
private function estUneRechercheGenerale() { |
return isset($_GET['recherche']); |
} |
private function executerService($elements) { |
$contenu = ''; |
if (is_array($elements)) { |
// Prétraitement des données |
$donnees = $this->construireDonneesCommunesAuFlux($elements); |
foreach ($elements as $element) { |
$identifiants[$element['courriel_utilisateur']] = $element['courriel_utilisateur']; |
} |
$this->auteurs = $this->creerAuteurs($identifiants); |
foreach ($elements as $element) { |
$donnees['items'][] = $this->construireDonneesCommunesAuxItems($element); |
} |
// Création du contenu à partir d'un template PHP |
if (isset($this->squelette)) { |
$contenu = Cel::traiterSquelettePhp($this->squelette, $donnees); |
} |
} |
return $contenu; |
} |
private function construireDonneesCommunesAuFlux($observations) { |
$donnees = $this->getFlux($this->service); |
$donnees['guid'] = $this->getUrlServiceBase(); |
$donnees['titre'] = 'Flux des observations du CEL'; |
$donnees['lien_service'] = $this->creerUrlService(); |
$donnees['lien_cel'] = $this->config['settings']['baseURLAbsolu']; |
$donnees['editeur'] = $this->config['settings']['editeur']; |
$derniere_info_en_date = reset($observations); |
$date_modification_timestamp = strtotime($derniere_info_en_date['date_modification']); |
$donnees['date_maj_RSS'] = date(DATE_RSS, $date_modification_timestamp); |
$donnees['date_maj_ATOM'] = date(DATE_ATOM, $date_modification_timestamp); |
$donnees['date_maj_W3C'] = date(DATE_W3C, $date_modification_timestamp); |
$donnees['annee_courante'] = date('Y'); |
$donnees['generateur'] = 'CEL - Jrest - CelSyndicationObservation'; |
$donnees['generateur_version'] = (preg_match('/([0-9]+)/', '$Revision$', $match)) ? $match[1] : '0'; |
return $donnees; |
} |
private function construireDonneesCommunesAuxItems($observation) { |
$item = array(); |
$date_modification_timestamp = $this->convertirDateHeureMysqlEnTimestamp($observation['date_modification']); |
$item['date_maj_simple'] = strftime('%A %d %B %Y à %H:%M', $date_modification_timestamp); |
$item['date_maj_RSS'] = date(DATE_RSS, $date_modification_timestamp); |
$item['date_maj_ATOM'] = date(DATE_ATOM, $date_modification_timestamp); |
$item['date_maj_W3C'] = date(DATE_W3C, $date_modification_timestamp); |
$item['date_creation_simple'] = strftime('%A %d %B %Y à %H:%M', strtotime($observation['date_creation'])); |
$item['titre'] = $this->creerTitre($observation); |
$item['guid'] = $this->creerGuidItem($observation); |
$item['lien'] = $this->creerLienItem($observation); |
$item['categorie'] = $this->creerCategorie($item); |
$item['description'] = $this->creerDescription($this->protegerCaracteresHtmlDansChamps($observation), $item); |
$item['description_encodee'] = htmlspecialchars($this->creerDescription($observation, $item)); |
$item['modifier_par'] = $observation['id_observation']; |
return $item; |
} |
private function creerTitre($obs) { |
$date = ($obs['date_observation'] != '0000-00-00 00:00:00') ? 'le '.date("d/m/Y", strtotime($obs['date_observation'])) : '' ; |
$nom_plante = $obs['nom_sel'].' [nn'.$obs['nom_sel_nn'].']'; |
$lieu = $obs['zone_geo'].' ('.$obs['ce_zone_geo'].')'; |
$utilisateur = $this->getIntituleAuteur($obs['courriel_utilisateur']); |
$titre = "$nom_plante à $lieu par $utilisateur $date"; |
$titre = $this->nettoyerTexte($titre); |
return $titre; |
} |
private function creerGuidItem($element) { |
$guid = sprintf($this->config['settings']['guidObsTpl'], $element['id_observation']); |
return $guid; |
} |
private function creerLienItem($element) { |
$lien = null; |
if ($element['nom_sel_nn'] != 0) { |
$lien = sprintf($this->config['settings']['efloreUrlTpl'], urlencode($element['nom_sel_nn']), 'cel'); |
} |
return $lien; |
} |
private function creerDescription($obs, $item) { |
$id_obs = $obs['id_observation']; |
$famille = $obs['famille']; |
$nom_saisi = $obs['nom_sel']; |
$nom_retenu = $obs['nom_ret']; |
$auteur = $this->getIntituleAuteur($obs['courriel_utilisateur']); |
$auteur_mail = $obs['courriel_utilisateur']; |
$mots_cles_obs = $obs['mots_cles_texte']; |
$lien_correction = sprintf($this->config['settings']['phpEditUrlTpl'], $obs['id_observation']); |
$lieu = $obs['zone_geo'].' ('.$this->convertirCodeZoneGeoVersCodeInsee($obs['ce_zone_geo']).') > '.$obs['lieudit'].' > '.$obs['station']; |
$milieu = $obs['milieu']; |
$coordonnees = ($this->etreNull($obs['latitude']) && $this->etreNull($obs['longitude'])) ? '' : $obs['latitude'].'/'.$obs['longitude']; |
$commentaire = $obs['commentaire']; |
$date_observation = ($obs['date_observation'] != '0000-00-00 00:00:00') ? $this->formaterDate($obs['date_observation'], '%A %d %B %Y') : ''; |
$date_transmission = $this->formaterDate($obs['date_transmission']); |
$date_modification = $this->formaterDate($obs['date_modification']); |
$date_creation = $this->formaterDate($obs['date_creation']); |
$transmission = $obs['transmission'] == 1 ? "oui ($date_transmission)" : 'non'; |
$description = '<h2>'."Observation #$id_obs de $nom_saisi".'</h2>'. |
'<ul>'. |
'<li>'.'Famille : '.$famille.'</li>'. |
'<li>'.'Nom saisi : '.$nom_saisi.'</li>'. |
'<li>'.'Nom retenu : '.$nom_retenu.'</li>'. |
'<li>'.'Observée le : '.$date_observation.'</li>'. |
'<li>'.'Lieu : '.$lieu.'</li>'. |
'<li>'.'Milieu : '.$milieu.'</li>'. |
(($this->etreFluxAdmin()) ? '<li>Coordonnées (Lat/Long) : '.$coordonnees.'</li>' : ''). |
'<li>'.'Commentaire : '.$commentaire.'</li>'. |
'<li>'.'Mots-clés : '.$mots_cles_obs.'</li>'. |
(($this->etreFluxAdmin()) ? '<li>Transmis (= public) : '.$transmission.'</li>' : ''). |
'<li>Modifiée le : '.$date_modification.'</li>'. |
'<li>Créée le : '.$date_creation.'</li>'. |
'<li>'.'Par : '. |
(($this->etreFluxAdmin()) ? '<a href="mailto:'.$auteur_mail.'">'.$auteur.'</a>' : $auteur). |
'</li>'. |
(($this->etreFluxAdmin()) ? '<li><a href="'.$lien_correction.'">Corriger cette observation</a></li>' : ''). |
'</ul>'; |
$description = $this->nettoyerTexte($description); |
return $description; |
} |
private function creerCategorie($element) { |
$categorie = ''; |
$categorie = 'Observation'; |
$categorie = $this->nettoyerTexte($categorie); |
return $categorie; |
} |
private function etreFluxAdmin() { |
return (isset($_GET['admin']) && $_GET['admin'] == '1') ? true : false; |
} |
private function creerUrlService() { |
$url_service = $this->getUrlServiceBase(); |
if (count($_GET) > 0) { |
$parametres_get = array(); |
foreach ($_GET as $cle => $valeur) { |
$parametres_get[] = $cle.'='.$valeur; |
} |
$url_service .= '?'.implode('&', $parametres_get); |
} |
return $url_service; |
} |
private function getIntituleAuteur($courriel) { |
$courriel = strtolower($courriel); |
if(isset($this->auteurs[$courriel])) { |
$intitule = $this->auteurs[$courriel]; |
} else { |
$intitule = $courriel; |
} |
return $intitule; |
} |
} |
/branches/v1.6-croc/jrest/services/InventoryKeyWordObsLink.php |
---|
New file |
0,0 → 1,74 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurélien Peronnet <aurelien@tela-botania.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* in : utf8 |
* out : utf8 |
* |
* Service de liaisons de mots clés à des observations. |
* Le service lie une ou plusieurs mots clés à une ou plusieurs observations |
* |
*/ |
class InventoryKeyWordObsLink extends Cel { |
public function getElement($uid) { |
} |
public function createElement($pairs) { |
// Controle detournement utilisateur |
$this->controleUtilisateur($pairs['ce_utilisateur']); |
if (!isset($pairs['mots_cles']) || !isset($pairs['observations']) || !isset($pairs['ce_utilisateur'])) { |
return; |
} |
$ids_obs = explode(',',$pairs['observations']); |
$mots_cles = explode(',',$pairs['mots_cles']); |
$gestionnaire_mots_cles = new LiaisonMotsCles($this->config,'obs'); |
$liaison_mot_cle = $gestionnaire_mots_cles->ajouterLiaisonMotsCles($pairs['ce_utilisateur'],$ids_obs, $mots_cles); |
return $liaison_mot_cle; |
} |
public function deleteElement($uid){ |
$retour = false; |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if (!isset($uid[0]) || !isset($uid[1]) || !isset($uid[2]) || !$this->estUnIdentifiantMotCle($uid[2])) { |
return; |
} |
$ids_obs = explode(',',$uid[1]); |
$id_utilisateur = $uid[0]; |
$gestionnaire_mots_cles = new LiaisonMotsCles($this->config,'obs'); |
$mots_cles = $gestionnaire_mots_cles->nettoyerMotsCles($uid[2]); |
$mots_cles = explode(',',$mots_cles); |
$suppression_liaison_mot_cle = $gestionnaire_mots_cles->supprimerLiaisonMotsClesEtRegenererIndexTexte($id_utilisateur, $ids_obs, $mots_cles); |
return $suppression_liaison_mot_cle; |
} |
private function estUnIdentifiantMotCle($chaine) { |
return trim($chaine) != '' && preg_match('/[0-9A-Z]+\.[0-9A-Z]+/i', $chaine); |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryPDF.php |
---|
New file |
0,0 → 1,248 |
<?php |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david.delon@clapas.net> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** Constante stockant l'URL de la page d'accueil de Photoflora.*/ |
define('EF_URL_PHOTOFLORA', 'http://photoflora.free.fr/'); |
/** Constante stockant l'URL de la page de Photoflora affichant toutes les images d'un taxon donn.es.*/ |
define('EF_URL_PHOTOFLORA_TAXON', EF_URL_PHOTOFLORA.'FiTax.php?NumTaxon=%s'); |
/** Constante stockant l'URL du dossier de photoflora contenant les images miniatures.*/ |
define('EF_URL_PHOTOFLORA_IMG_MIN', 'http://www.tela-botanica.org/~photoflo/photos/%s/min/%s'); |
/** Constante stockant l'URL du dossier de photoflora contenant les images normale.*/ |
define('EF_URL_PHOTOFLORA_IMG_MAX', 'http://www.tela-botanica.org/~photoflo/photos/%s/max/%s'); |
/** Constante stockant l'expression r.guli.re r.cup.rant l'abr.viation du photographe et le nom du fichier.*/ |
define('EF_URL_PHOTOFLORA_REGEXP', '/\/photos\/([^\/]+)\/max\/(.+)$/'); |
/** Constante stockant l'URL du service XML de Photoflora.*/ |
define('EF_URL_PHOTOFLORA_SERVICE', EF_URL_PHOTOFLORA.'ef_photoflora.php?nt=%s'); |
/** |
* InventoryPDF.php |
* |
* in : utf8 |
* out : iso8859 |
* |
* Formatage pdf d'un releve (a revoir) |
*/ |
class InventoryPDF extends Cel { |
var $extendPDFProductor; |
function InventoryPDF($config) { |
parent::__construct($config); |
$this->config=$config; |
// Pas d'heritage multiple en php :( |
$this->extendPDFProductor = new PDFProductor(); |
$this->extendPDFProductor->initPDF(); |
} |
/** |
* uid[0] : utilisateur obligatoire |
* uid[1] : si absent : valeur 'all' (commune) |
* uid[2] : si absent : valeur 'all' (date) |
* uid[3] : si absent : valeur 'all' (recherche libre) |
* uid[4] : si absent : valeur 'all' (station) |
*/ |
function getElement($uid){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if (!isset($uid[1]) || $uid[1]=="" || $uid[1]=="all" ) { |
$uid[1]="all"; |
$requete_location=""; |
} |
else { |
$requete_location=" AND location= ".$this->proteger($uid[1])." "; |
} |
if (!isset($uid[2]) || $uid[2]=="" || $uid[2]=="all") { |
$uid[2]="all"; |
$requete_date=""; |
} |
else { |
$requete_date=" AND date_observation= ".$this->proteger($uid[2])." "; |
} |
if (!isset($uid[3]) || $uid[3]=="" || $uid[3]=="all") { |
$uid[3]="all"; |
$requete_libre=""; |
} |
else { |
$requete_libre=" AND (nom_sel LIKE ".$this->proteger('%'.$uid[3].'%'). |
" OR nom_ret LIKE ".$this->proteger('%'.$uid[3].'%'). |
" OR station LIKE ".$this->proteger('%'.$uid[3].'%'). |
" OR commentaire LIKE ".$this->proteger('%'.$uid[3].'%'); |
} |
if (!isset($uid[4]) || $uid[4]=="" || $uid[4]=="all") { |
$uid[4]="all"; |
$requete_station=""; |
} |
else { |
$requete_station=" AND station= ".$this->proteger($uid[4])." "; |
} |
$value=array(); |
$requete="SELECT ce_utilisateur, ordre, nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, nt, famille, zone_geo, date_observation," . |
" station, commentaire, transmission FROM cel_obs WHERE ce_utilisateur = ".$this->proteger($uid[0])." " . |
$requete_location. |
$requete_date. |
$requete_libre. |
$requete_station. |
" ORDER BY ordre "; |
$resultat_requete = $this->requeter($requete); |
$observations = array();; |
if(is_array($resultat_requete)) { |
$observations = $resultat_requete; |
} |
// Set up the pdf object. |
$pdf = &File_PDF::factory(array('orientation' => 'P', 'format' => 'A4')); |
// DesActivate compression. |
$pdf->setCompression(false); |
$pdf->setMargins(0, 0); |
// Enable automatic page breaks. |
$pdf->setAutoPageBreak(true); |
// Start the document. |
$pdf->open(); |
// Start a page. |
$pdf->addPage(); |
$pdf->setFont('Times', '' , 12); |
$i=1; |
$tempfn = tempnam("",""); |
foreach ($observations as $obs) { |
// Denullifiage |
foreach($obs as $k=>$v) { |
if (($v=="null") || ($v=="000null")) { |
$obs[$k]=""; |
} |
else { |
$obs[$k]=utf8_decode($v); |
} |
} |
if ($obs['date_observation']!="0000-00-00 00:00:00") { |
list($year,$month,$day)= explode('-',$obs['date_observation']); |
list($day)= explode(' ',$day); |
$obs['date_observation']=$day."/".$month."/".$year; |
} |
else { |
$obs['date_observation']="00/00/0000"; |
} |
$text= $obs['nom_sel']." ".$obs['nom_sel_nn']." ".$obs['nom_ret']." ".$obs['nom_ret_nn']." ".$obs['nt']." ". |
$obs['famille']." ".$obs['zone_geo']." ".$obs['ce_zone_geo']." ".$obs['date_observation']." ".$obs['station']; |
$obs['commentaire']; |
$pdf->write(10, $text."\n"); |
$projet_photo = 'photoflora'; |
$tab_retour[$projet_photo]=chercherIllustrationsServiceXml(sprintf(EF_URL_PHOTOFLORA_SERVICE, $obs['nt'])); |
$url_miniature =''; |
foreach ($tab_retour[$projet_photo] as $cle => $illustration) { |
if (preg_match(EF_URL_PHOTOFLORA_REGEXP, $illustration['about'], $match)) { |
$abreviation = $match[1]; |
$fichier = $match[2]; |
$url_miniature = sprintf(EF_URL_PHOTOFLORA_IMG_MIN, $abreviation, $fichier);; |
// Priorite aux images en png |
if (strstr($fichier, '.png')) { |
break; |
} |
} |
} |
if ($url_miniature!='') { |
list($debut,$ext)=explode("\.",basename($url_miniature)); |
$temp = fopen($tempfn, "w"); |
$buf=file_get_contents($url_miniature); |
fwrite($temp,$buf); |
fclose($temp); |
$pdf->image($tempfn,10,($i*10),0,0,$ext); |
} |
$i++; |
} |
echo $pdf->output("Rapport"); |
} |
} |
function chercherIllustrationsServiceXml($url) |
{ |
return analyserFichierRdf($url); |
} |
function analyserFichierRdf($chemin) |
{ |
$aso_info = array(); |
$dom = new DOMDocument(); |
$dom->validateOnParse = true; |
if (preg_match('/^http:\/\//', $chemin)) { |
$dom->loadXML(file_get_contents($chemin)); |
} else { |
$dom->load($chemin); |
} |
$tab_infos = array(); |
foreach ($dom->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'Description') as $rdf_description) { |
$aso_info['about'] = $rdf_description->getAttribute('about'); |
$aso_info['dc:identifier'] = $rdf_description->getAttribute('identifier'); |
$aso_info['dc:title'] = utf8_decode($rdf_description->getAttribute('title')); |
$aso_info['dc:creator'] = utf8_decode($rdf_description->getAttribute('creator')); |
$aso_info['dc:contributor'] = utf8_decode($rdf_description->getAttribute('contributor')); |
$aso_info['dc:publisher'] = utf8_decode($rdf_description->getAttribute('publisher')); |
$aso_info['dc:type'] = utf8_decode($rdf_description->getAttribute('type')); |
$aso_info['dc:format'] = utf8_decode($rdf_description->getAttribute('format')); |
if (function_exists('date_default_timezone_set')) { |
date_default_timezone_set('Europe/Paris'); |
} |
if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $rdf_description->getAttribute('created'))) { |
$aso_info['dcterms:created'] = date('j-m-Y � H:i:s', strtotime($rdf_description->getAttribute('created'))); |
} else { |
$aso_info['dcterms:created'] = $rdf_description->getAttribute('created'); |
} |
$aso_info['dcterms:dateSubmitted'] = utf8_decode($rdf_description->getAttribute('dateSubmitted')); |
$aso_info['dcterms:spatial'] = utf8_decode($rdf_description->getAttribute('spatial')); |
$aso_info['dcterms:licence'] = utf8_decode($rdf_description->getAttribute('licence')); |
$tab_infos[$rdf_description->getAttribute('identifier')] = $aso_info; |
} |
return $tab_infos; |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.2 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.1 2007-06-06 13:31:16 ddelon |
* v0.09 |
* |
* Revision 1.4 2007-05-22 12:54:09 ddelon |
* Securisation acces utilisateur |
* |
*/ |
?> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v1.6-croc/jrest/services/InventoryImport.php |
---|
New file |
0,0 → 1,60 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david.delon@clapas.net> |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* InventoryImport.php |
* |
* in : utf8 |
* out : utf8 |
* |
* Cas d'utilisation : |
* Service importation releve en cours |
* |
* 1 : L'utilisateur à traiter est communique au service |
* 2 : Les releves associés à la session en cours sont transferés à l'utilisateur identifié |
*/ |
class InventoryImport extends Cel { |
function getElement($uid){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
$id_session_temporaire = session_id(); |
$gestionnaire_observation = new GestionObservation($this->config); |
$migration_compte_a_compte = $gestionnaire_observation->migrerObservations($id_session_temporaire, $uid[0]); |
$retour = false; |
if($migration_compte_a_compte) { |
$retour = 'OK'; |
} |
echo $retour; |
exit; |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.3 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.2 2007-05-22 12:54:09 ddelon |
* Securisation acces utilisateur |
* |
* Revision 1.1 2007-05-21 18:12:20 ddelon |
* Gestion des importations locale de releves |
*/ |
?> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v1.6-croc/jrest/services/InventoryUserList.php |
---|
New file |
0,0 → 1,101 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* |
* Liste des utilisateurs du cel, par défaut les 50 premiers |
* ou bien commencant par la chaine fournie en paramètre |
* |
* in=utf8 |
* out utf8 |
* |
**/ |
class InventoryUserList extends Cel { |
function getElement($uid){ |
$this->controleUtilisateur($uid[0]); |
$requete_utilisateurs ='SELECT DISTINCT id_utilisateur, courriel FROM cel_utilisateurs '. |
$this->construireRequeteConditionTableUtilisateurs($uid).' '. |
'UNION '. |
'SELECT DISTINCT ce_utilisateur as id_utilisateur, courriel_utilisateur as courriel '. |
'FROM cel_obs '. |
$this->construireRequeteConditionTableObs($uid).' '. |
'LIMIT 0,50'; |
$utilisateurs = $this->executerRequete($requete_utilisateurs); |
$liste_utilisateurs = array(); |
if (!$utilisateurs) { |
} else { |
foreach ($utilisateurs as $utilisateur) { |
$liste_utilisateurs[] = $utilisateur; |
} |
} |
usort($liste_utilisateurs,'trierUtilisateurs'); |
$this->envoyerJson($liste_utilisateurs); |
return true; |
} |
private function construireRequeteConditionTableUtilisateurs($params) { |
$condition = ''; |
if (isset($params[1]) && $params[1] != null && $params[1] != '*') { |
$condition .= ' WHERE courriel LIKE '.$this->proteger($params[1].'%'); |
} |
return $condition; |
} |
private function construireRequeteConditionTableObs($params) { |
$condition = ''; |
if (isset($params[1]) && $params[1] != null && $params[1] != '*') { |
$condition .= ' WHERE courriel_utilisateur LIKE '.$this->proteger($params[1].'%'); |
} |
return $condition; |
} |
} |
function trierUtilisateurs($val1, $val2) { |
if (strstr($val1['courriel'],'@')) { |
if (strstr($val2['courriel'],'@')) { |
return strcmp($val1['courriel'],$val2['courriel']); |
} |
else |
{ |
return -1 ; |
} |
} |
else |
{ |
if (strstr($val2['courriel'],'@')) { |
return 1 ; |
} |
else |
{ |
return strcmp($val1['courriel'],$val2['courriel']) ; |
} |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/CelImageDoublon.php |
---|
New file |
0,0 → 1,149 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Service fournissant une liste d'images doublon pour l'utilisateur qui s'authentifie. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* Cas d'utilisation : |
* /CelImageDoublon/Sortie : images doublon de l'utilisateur authentifié. |
* |
* Sortie = Type de sortie : html ou json. Par défaut : html |
* |
* Utilisateur : |
* identifiant (= courriel) de l'utilisateur récupéré via une identification HTTP. |
* |
* @author Jean-Pascal MILCENT <jpm@clapas.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2010, Jean-Pascal MILCENT |
*/ |
class CelImageDoublon extends Cel { |
/** |
* Méthode appelée avec une requête de type GET. |
*/ |
public function getElement($params) { |
$parametres = $this->traiterParametres(array('mode', 'utilisateur'), $params, false); |
extract($parametres); |
$contenu = ''; |
if ($this->authentifierUtilisateur()) { |
$retour = null; |
if (isset($mode)) { |
$methode = $this->traiterNomMethodeGet($mode); |
if (method_exists($this, $methode)) { |
$retour = $this->$methode($parametres); |
} else { |
$service = get_class($this); |
$this->messages[] = "Ce type de mode '$mode' pour le service '$service' n'est pas disponible."; |
} |
} else { |
$this->messages[] = "Vous devez indiquer un type de mode."; |
} |
if (is_null($retour)) { |
$contenu = 'Un problème est survenu : '.print_r($this->messages, true); |
} else { |
if ($retour['type'] == 'widget') { |
$squelette = dirname(__FILE__).DIRECTORY_SEPARATOR.'squelettes'.DIRECTORY_SEPARATOR.$retour['squelette'].'.tpl.html'; |
$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']); |
} else if ($retour['type'] == 'json') { |
$contenu = $retour['donnees']; |
} |
} |
} |
// Envoie sur la sortie standard |
$encodage = 'UTF-8'; |
$mime = 'text/html'; |
$formatage_json = (isset($retour) && $retour['type'] == 'json') ? true : false; |
$this->envoyer($contenu, $mime, $encodage, $formatage_json); |
} |
/** |
* Carte par défaut |
*/ |
private function getDoublonHtml($parametres) { |
$widget = null; |
$utilisateur_mail = $this->getAuthIdentifiant(); |
$utilisateur_infos = new User($this->config); |
$utilisateur = $utilisateur_infos->obtenirUtilisateurSiExiste($utilisateur_mail); |
$utilisateur = $utilisateur['id_utilisateur']; |
// Création des infos du widget |
$widget['type'] = 'widget'; |
$widget['donnees']['utilisateur'] = $utilisateur_mail; |
$widget['donnees']['doublons'] = $this->getImagesDoublon($utilisateur); |
$widget['squelette'] = 'doublon_defaut'; |
return $widget; |
} |
/** |
* Images en doublon d'un utilisateur |
*/ |
private function getImagesDoublon($utilisateur) { |
$doublons = null; |
if (isset($utilisateur)) { |
// Un utilisateur en particulier |
$requete = 'SELECT id_image, ordre, nom_original, md5 '. |
'FROM cel_images '. |
"WHERE ce_utilisateur = '$utilisateur' "; |
$images = $this->executerRequete($requete); |
// Traitement |
$doublons = array(); |
$images_doublons_id = array(); |
$md5 = array(); |
foreach ($images as $img) { |
if (!isset($md5[$img['md5']])) { |
$md5[$img['md5']] = array( |
'url' => $this->getUrlImage($img['id_image'], 'CXS'), |
'obs_ordre' => array(), |
'img_ordre' => $img['ordre'], |
'img_id' => $img['id_image']); |
} else { |
if (!isset($doublons[$img['md5']])) { |
$id_img = $md5[$img['md5']]['img_id']; |
$doublons[$img['md5']][$id_img] = $md5[$img['md5']]; |
$images_doublons_id[] = $this->bdd->quote($id_img); |
} |
$doublons[$img['md5']][$img['id_image']] = array( |
'url' => $this->getUrlImage($img['id_image'], 'CXS'), |
'obs_ordre' => array(), |
'img_ordre' => $img['ordre'], |
'img_id' => $img['id_image']); |
$images_doublons_id[] = $this->bdd->quote($img['id_image']); |
} |
} |
if (count($images_doublons_id) > 0) { |
$requete = 'SELECT cim.id_image, nom_original, md5, co.ordre as ordre_obs '. |
'FROM cel_images AS cim '. |
' LEFT JOIN cel_obs_images AS coi '. |
' ON (coi.id_image = cim.id_image) '. |
' LEFT JOIN cel_obs AS co '. |
' ON (coi.id_observation = co.id_observation) '. |
"WHERE cim.ce_utilisateur = '$utilisateur' ". |
' AND cim.id_image IN ('.implode(',', $images_doublons_id).')'; |
$infos = $this->executerRequete($requete); |
foreach ($infos as $info) { |
if (isset($doublons[$info['md5']][$info['id_image']]) && ! $this->etreNull($info['ordre_obs'])) { |
$doublons[$info['md5']][$info['id_image']]['obs_ordre'][] = $info['ordre_obs']; |
} |
} |
} |
} |
return $doublons; |
} |
} |
/branches/v1.6-croc/jrest/services/CelValidationObservation.php |
---|
New file |
0,0 → 1,59 |
<?php |
class CelValidationObservation extends Cel { |
/** |
* Méthode appelée avec une requête de type POST avec un identifiant d'obs. |
* Modifie le taxon associé à une observation avec les informations envoyées |
* |
* @param int $uid[0] identifiant observation |
* @param pairs array tableau contenant les valeurs à modifier |
*/ |
public function updateElement($uid,$pairs) |
{ |
// ce service est uniquement destiné à être appelé en local, |
// depuis le serveur lui même |
// en particulier par l'application identiplante |
$this->controleAppelIpAutorisee(); |
$this->verifierParametresObligatoires($uid, $pairs); |
$id = $uid[0]; |
$gestion_observation = new GestionObservation($this->config); |
$utilisateur = $pairs['ce_utilisateur']; |
unset($pairs['ce_utilisateur']); |
$modification = $gestion_observation->modifierObservationPublique($utilisateur, $id, $pairs); |
if($modification !== false) { |
$resultat = 'ok'; |
$this->envoyer($resultat); |
exit; |
} else { |
$info = array(); |
$info = 'Impossible de modifier l\'observation associée à cet identifiant '; |
$this->envoyer($info, 'text/html', 'utf-8', false); |
exit; |
} |
} |
private function verifierParametresObligatoires($uid ,$params) { |
$params_obligatoires = array('id_observation', |
'ce_utilisateur', |
'nom_sel'); |
$info = array(); |
if(!isset($uid[0]) || !is_numeric($uid[0])) { |
$info .= 'l\' identifiant doit être un entier '; |
} |
foreach($params_obligatoires as $param) { |
if(!isset($params[$param]) || trim($params[$param]) == "") { |
$info = 'le paramètre '.$param.' doit exister et ne peut pas être vide '; |
} |
} |
if(!empty($info)) { |
$this->envoyer($info, 'text/html', 'utf-8', false); |
exit; |
} |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryImageListPublic.php |
---|
New file |
0,0 → 1,74 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurélien Peronnet <aurelien@tela-botania.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* in : utf8 |
* out : utf8 |
* |
* Service recherche d'images publique a partir de divers critères |
* |
*/ |
class InventoryImageListPublic extends Cel { |
const start_defaut = 0; |
const limit_defaut = 100; |
const tri_defaut = 'ci.date_creation'; |
const dir_defaut = 'DESC'; |
function getRessource() { |
} |
function getElement($uid) |
{ |
// restriction aux observations publiques |
$criteres = array('transmission' => '1'); |
if($uid[0] != '*' && empty($_GET)) { |
header("content-type: application/json"); |
$images_json = json_encode(array()); |
print $images_json; |
exit() ; |
} |
$this->start = isset($_GET['start']) ? $_GET['start'] : self::start_defaut; |
$this->limit = isset($_GET['limit']) ? $_GET['limit'] : self::limit_defaut; |
$criteres['mots_cles'] = isset($_GET['tag']) ? $_GET['tag'] : null; |
$criteres['auteur'] = isset($_GET['auteur']) ? $_GET['auteur'] : null; |
$criteres['zone_geo'] = isset($_GET['commune']) ? $_GET['commune'] : null; |
$criteres['taxon'] = isset($_GET['taxon']) ? $_GET['taxon'] : null; |
$criteres['ce_zone_geo'] = isset($_GET['dept']) ? $_GET['dept'] : null; |
$criteres['famille'] = isset($_GET['famille']) ? $_GET['famille'] : null; |
$criteres['recherche'] = isset($_GET['recherche']) ? $_GET['recherche'] : null; |
$criteres['tri'] = isset($_GET['tri']) ? $_GET['tri'] : self::tri_defaut; |
$criteres['dir'] = isset($_GET['dir']) ? $_GET['dir'] : self::dir_defaut; |
$chercheur_images = new RechercheImage($this->config); |
$total = $chercheur_images->compterImages(null, $criteres); |
$images = $chercheur_images->rechercherImages(null, $criteres, $this->start, $this->limit); |
$resultat = array('total' => $total,'images' => $images); |
$images_json = json_encode($resultat) ; |
$images_json = str_replace('\u0000','',$images_json); |
header("content-type: application/json") ; |
print $images_json ; |
exit() ; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryImportMail.php |
---|
New file |
0,0 → 1,209 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* Service d'import d'image à partir de mails |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* @author Aurélien PERONNET <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
*/ |
Class InventoryImportMail extends Cel { |
/** |
* Appelée en mode client, lit le mail envoyé sur l'entrée stdin |
* et le stocke dans le dossier temporaire en attendant |
* qu'une tache périodique associée traite les mails en attente |
* |
* @param array $params les paramètres du script client, l'utilisateur est indiqué avec le paramètre -s |
*/ |
public function stockerMailCli($params) |
{ |
$contenu_mail = file_get_contents('php://stdin'); |
$parametres_ajout = array(); |
$parametres_ajout['mail_utilisateur'] = $params['-s']; |
$stockage = $this->stockerMailTemporaire($parametres_ajout, $contenu_mail); |
if($stockage) { |
$message_attente = 'Votre messsage a été reçu, et est en attente de traitement, '. |
'vous recevrez un message lorsque celui-ci aura été effectué'; |
mail($parametres_ajout['mail_utilisateur'],'Votre message est en attente de traitement',$message_attente); |
} else { |
$message_echec = 'Votre messsage a été reçu, mais il n\'a pas pu être stocké'; |
mail($parametres_ajout['mail_utilisateur'],'Problème lors de reception du message',$message_echec); |
} |
exit; |
} |
private function stockerMailTemporaire($parametres_ajout, $contenu_mail) { |
$expediteur = $parametres_ajout['mail_utilisateur']; |
$nom_fichier_temp = $this->fabriquerNomTemporaireStockageMail($expediteur); |
$dossier_stockage_temp = $this->config['chemin_stockage_temp']; |
$chemin_stockage_image_temp = $dossier_stockage_temp.'/mails/'; |
return file_put_contents($chemin_stockage_image_temp.$nom_fichier_temp); |
} |
/** |
* Appelée en mode client, lit le mail envoyé sur l'entrée stdin |
* extrait les images en pièces jointes, et les ajoute au cel de l'utilisateur |
* expediteur |
* |
* @param array $params les paramètres du script client, l'utilisateur est indiqué avec le paramètre -s |
*/ |
public function traiterMailCli($params) |
{ |
$contenu_mail = file_get_contents('php://stdin'); |
$parametres_ajout = array(); |
$parametres_ajout['mail_utilisateur'] = $params['-s']; |
$ids_stockage = $this->traiterMail($parametres_ajout, $contenu_mail); |
foreach($ids_stockage as $nom_image => $id_stockage) { |
if($id_stockage) { |
mail($parametres_ajout['mail_utilisateur'],'Votre image a été ajoutée au Carnet en ligne','Votre image '.$nom_image.' a été ajoutée avec succès'); |
} else { |
mail($parametres_ajout['mail_utilisateur'],'Problème lors de l\'ajout au Carnet en ligne','Votre image '.$nom_image.' n\'a pas pu être ajoutée'); |
} |
} |
exit(); |
} |
/** |
* Traite le mail fourni en paramètre extrait les images en pièces jointes, |
* et les ajoute au cel de l'utilisateur expediteur |
* |
* @param array $params les paramètres du script client, l'utilisateur est indiqué dans la case 'identifiant' |
*/ |
public function traiterMail($params, $contenu_mail) |
{ |
$pieces_jointes = $this->extrairePiecesJointes($contenu_mail); |
$stockeur_image = new InventoryImage($this->config); |
$ids = array(); |
$infos_utilisateur = $this->getInfosComplementairesUtilisateurPourMail($params['mail_utilisateur']); |
$params['ce_utilisateur'] = $infos_utilisateur['id_utilisateur']; |
foreach($pieces_jointes as $piece_jointe) { |
$nouvel_id_image = $stockeur_image->ajouterImageSurDdEtBdd($params, $piece_jointe); |
if($nouvel_id_image) |
{ |
$ids[$piece_jointe['name']] = $nouvel_id_image; |
} |
else |
{ |
$ids[$piece_jointe['name']] = false; |
} |
} |
// TODO: permettre la création d'observations liées aux images à partir du mail |
// et d'une syntaxe simple à définir |
return $ids; |
} |
/** |
* Appelée en mode client, parse le dossier ou sont stockés les mails |
* extrait les images en pièces jointes, et les ajoute au cel de l'utilisateur |
* |
*/ |
public function parserDossierMail() |
{ |
$dossier_stockage_temp = $this->config['chemin_stockage_temp']; |
$chemin_stockage_image_temp = $dossier_stockage_temp.'/mails/'; |
foreach (new DirectoryIterator($chemin_stockage_image_temp) as $fichier_a_stocker) { |
if($fichier_ou_dossier->isDot()) { |
continue; |
} |
$chemin_fichier = $fichier_a_stocker->getPathname(); |
$nom_fichier = $fichier_ou_dossier->getFilename(); |
$expediteur_mail = $this->obtenirExpediteurPourNomTemporaireMail($nom_fichier); |
$contenu_mail = file_get_contents($chemin_fichier); |
$parametres = array('courriel_utilisateur' => $expediteur_mail); |
$this->traiterMail($parametres, $contenu_mail); |
unlink($chemin_fichier); |
} |
} |
private function extrairePiecesJointes($mail) { |
$pieces_jointes = array(); |
$args['include_bodies'] = true; |
$args['decode_bodies'] = true; |
$args['decode_headers'] = true; |
$args['input'] = $mail; |
$dossier_stockage_temp = $this->config['chemin_stockage_temp']; |
$tableau_mail_decode = Mail_mimeDecode::decode($args); |
foreach ($tableau_mail_decode->parts as $partie) { |
if ($partie->ctype_primary == 'image' && $partie->ctype_secondary == 'jpeg') { |
$informations = array(); |
$nom_original = $partie->ctype_parameters['name']; |
$fichier = $partie->body; |
$hash = md5(time()); |
$chemin_temp = $dossier_stockage_temp.'/images/'.$hash.'.jpg'; |
$temp = fopen($chemin_temp,'w+'); |
fwrite($temp,$fichier); |
fclose($temp); |
chmod($chemin_temp, 0777); |
$informations = array('tmp_name' => $chemin_temp,'name' => $nom_original,'type' => 'image/jpeg','size' => filesize($chemin_temp)); |
$pieces_jointes[] = $informations; |
} |
} |
return $pieces_jointes; |
} |
private function fabriquerNomTemporaireStockageMail($expediteur) { |
return time().'_'.$expediteur; |
} |
private function obtenirExpediteurPourNomTemporaireMail($nom_temp) { |
$chaine_separee = explode('_', $nom_temp,1); |
$nom_expediteur = false; |
if($chaine_separee && count($chaine_separee) > 1) { |
$nom_expediteur = $chaine_separee[1]; |
} |
return $nom_expediteur; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryImageList.php |
---|
New file |
0,0 → 1,104 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* InventoryImageList.php |
* |
* in : utf8 |
* out : utf8 |
* |
* Service recherche, et de suppression multiple d'images a partir de divers critères |
* |
*/ |
class InventoryImageList extends Cel { |
/** |
* Recherche les images correspondant aux critères passés en paramètres |
* uid[0] : utilisateur obligatoire |
* $_GET : critères de filtrage de la forme critère1=valeur1;critère2=valeur2 |
*/ |
function getElement($uid) |
{ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
$chercheur_images = new RechercheImage($this->config); |
$numero_page = 0; |
$taille_page = 50; |
$criteres = array(); |
$criteres = $_GET; |
if (isset($criteres['numero_page']) && isset($criteres['limite'])) { |
$numero_page = $criteres['numero_page']; |
unset($criteres['numero_page']); |
$taille_page = $criteres['limite']; |
unset($criteres['limite']); |
} |
$debut = $taille_page*$numero_page ; |
$retour = $chercheur_images->rechercherImagesEtObservationAssociees($uid[0], $criteres, $debut, $taille_page); |
$retour = $chercheur_images->formaterPourEnvoiCel(&$retour); |
$retour_encode = json_encode($retour) ; |
$retour_encode = $this->nettoyerCaracteresNuls($retour_encode); |
header("content-type: application/json") ; |
print $retour_encode ; |
exit() ; |
} |
private function nettoyerCaracteresNuls($chaine) { |
return str_replace('\u0000','',$chaine); |
} |
/** |
* Méthode appelée avec une requête de type DELETE. |
* Supprime les infos sur l'image et le fichier correspondant à l'ordre passé en parametre |
* Supporte la suppression multiple en passant plusieurs numéros séparés par des virgules |
* |
* @param int uid[0] id utilisateur |
* @param string uid[1] : ordre(s) image(s) obligatoire(s) séparés par des virgules |
* |
*/ |
function deleteElement($uid){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if (!isset($uid[1]) || !$this->EstUneSuiteIdentifiantsImage($uid[1])) { |
return; |
} |
$ids_images = rtrim($uid[1], ','); |
$ids_images = explode(',',$ids_images); |
$gestionnaire_image = new GestionImage($this->config); |
$suppression_image = $gestionnaire_image->supprimerImage($uid[0], $ids_images); |
$this->envoyer('OK'); |
exit; |
} |
private function estUneSuiteIdentifiantsImage($chaine) { |
$chaine = rtrim($chaine,','); |
// un ensemble d'identifiants est une suite d'identifiants séparés par des virgules |
// avec ou sans virgule terminale |
$reg_exp = "/^(([0-9])+,)*([0-9])+$/"; |
return preg_match($reg_exp, $chaine); |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/CoordSearch.php |
---|
New file |
0,0 → 1,239 |
<?php |
/** |
* Service recherche de commune par coordonnées et vice versa |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* @author Aurélien PERONNET <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
*/ |
class CoordSearch extends Cel { |
private $adresse_service_geonames = null; |
private $adresse_service_local = null; |
private $nom_service_geocoding = null; |
private $nom_service_reverse_geocoding = null; |
function CoordSearch($config) { |
parent::__construct($config); |
$this->adresse_service_geonames = $this->config['cel']['url_service_geo_geonames']; |
$this->adresse_service_local = $this->config['cel']['url_service_geo_local']; |
$this->nom_service_geocoding = $this->config['cel']['nom_service_geocoding_geonames']; |
$this->nom_service_reverse_geocoding = $this->config['cel']['nom_service_reverse_geocoding_geonames']; |
} |
/** |
* Recherche de coordonnées suivant ce qui est fourni |
* |
* $uid[0] = latitude (ou * si recherche coordonnées d'une commune) |
* $uid[1] = longitude (ou * si recherche coordonnées d'une commune) |
* $uid[2] = commune (ou * si recherche d'une commune correspondant à des coordonnées) |
* $uid[3] = code_postal (ou * si recherche d'une commune correspondant à des coordonnées) |
* $uid[4] = code_pays (ou * si recherche d'une commune correspondant à des coordonnées, par défaut vaut FR) |
*/ |
function getElement($uid){ |
$header = ''; |
$retour = array(); |
$params = $this->traiterParametres($uid); |
if ($this->estUneRequeteReverseGeocoding($params)) { |
$informations_communes = $this->effectuerRequeteReverseGeocodingCartoOsm($params['lat'], $params['lon']); |
if (!$informations_communes) { |
$informations_communes = $this->effectuerRequeteReverseGeocodingGeonames($params['lat'], $params['lon']); |
} |
$header = 'Content-Type: application/json; charset=UTF-8'; |
$retour = json_encode($informations_communes) ; |
} elseif ($this->estUneRequeteGeocoding($params)) { |
$informations_coord = $this->chercherCentroideCommuneBdd($params['commune'],$params['code_postal']); |
if(!$informations_coord) { |
$informations_coord = $this->effectuerRequeteGeocodingGeonames($params['commune'],$params['code_postal'],$params['code_pays']); |
} |
$header = 'Content-Type: application/json; charset=UTF-8'; |
$retour = json_encode($informations_coord); |
} else { |
$header = 'HTTP/1.0 400 Bad Request'; |
$retour = 'Commune ou Coordonnées non spécifiées' ; |
} |
header($header); |
echo $retour; |
} |
protected function traiterParametres($params) { |
$lat = $this->affecterValeurParametreOuDefaut($params, 0, '*'); |
$lng = $this->affecterValeurParametreOuDefaut($params, 1, '*'); |
$commune = $this->affecterValeurParametreOuDefaut($params, 2, '*'); |
$code_postal = $this->affecterValeurParametreOuDefaut($params, 3, '*'); |
$code_pays = $this->affecterValeurParametreOuDefaut($params, 4, 'FR'); |
return array('lat' => $lat, 'lon' => $lng, 'commune' => $commune, |
'code_postal' => $code_postal, 'code_pays' => $code_pays); |
} |
private function affecterValeurParametreOuDefaut($params, $indice, $valeur_si_non_present) { |
return isset($params[$indice]) ? str_replace('"','',urldecode($params[$indice])) : $valeur_si_non_present; |
} |
private function estUneRequeteReverseGeocoding($params) { |
return ($params['lat'] != '*' && $params['lon'] != '*'); |
} |
private function estUneRequeteGeocoding($params) { |
return ($params['commune'] != '*'); |
} |
private function effectuerRequeteReverseGeocodingCartoOsm($lat, $lon) { |
$infos_commune_json = @file_get_contents($this->adresse_service_local."?lat=".$lat."&lon=".$lon); |
$infos_commune = json_decode($infos_commune_json); |
$retour = false; |
if ($this->estUnRetourOsmValide($infos_commune)) { |
$retour = array('nom' => $infos_commune->nom, 'code_insee' => $infos_commune->codeINSEE); |
} |
return $retour; |
} |
private function estUnretourOsmValide($retour) { |
return (is_a($retour,'stdClass') && property_exists($retour,'nom') && property_exists($retour,'codeINSEE')); |
} |
private function effectuerRequeteReverseGeocodingGeonames($lat, $lon) { |
$infos_commune_json = @file_get_contents($this->adresse_service_geonames. |
$this->nom_service_reverse_geocoding. |
"?featureClass=ADM4&lat=".urlencode($lat)."&lng=".urlencode($lon). |
"&style=full") ; |
$objet_retour = json_decode($infos_commune_json); |
$retour = false; |
if($this->estUnRetourReverseGeocodingGeonamesValide($objet_retour)) { |
$retour = array('nom' => $objet_retour->geonames[0]->name, 'code_insee' => $objet_retour->geonames[0]->adminCode4); |
} |
return $retour; |
} |
private function estUnRetourReverseGeocodingGeonamesValide($retour) { |
$valide = false; |
if (is_a($retour,'stdClass') && property_exists($retour,'geonames') |
&& is_array($retour->geonames) && count($retour->geonames) > 0) { |
$objet_resultats = $retour->geonames[0]; |
if (property_exists($objet_resultats,'adminName4') && property_exists($objet_resultats,'adminCode2')) { |
$valide = true; |
} |
} |
return $valide; |
} |
private function chercherCentroideCommuneBdd($commune, $departement) { |
$commune_formatee = str_replace(' ','_',$commune); |
$commune_formatee = str_replace('-','_',$commune_formatee); |
if(strlen($departement) > 2) { |
$departement = substr($departement,0,2); |
} |
$requete_selection_commune = 'SELECT utm_x, utm_y, utm_secteur, code FROM cel_zones_geo '. |
'WHERE nom LIKE '.$this->proteger($commune_formatee).' AND code LIKE '.$this->proteger($departement.'%'); |
$commune_coordonnees = $this->executerRequete($requete_selection_commune); |
$retour = false; |
if($commune_coordonnees && is_array($commune_coordonnees) && count($commune_coordonnees) > 0) { |
$lat_lon = $this->convertirUtmVersLatLong($commune_coordonnees[0]['utm_x'],$commune_coordonnees[0]['utm_y'],$commune_coordonnees[0]['utm_secteur']); |
$retour = array('lat' => (float)$lat_lon['lat'], |
'lng' => (float)$lat_lon['lng'], |
'nom' => $commune, |
'code_insee' => $commune_coordonnees[0]['code'] |
); |
} |
return $retour; |
} |
private function convertirUtmVersLatLong($x, $y, $sector) { |
$lat_long = array(); |
$convertisseur = new gPoint(); |
$convertisseur->setUTM($x, $y, $sector); |
$convertisseur->convertTMtoLL(); |
$lat_long['lat'] = str_replace(',','.',$convertisseur->Lat()); |
$lat_long['lng'] = str_replace(',','.',$convertisseur->Long()); |
return $lat_long; |
} |
private function effectuerRequeteGeocodingGeonames($commune, $code_postal, $code_pays) { |
$requete = $this->adresse_service_geonames. |
$this->nom_service_geocoding. |
"?placename_startsWith=".urlencode($commune); |
if($code_postal != '*') { |
$requete .= "&postalcode_startsWith=".urlencode($code_postal); |
} |
$requete .= "&country=".urlencode($code_pays)."&maxRows=10" ; |
$coord_json = @file_get_contents($requete); |
$objet_retour = json_decode($coord_json); |
$retour = false; |
if($this->estUnRetourGeocodingGeonamesValide($objet_retour)) { |
$retour = array('lat' => $objet_retour->postalCodes[0]->lat, |
'lng' => $objet_retour->postalCodes[0]->lng, |
'nom' => $objet_retour->postalCodes[0]->placeName, |
'code_insee' => $objet_retour->postalCodes[0]->postalCode |
); |
} |
return $retour; |
} |
private function estUnRetourGeocodingGeonamesValide($retour) { |
$valide = false; |
if (is_a($retour,'stdClass') && property_exists($retour,'postalCodes') |
&& is_array($retour->postalCodes) && count($retour->postalCodes) > 0) { |
$objet_resultats = $retour->postalCodes[0]; |
if (property_exists($objet_resultats,'lat') && property_exists($objet_resultats,'lng')) { |
$valide = true; |
} |
} |
return $valide; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/ImageProvider.php |
---|
New file |
0,0 → 1,69 |
<?php |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package papyrus_bp |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/papyrus_bp/ |
*/ |
/** |
* Classe fournissant des images au format demandé ou bien aux dimensions demandées |
* |
* in=utf8 |
* out=utf8 |
* |
*/ |
class ImageProvider extends Cel { |
function getElement($uid){ |
if(!isset($uid[0])) { |
return; |
} |
$id_image = $uid[0]; |
$format = 'temp'; |
if(isset($_GET['format'])) { |
$format = $_GET['format']; |
} |
if(isset($_GET['dimensions'])) { |
$dimensions = $_GET['dimensions']; |
} else { |
if(isset($this->config['cel']['format_'.$format])) { |
$dimensions = $this->config['cel']['format_'.$format]; |
} |
} |
$this->config['cel']['format_'.$format] = $dimensions; |
$generateur_image = new ImageRecreation($this->config); |
$infos_image = $generateur_image->obtenirImageEtInfosPourId($id_image); |
if(!$infos_image) { |
header('HTTP/1.0 404 Not Found'); |
exit; |
} |
$image_generee = $generateur_image->creerMiniatureImageSelonFormat($infos_image, $format); |
header('Content-type: image/jpeg'); |
imagejpeg($image_generee); |
exit; |
} |
private function estUneImageALaDemande() { |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/LicenceUtilisateur.php |
---|
New file |
0,0 → 1,52 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* Classe gérant l'acceptation de la licence utilisateur |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2010, Aurélien Peronnet |
*/ |
class LicenceUtilisateur extends Cel { |
/** |
* Fonction appelée sur un POST |
* |
* Accepte ou refuse la licence utilisateur, en mettant à jour la base de données pour |
* l'utilisateur indiqué |
* |
* @param array $uid |
* @param array $pairs |
*/ |
function updateElement($uid,$pairs) { |
if(!isset($uid[0]) && is_numeric($uid[0])) { |
return; |
} |
if(!isset($pairs['licence'])) { |
return; |
} |
$requete_acceptation_licence = 'UPDATE cel_utilisateurs_infos '. |
'SET licence_acceptee = '.$this->proteger($pairs['licence']). |
'WHERE id_utilisateur = '.$this->proteger($uid[0]); |
$resultat_acceptation_licence = $this->executer($requete_acceptation_licence); |
$resultat = false; |
if($resultat_acceptation_licence) { |
$resultat = "OK"; |
} |
echo $resultat; |
exit; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryExport.php |
---|
New file |
0,0 → 1,130 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david@tela-botania.org> |
* @author Aurélien Peronnet <aurelien@tela-botania.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* in:utf8 |
* out:iso8859 |
* |
* Export vers feuille de calcul d'une selection de releves |
* |
*/ |
class InventoryExport extends Cel { |
private $extendSpreadsheetProductor; |
function InventoryExport($config) { |
parent::__construct($config); |
$this->extendSpreadsheetProductor = new SpreadsheetProductor(); |
$this->extendSpreadsheetProductor->initSpreadsheet(); |
} |
function getElement($uid){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
$criteres = $_GET; |
$chercheur_observations = new RechercheObservation($this->config); |
// Creating a workbook |
$workbook = new Spreadsheet_Excel_Writer(); |
$workbook->send('liste.xls'); |
// Creating a worksheet |
$worksheet = $workbook->addWorksheet('Liste'); |
$worksheet->write(0,0,'Espece'); |
$worksheet->write(0,1,'Numero nomenclatural'); |
$worksheet->write(0,2,'Nom retenu'); |
$worksheet->write(0,3,'Numero nomenclatural nom retenu'); |
$worksheet->write(0,4,'Numero taxonomique'); |
$worksheet->write(0,5,'Famille'); |
$worksheet->write(0,6,'Referentiel taxonomique'); |
$worksheet->write(0,7,'Commune'); |
$worksheet->write(0,8,'Identifiant Commune'); |
$worksheet->write(0,9,'Date'); |
$worksheet->write(0,10,'Lieu-dit'); |
$worksheet->write(0,11,'Station'); |
$worksheet->write(0,12,'Milieu'); |
$worksheet->write(0,13,'Notes'); |
$worksheet->write(0,14,'Latitude'); |
$worksheet->write(0,15,'Longitude'); |
$worksheet->write(0,16,'Referentiel Geographique'); |
$worksheet->write(0,17,'Ordre'); |
$worksheet->write(0,18,'Identifiant'); |
$numero_page = isset($criteres['numero_page']) ? $criteres['numero_page'] : 0; |
$limite = isset($criteres['limite']) ? $criteres['limite'] : 0; |
$observations = $chercheur_observations->rechercherObservations($uid[0], $criteres, $numero_page, $limite); |
$i=1; |
foreach ($observations as $obs) { |
$obs = $this->denullifierTableauValeurCel(&$obs); |
if ($obs['date_observation'] != "0000-00-00 00:00:00") { |
$obs['date_observation'] = $this->formaterDate($obs['date_observation']); |
} |
else { |
$obs['date_observation']="00/00/0000"; |
} |
$worksheet->write($i,0,$obs['nom_sel']); |
$worksheet->write($i,1,$obs['nom_sel_nn']); |
$worksheet->write($i,2,$obs['nom_ret']); |
$worksheet->write($i,3,$obs['nom_ret_nn']); |
$worksheet->write($i,4,$obs['nt']); |
$worksheet->write($i,5,$obs['famille']); |
$worksheet->write($i,6,$obs['nom_referentiel']); |
$worksheet->write($i,7,$obs['zone_geo']); |
$worksheet->write($i,8,$this->convertirCodeZoneGeoVersDepartement($obs['ce_zone_geo'])); |
$worksheet->write($i,9,$obs['date_observation']); |
$worksheet->write($i,10,$obs['lieudit']); |
$worksheet->write($i,11,$obs['station']); |
$worksheet->write($i,12,$obs['milieu']); |
$worksheet->write($i,13,$obs['commentaire']); |
$worksheet->write($i,14,$obs['latitude']); |
$worksheet->write($i,15,$obs['longitude']); |
$worksheet->write($i,16,$obs['geodatum']); |
$worksheet->write($i,17,$obs['ordre']); |
$worksheet->write($i,18,$obs['id_observation']); |
$i++; |
} |
$workbook->close(); |
exit(); |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.7 2008-11-13 11:29:12 ddelon |
* Reecriture gwt-ext |
* |
* Revision 1.6 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.5 2007-06-06 13:31:16 ddelon |
* v0.09 |
* |
* Revision 1.4 2007-05-22 12:54:09 ddelon |
* Securisation acces utilisateur |
*/ |
?> |
/branches/v1.6-croc/jrest/services/InventoryImage.php |
---|
New file |
0,0 → 1,164 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurelien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* Service recherche et ajout d'image a partir de divers critères |
* in=utf8 |
* out=utf8 |
* |
*/ |
class InventoryImage extends Cel { |
const ARRET_SERVICE = false; |
/** |
* Méthode appelée avec une requête de type GET. |
* Renvoie les infos sur l'image correspondant à l'id passé en parametre |
* @param int uid[0] : utilisateur obligatoire |
* @param int uid[1] : identifiant image obligatoire |
*/ |
public function getElement($uid) |
{ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if(!isset($uid[0]) || !isset($uid[1])) { |
return; |
} |
$chercheur_image = new RechercheImage($this->config); |
$parametres = array('ordre' => $uid[1]); |
$retour = null; |
$image_recherchee = $chercheur_image->rechercherImages($uid[0], $parametres, 0, 1); |
if(count($image_recherchee) > 0) { |
$retour = $image_recherchee[0]; |
} |
$this->envoyerJson($retour); |
return true; |
} |
/** |
* Méthode appelée avec une requête de type POST avec un identifiant d'image. |
* Met a jour l'image correspondant à l'id passé en paramètre avec les valeurs passées dans le post |
* |
* @param int $uid[0] identifiant utilisateur |
* @param int $uid[1] ordre de l'image relatif à l'utilisateur |
* @param pairs array tableau contenant les valeurs de metadonnées à modifier |
*/ |
public function updateElement($uid,$pairs) |
{ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if(count($pairs) == 0 || !isset($uid[1])) { |
return; |
} |
$gestionnaire_image = new GestionImage($this->config); |
$resultat_mise_a_jour = $gestionnaire_image->modifierImage($uid[0],$uid[1],$pairs); |
$retour = false; |
if ($resultat_mise_a_jour) { |
$retour = 'OK'; |
} |
$this->envoyer($retour); |
} |
/** |
* Méthode appelée avec une requête de type PUT. |
* Stocke une image, crée ses miniatures et enregistre ses informations |
* Renvoie l'identifiant d'image nouvellement crée en cas de succès |
* |
* @param $pairs array tableau contenant les valeurs de metadonnées à ajouter |
*/ |
function createElement($pairs) |
{ |
if(self::ARRET_SERVICE) { |
header('Status: 503 Service Temporarily Unavailable'); |
echo "L'envoi d'images au cel est temporairement désactivé"; |
exit; |
} |
// Controle detournement utilisateur |
$this->controleUtilisateur($pairs['ce_utilisateur']); |
foreach ($_FILES as $file) { |
$infos_fichier = $file ; |
} |
$gestionnaire_image = new GestionImage($this->config); |
$id_utilisateur = $pairs['ce_utilisateur']; |
if ($gestionnaire_image->ajouterImage($id_utilisateur, $infos_fichier)) { |
// l'upload demande de court-circuiter le fonctionnement normal de JREST |
// en quittant directement après l'envoi |
$this->envoyerMessageCreationEffectuee(); |
exit; |
} |
} |
private function envoyerMessageCreationEffectuee() { |
header('HTTP/1.0 200 Created'); |
echo 'OK'; |
exit() ; |
} |
/** |
* Méthode appelée avec une requête de type DELETE. |
* Supprime les infos sur l'image et le fichier correspondant à l'ordre passé en parametre |
* Supporte la suppression multiple en passant plusieurs numéros séparés par des virgules |
* |
* @param int uid[0] id utilisateur |
* @param string uid[1] : ordre(s) image(s) obligatoire(s) séparés par des virgules |
* |
*/ |
function deleteElement($uid){ |
if(self::ARRET_SERVICE) { |
header('Status: 503 Service Temporarily Unavailable'); |
echo "L'envoi d'images au cel est temporairement désactivé"; |
exit; |
} |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if (!isset($uid[1]) || !$this->EstUneSuiteIdentifiantsImage($uid[1])) { |
return; |
} |
$ids_images = explode(',',$uid[1]); |
$gestionnaire_image = new GestionImage($this->config); |
$suppression_image = $gestionnaire_image->supprimerImage($uid[0], $ids_images); |
$this->envoyer('OK'); |
} |
private function estUneSuiteIdentifiantsImage($chaine) { |
// un ensemble d'identifiants est une suite d'identifiants séparés par des virgules |
// sans virgule terminale |
$reg_exp = "/^(([0-9])+,)*([0-9])+$/"; |
return preg_match($reg_exp, $chaine); |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/CelRestClient.php |
---|
New file |
0,0 → 1,157 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe modèle spécifique à l'application, donc d'accés au données, elle ne devrait pas être appelée de l'extérieur. |
* |
* @category php5 |
* @package Cel |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version SVN: $Id$ |
*/ |
// TODO : remplacer les trigger_error par des exceptions qui pourrait être attrapées... |
class CelRestClient { |
const HTTP_URL_REQUETE_SEPARATEUR = '&'; |
const HTTP_URL_REQUETE_CLE_VALEUR_SEPARATEUR = '='; |
private $http_methodes = array('GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'CONNECT', 'TRACE'); |
protected $parametres = null; |
private $url = null; |
private $reponse_entetes = null; |
//+----------------------------------------------------------------------------------------------------------------+ |
// ACCESSEURS |
public function getReponseEntetes($cle) { |
return $this->reponse_entetes; |
} |
public function getParametre($cle) { |
$valeur = (isset($this->parametres[$cle])) ? $this->parametres[$cle] : null; |
return $valeur; |
} |
public function ajouterParametre($cle, $valeur) { |
$this->parametres[$cle] = $valeur; |
} |
public function supprimerParametre($cle) { |
unset($this->parametres[$cle]); |
} |
public function nettoyerParametres() { |
$this->parametres = null; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// MÉTHODES |
public function consulter($url) { |
$retour = $this->envoyerRequete($url, 'GET'); |
return $retour; |
} |
public function ajouter($url, Array $donnees) { |
$retour = $this->envoyerRequete($url, 'PUT', $donnees); |
return $retour; |
} |
public function modifier($url, Array $donnees) { |
$retour = $this->envoyerRequete($url, 'POST', $donnees); |
return $retour; |
} |
public function supprimer($url) { |
$retour = $this->envoyerRequete($url, 'DELETE'); |
return $retour; |
} |
public function envoyerRequete($url, $mode, Array $donnees = array()) { |
$this->url = $url; |
$contenu = false; |
if (! in_array($mode, $this->http_methodes)) { |
$e = "Le mode de requête '$mode' n'est pas accepté!"; |
trigger_error($e, E_USER_WARNING); |
} else { |
if ($mode == 'GET') { |
$this->traiterUrlParametres(); |
} |
$contexte = stream_context_create(array( |
'http' => array( |
'method' => $mode, |
'header' => "Content-type: application/x-www-form-urlencoded\r\n", |
'content' => http_build_query($donnees, null, self::HTTP_URL_REQUETE_SEPARATEUR)))); |
$flux = @fopen($this->url, 'r', false, $contexte); |
if (!$flux) { |
$this->reponse_entetes = $http_response_header; |
$e = "L'ouverture de l'url '{$this->url}' par la méthode HTTP '$mode' a échoué!"; |
trigger_error($e, E_USER_WARNING); |
} else { |
// Informations sur les en-têtes et métadonnées du flux |
$this->reponse_entetes = stream_get_meta_data($flux); |
// Contenu actuel de $url |
$contenu = stream_get_contents($flux); |
fclose($flux); |
} |
$this->traiterEntete(); |
} |
$this->reinitialiser(); |
return $contenu; |
} |
private function traiterUrlParametres() { |
$parametres = array(); |
if (count($this->parametres) > 0) { |
foreach ($this->parametres as $cle => $valeur) { |
$cle = rawurlencode($cle); |
$valeur = rawurlencode($valeur); |
$parametres[] = $cle.self::HTTP_URL_REQUETE_CLE_VALEUR_SEPARATEUR.$valeur; |
} |
$url_parametres = implode(self::HTTP_URL_REQUETE_SEPARATEUR, $parametres); |
$this->url = $this->url.'?'.$url_parametres; |
} |
} |
private function traiterEntete() { |
$infos = $this->analyserEntete(); |
$this->traiterEnteteDebogage($infos); |
} |
private function analyserEntete() { |
$entetes = $this->reponse_entetes; |
$infos = array('date' => null, 'uri' => $this->url, 'debogages' => null); |
if (isset($entetes)) { |
if (isset($entetes['wrapper_data'])) { |
$entetes = $entetes['wrapper_data']; |
} |
foreach ($entetes as $entete) { |
if (preg_match('/^X_REST_DEBOGAGE_MESSAGES: (.+)$/', $entete, $match)) { |
$infos['debogages'] = json_decode($match[1]); |
} |
if (preg_match('/^Date: .+ ([012][0-9]:[012345][0-9]:[012345][0-9]) .*$/', $entete, $match)) { |
$infos['date'] = $match[1]; |
} |
} |
} |
return $infos; |
} |
private function traiterEnteteDebogage($entetes_analyses) { |
if (isset($entetes['debogages'])) { |
$date = $entetes['date']; |
$uri = $entetes['uri']; |
$debogages = $entetes['debogages']; |
foreach ($debogages as $debogage) { |
$e = "DEBOGAGE : $date - $uri :\n$debogage"; |
trigger_error($e, E_USER_NOTICE); |
} |
} |
} |
private function reinitialiser() { |
$this->nettoyerParametres(); |
} |
} |
/branches/v1.6-croc/jrest/services/CelWidgetMap.php |
---|
New file |
0,0 → 1,836 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Service fournissant une carte dynamique des obsertions publiques du CEL. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* Cas d'utilisation : |
* /CelWidgetMap/Carte/Utilisateur : carte des observations publiques d'un utilisateur. |
* /CelWidgetMap/Carte/Utilisateur/Projet : carte des observations publiques d'un utilisateur pour un projet. |
* /CelWidgetMap/Carte/Utilisateur/Projet/dept : carte des observations publiques d'un utilisateur pour un projet sur un département. |
* /CelWidgetMap/Carte/Utilisateur/Projet/dept/num_taxon : carte des observations publiques d'un utilisateur pour un projet sur un département pour un taxon. |
* |
* Carte = Type de carte. Valeurs possible : defaut, |
* Utilisateur = identifiant (= courriel) de l'utilisateur ou * pour tous les utilisateurs. |
* Projet = mot-clé du projet |
* |
* @author Jean-Pascal MILCENT <jpm@clapas.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2010, Jean-Pascal MILCENT |
*/ |
// TODO : supprimer le TRIM quand les obs seront reliées correctements aux localisations (sur le code INSEE par exemple) |
class CelWidgetMap extends Cel { |
/** |
* Méthode appelée avec une requête de type GET. |
*/ |
public function getElement($ressources) { |
$retour = null; |
extract($this->parametres); |
$action = array_shift($ressources); |
if (isset($action)) { |
$methode = $this->traiterNomMethodeGet($action); |
if (method_exists($this, $methode)) { |
$retour = $this->$methode($ressources); |
} else { |
$this->messages[] = "Ce type de ressource '$methode' n'est pas disponible."; |
} |
} else { |
$this->messages[] = "Vous devez indiquer le type de ressource."; |
} |
if (is_null($retour)) { |
$info = 'Un problème est survenu : '.print_r($this->messages, true); |
$this->envoyer($info); |
} else if (isset($retour['type']) && $retour['type'] == 'jsonVar') { |
$this->envoyerJsonVar($retour['variable_js'], $retour['donnees']); |
} else if (isset($retour['type']) && $retour['type'] == 'jsonP') { |
$this->envoyerJsonp($retour['donnees']); |
} else { |
$this->envoyerJson($retour); |
} |
} |
/** |
* Les stations de la carte par défaut |
*/ |
public function getStations($params) { |
$json = null; |
$requete = 'SELECT utm_secteur, utm_x, utm_y, wgs84_latitude AS latitude, wgs84_longitude AS longitude '. |
'FROM cel_obs AS co '. |
' LEFT JOIN cel_zones_geo AS l '. |
' ON (l.id_zone_geo = co.ce_zone_geo) '. |
"WHERE transmission = '1' ". |
$this->construireWhereDept(). |
$this->construireWhereCommune(). |
$this->construireWherePhotosSeulement(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereDate(). |
$this->construireWhereCommentaire(). |
$this->construireWhereProjet(). |
$this->construireWhereTag(); |
//die($requete); |
$resultats = $this->requeter($requete); |
// Traitement des résultats |
$obs_nbre = $this->traiterNbreObs($resultats); |
$stations = $this->traiterStations($resultats); |
// Création des infos du widget |
$json['donnees']['points'] = $stations; |
$json['donnees']['stats']['communes'] = count($stations); |
$json['donnees']['stats']['observations'] = $obs_nbre; |
$json['type'] = (isset($this->formatRetour)) ? $this->formatRetour : 'jsonVar'; |
$json['variable_js'] = 'stations'; |
return $json; |
} |
private function traiterNbreObs($resultats) { |
$obs_nbre = 0; |
if ($resultats !== false) { |
$obs_nbre = count($resultats); |
} |
return $obs_nbre; |
} |
private function traiterStations($resultats) { |
$stations = array(); |
if ($resultats !== false) { |
foreach ($resultats as $enrg) { |
if ($enrg['latitude'] != null && $enrg['longitude'] != null) { |
$id = $enrg['latitude'].'-'.$enrg['longitude']; |
if (!isset($stations[$id])) { |
$enrg['id'] = 'UTM:'.$enrg['utm_x'].'-'.$enrg['utm_y'].'-'.$enrg['utm_secteur']; |
unset($enrg['utm_x']); |
unset($enrg['utm_y']); |
unset($enrg['utm_secteur']); |
$stations[$id] = $enrg; |
$stations[$id]['nbre'] = 1; |
} else { |
$stations[$id]['nbre']++; |
} |
} |
} |
$stations = array_values($stations); |
} |
return $stations; |
} |
/** |
* Données pour l'affichage des obs d'une station |
*/ |
public function getObservations($params) { |
$resultats = array(); |
$total = 0; |
if (!$this->etreNull($this->parametres['station'])) { |
$requete = 'SELECT SQL_CALC_FOUND_ROWS id_observation, ce_utilisateur, courriel_utilisateur, '. |
' nom_sel, nom_ret, nom_sel_nn, nom_ret_nn, nt, famille, '. |
' lieudit, zone_geo, date_observation, milieu, commentaire, '. |
' utm_secteur, utm_x, utm_y, id_zone_geo, date_transmission '. |
'FROM cel_obs AS co '. |
' LEFT JOIN cel_zones_geo AS l '. |
" ON (l.id_zone_geo = co.ce_zone_geo) ". |
"WHERE transmission = '1' ". |
$this->construireWhereCoordonnees(). |
$this->construireWherePhotosSeulement(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereDate(). |
$this->construireWhereCommentaire(). |
$this->construireWhereProjet(). |
$this->construireWhereTag(). |
'ORDER BY nom_sel ASC '. |
"LIMIT {$this->start},{$this->limit} "; |
//die($requete); |
$resultats = $this->requeter($requete, self::SQL_RETOUR_COMPLET, self::SQL_MODE_OBJET); |
$requete = 'SELECT FOUND_ROWS()'; |
$total = (int) $this->requeter($requete, self::SQL_RETOUR_COLONNE); |
} |
// Post-traitement |
$observations = $this->traiterObservations($resultats, $total); |
$observations = $this->ajouterImagesAuxObs($observations); |
$observations = $this->ajouterAuteursAuxObs($observations); |
$observations = $this->supprimerIdDesObs($observations); |
return $observations; |
} |
private function traiterObservations($donnees, $total) { |
$observations = array('commune' => '', 'observations' => array(), 'observateurs' => array()); |
$observations['total'] = (isset($total)) ? $total : 0; |
if (is_array($donnees) && count($donnees) > 0) { |
foreach ($donnees as $donnee) { |
$observation = array(); |
$observation['idObs'] = $donnee->id_observation; |
$observation['nn'] = $this->etreNull($donnee->nom_sel_nn) ? null : $donnee->nom_sel_nn; |
$observation['nomSci'] = $this->nettoyerTexte($donnee->nom_sel); |
$observation['date'] = $this->formaterDate($donnee->date_observation, '%d/%m/%Y'); |
$observation['datePubli'] = $this->formaterDate($donnee->date_transmission); |
$observation['lieu'] = $this->traiterLieu($donnee); |
$observation['observateur'] = $donnee->courriel_utilisateur; |
$observation['observateurId'] = $donnee->ce_utilisateur; |
$observation['urlEflore'] = $this->getUrlEflore($donnee->nom_sel_nn); |
if (isset($donnee->zone_geo)) { |
$observations['commune'] = $this->nettoyerTexte($donnee->zone_geo); |
} |
$observations['observations'][$donnee->id_observation] = $observation; |
if (! array_key_exists($donnee->courriel_utilisateur, $observations['observateurs'])) { |
$observations['observateurs'][$donnee->courriel_utilisateur] = $donnee->courriel_utilisateur; |
} |
} |
} |
return $observations; |
} |
private function getUrlEflore($nn) { |
$urlEflore = null; |
if (! $this->etreNull($nn)) { |
$urlEflore = sprintf($this->config['settings']['efloreUrlTpl'], $nn, 'illustration'); |
} |
return $urlEflore; |
} |
private function traiterLieu($donnee) { |
$lieu = array(); |
if (!$this->etreNull($donnee->lieudit)) { |
$lieu[] = $donnee->lieudit; |
} |
if (!$this->etreNull($donnee->milieu)) { |
$lieu[] = $donnee->milieu; |
} |
return implode(', ', $lieu); |
} |
private function chargerImages(Array $obs_ids) { |
// Récupération des données au format Json |
$service = 'CelImage/liste-ids?obsId='.implode(',', $obs_ids); |
$url = sprintf($this->config['settings']['baseURLServicesCelTpl'], $service); |
$json = $this->getRestClient()->consulter($url); |
$donnees = json_decode($json); |
// Post-traitement des données |
$images = $this->traiterImages($donnees); |
return $images; |
} |
private function traiterImages($donnees) { |
$images = array(); |
if (count($donnees) > 0) { |
foreach ($donnees as $id_obs => $id_images) { |
foreach ($id_images as $id_img) { |
$urls['idImg'] = $id_img; |
$urls['guid'] = sprintf($this->config['settings']['guidImgTpl'], $id_img); |
$urls['miniature'] = $this->getUrlImage($id_img, 'CXS'); |
$urls['normale'] = $this->getUrlImage($id_img, 'XL'); |
$images[$id_obs][] = $urls; |
} |
} |
} |
return $images; |
} |
private function ajouterImagesAuxObs($observations) { |
$images = $this->chargerImages(array_keys($observations['observations'])); |
foreach ($observations['observations'] as $id => $infos) { |
if(isset($images[$id])) { |
$infos['images'] = $images[$id]; |
} |
$observations['observations'][$id] = $infos; |
} |
return $observations; |
} |
private function ajouterAuteursAuxObs($observations) { |
$observateurs = $this->recupererUtilisateursIdentite(array_keys($observations['observateurs'])); |
unset($observations['observateurs']); |
foreach ($observations['observations'] as $id => $infos) { |
$courriel = strtolower($infos['observateur']); |
$infos['observateur'] = $observateurs[$courriel]['intitule']; |
$infos['observateurId'] = $observateurs[$courriel]['id']; |
$observations['observations'][$id] = $infos; |
} |
return $observations; |
} |
private function supprimerIdDesObs($observations) { |
// Le tableau de sortie ne doit pas avoir les id des obs en clé car sinon Jquery Template ne fonctionne pas |
$observationSansId = $observations; |
unset($observationSansId['observations']); |
foreach ($observations['observations'] as $id => $infos) { |
$observationSansId['observations'][] = $infos; |
} |
return $observationSansId; |
} |
/** |
* Liste des taxons présents sur la carte |
*/ |
public function getTaxons($params) { |
$json = null; |
$requete = 'SELECT SQL_CALC_FOUND_ROWS DISTINCT nom_ret, nom_ret_nn, nt, famille '. |
'FROM cel_obs AS co '. |
' LEFT JOIN cel_zones_geo AS l '. |
' ON (l.id_zone_geo = co.ce_zone_geo) '. |
"WHERE transmission = '1' ". |
" AND nom_ret != '' ". |
$this->construireWhereDept(). |
$this->construireWhereCommune(). |
$this->construireWherePhotosSeulement(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereDate(). |
$this->construireWhereCommentaire(). |
$this->construireWhereProjet(). |
$this->construireWhereTag(); |
'ORDER BY nom_ret ASC '. |
"LIMIT {$this->start},{$this->limit} "; |
//$this->debug[] = $requete; |
//die($requete); |
$resultats = $this->requeter($requete, self::SQL_RETOUR_COMPLET, self::SQL_MODE_OBJET); |
$requete = 'SELECT FOUND_ROWS()'; |
$taxons['total'] = (int) $this->requeter($requete, self::SQL_RETOUR_COLONNE); |
// Post-traitement |
$taxons['taxons'] = $this->traiterTaxons($resultats); |
return $taxons; |
} |
private function traiterTaxons($donnees) { |
$taxons = array(); |
if (is_array($donnees) && count($donnees) > 0) { |
foreach ($donnees as $donnee) { |
if (!isset($taxons[$donnee->nt]) && ! $this->etreNull($donnee->nom_ret)) { |
$taxon = array(); |
$taxon['nn'] = $donnee->nom_ret_nn; |
$taxon['nt'] = $donnee->nt; |
$taxon['nom'] = $this->nettoyerTexte($donnee->nom_ret); |
$taxon['famille'] = $this->nettoyerTexte($donnee->famille); |
$taxons[$donnee->nt] = $taxon; |
} |
} |
} |
$taxons = array_values($taxons); |
return $taxons; |
} |
private function construireWhereCoordonnees() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->decomposerParametreStation()); |
if (isset($type)) { |
if ($type == 'UTM') { |
$secteur = $this->proteger($secteur); |
$utm_x = $this->proteger($utm_x); |
$utm_y = $this->proteger($utm_y); |
$sql = " AND (utm_secteur = $secteur AND utm_x = $utm_x AND utm_y = $utm_y ) "; |
} else if ($type == 'LngLat') { |
$latitude = $this->proteger($latitude); |
$longitude = $this->proteger($longitude); |
$sql = " AND (latitude = $latitude AND longitude = $longitude ) "; |
} |
} |
return $sql; |
} |
private function construireWhereCommentaire() { |
$sql = ''; |
list($type, $commentaire) = $this->decomposerParametreCommentaire(); |
if (!$this->etreNull($commentaire)) { |
$commentaire = $this->proteger('%'.$commentaire.'%'); |
switch ($type) { |
case '*' : |
$sql = $this->obtenirConditionPourCommentaires($commentaire); |
$sql = " AND (commentaire LIKE $commentaire OR ($sql)) "; |
break; |
case 'observation' : |
$sql = " AND co.commentaire LIKE $commentaire "; |
break; |
case 'photo' : |
$sql = ' AND '.$this->obtenirConditionPourCommentaires($commentaire).' '; |
break; |
case 'photo.meta' : |
$sql = ' AND '.$this->obtenirConditionPourCommentaireMeta($commentaire).' '; |
break; |
case 'photo.utilisateur' : |
$sql = ' AND '.$this->obtenirConditionPourCommentaireUtilisateur($commentaire).' '; |
break; |
default: |
$sql = " AND co.commentaire LIKE $commentaire "; |
} |
} |
return $sql; |
} |
private function construireWhereNomTaxon() { |
$sql = ''; |
list($type, $nom) = $this->decomposerParametreTaxon(); |
if (!$this->etreNull($nom)) { |
$nom = $this->proteger($nom.'%'); |
switch ($type) { |
case '*' : |
$sql = " AND (nom_ret LIKE $nom OR nom_sel LIKE $nom OR famille LIKE $nom) "; |
break; |
case 'retenu' : |
$sql = " AND nom_ret LIKE $nom "; |
break; |
case 'selectionne' : |
$sql = " AND nom_sel LIKE $nom "; |
break; |
case 'famille' : |
$sql = " AND famille LIKE $nom "; |
break; |
default: |
$sql = " AND nom_ret LIKE $nom "; |
} |
} |
return $sql; |
} |
private function construireWhereDate() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
list($type, $date) = $this->decomposerParametreDate(); |
if (!$this->etreNull($date)) { |
$date = $this->proteger($date.'%'); |
switch ($type) { |
case '*' : |
$sql = " AND ( |
date_observation LIKE $date |
OR date_creation LIKE $date |
OR date_modification LIKE $date |
OR date_transmission LIKE $date) "; |
break; |
case 'observation' : |
$sql = " AND date_observation LIKE $date "; |
break; |
case 'creation' : |
$sql = " AND date_creation LIKE $date "; |
break; |
case 'modification' : |
$sql = " AND date_modification LIKE $date "; |
break; |
case 'transmission' : |
$sql = " AND date_transmission LIKE $date "; |
break; |
case 'photo' : |
$sql = $this->obtenirConditionPourDatePhoto($date); |
break; |
case 'ajout' : |
$sql = $this->obtenirConditionPourDateAjout($date); |
break; |
case 'liaison' : |
$sql = $this->obtenirConditionPourDateLiaison($date); |
break; |
default: |
$sql = " AND date_observation LIKE $date "; |
} |
} |
return $sql; |
} |
private function obtenirConditionPourDatePhoto($date) { |
$observations = $this->obtenirObsLieesImg('date.photo', $date); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'est liée à une photo prise à la date : $date"; |
} |
$sql = $this->assemblerObsEnConditionSql($observations); |
return $sql; |
} |
private function obtenirConditionPourDateLiaison($date) { |
$observations = $this->obtenirObsLieesImg('date.liaison', $date); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'a été liée à une image à à la date : $date"; |
} |
$sql = $this->assemblerObsEnConditionSql($observations); |
return $sql; |
} |
private function obtenirConditionPourDateAjout($date) { |
$observations = $this->obtenirObsLieesImg('date.ajout', $date); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'est liée à une image ajoutée à la date : $date"; |
} |
$sql = $this->assemblerObsEnConditionSql($observations); |
return $sql; |
} |
private function obtenirConditionPourCommentaireMeta($commentaire) { |
$observations = $this->obtenirObsLieesImg('commentaire.meta', $commentaire); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'est liée à une image dont le commentaire des méta-données correspond à : $commmentaire"; |
} |
$operateur = ''; |
$sql = $this->assemblerObsEnConditionSql($observations, $operateur); |
return $sql; |
} |
private function obtenirConditionPourCommentaireUtilisateur($commentaire) { |
$observations = $this->obtenirObsLieesImg('commentaire.utilisateur', $commentaire); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'est liée à une image dont le commentaire des utilisateur correspond à : $commmentaire"; |
} |
$operateur = ''; |
$sql = $this->assemblerObsEnConditionSql($observations, $operateur); |
return $sql; |
} |
private function obtenirConditionPourCommentaires($commentaire) { |
$observations = $this->obtenirObsLieesImg('commentaire.*', $commentaire); |
if (is_null($observations)) { |
$this->debug[] = "Aucune observation n'est liée à une image dont un des commentaires correspond à : $commmentaire"; |
} |
$operateur = ''; |
$sql = $this->assemblerObsEnConditionSql($observations, $operateur); |
return $sql; |
} |
/** |
* Récupération des identifiant d'utilisateur et des ordres des observations correspondant à une date. |
* Retour sous forme de tableau : array[identifiant] = array(ordre, ordre...); |
*/ |
private function obtenirObsLieesImg($type, $param) { |
// Construction de la requête |
$requete = 'SELECT DISTINCT id_observation AS id_obs, ce_utilisateur AS utilisateur '. |
'FROM cel_images ci'. |
' LEFT JOIN cel_obs_images coi '. |
' ON (coi.id_image = ci.id_image) '. |
' LEFT JOIN cel_obs AS co '. |
' ON coi.id_observation = co.id_observation '. |
' LEFT JOIN locations AS l '. |
' ON (l.id_zone_geo = co.ce_zone_geo) '. |
"WHERE transmission = '1' ". |
($type == 'date.photo' ? " AND (date_prise_de_vue LIKE ".str_replace('-', ':', $param).") " : ''). |
($type == 'date.ajout' ? " AND date_creation LIKE $param " : ''). |
($type == 'date.liaison' ? " AND date_liaison LIKE $param " : ''). |
// TODO: recherche sur le xml |
//($type == 'commentaire.meta' ? " AND ci.commentaire LIKE $param " : ''). |
($type == 'commentaire.utilisateur' ? " AND ci.commentaire LIKE $param " : ''). |
($type == 'commentaire.*' ? " AND (ci.commentaire LIKE $param) " : ''). |
$this->construireWhereCoordonnees(). |
$this->construireWhereDept(). |
$this->construireWhereCommune(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereProjet(). |
$this->construireWhereTag(). |
'ORDER BY utilisateur ASC, ordre ASC'; |
//$this->debug[] = $requete; |
//die($requete); |
$resultats = $this->executerRequete($requete); |
$observations = null; |
if ($resultats != false) { |
$observations = array(); |
foreach ($resultats as $occurence) { |
$utilisateur = $occurence['utilisateur']; |
$id_obs = $occurence['id_obs']; |
if (!array_key_exists($utilisateur, $observations)) { |
$observations[$utilisateur] = array(); |
} |
if (!array_key_exists($id_obs, $observations[$utilisateur])) { |
$observations[$utilisateur][$id_obs] = $id_obs; |
} |
} |
} |
return $observations; |
} |
private function assemblerObsEnConditionSql($observations, $operateur = 'AND') { |
$sql = ''; |
if ($observations != null) { |
// Pré-construction du where de la requête |
$tpl_where = "(id_observation IN (%s))"; |
foreach ($observations as $utilisateur => $ids_obs) { |
$morceaux_requete[] = sprintf($tpl_where, implode(',', $ids_obs)); |
} |
if (count($morceaux_requete) > 0) { |
$sql = implode(" \nOR ", $morceaux_requete); |
} |
} else { |
// Nous voulons que la requête ne retourne rien |
$sql = "id_observation = ''"; |
} |
$sql = " $operateur ($sql) "; |
return $sql; |
} |
private function construireWhereDept() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->parametres); |
if (isset($dept) && !$this->etreNull($dept)) { |
$valeurs_a_proteger = explode(',',trim($dept)); |
foreach ($valeurs_a_proteger as $valeur) { |
$valeurs_protegees[] = '(ce_zone_geo LIKE '.$this->bdd->quote('INSEE-C:'.$valeur.'%').') '; |
} |
$valeurs = implode(' OR ', $valeurs_protegees); |
$sql = " AND ($valeurs) "; |
} |
return $sql; |
} |
private function construireWhereCommune() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->parametres); |
if (isset($commune) && !$this->etreNull($commune)) { |
$commune = $this->proteger($commune); |
$sql = " AND zone_geo LIKE $commune "; |
} |
return $sql; |
} |
private function construireWherePhotosSeulement() { |
$sql = ''; |
if (isset($this->parametres['photos']) && $this->parametres['photos'] == 1) { |
$sql = 'AND co.id_observation IN (SELECT DISTINCT id_observation FROM cel_obs_images) '; |
} |
return $sql; |
} |
private function construireWhereUtilisateur() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->parametres); |
if (isset($utilisateur) && !$this->etreNull($utilisateur)) { |
$utilisateur = $this->proteger($utilisateur); |
$sql = " AND courriel_utilisateur = $utilisateur "; |
} |
return $sql; |
} |
private function construireWhereNumTaxon() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->parametres); |
if (isset($num_taxon) && !$this->etreNull($num_taxon)) { |
$num_taxon = $this->proteger($num_taxon); |
$sql = " AND nt = $num_taxon "; |
} |
return $sql; |
} |
private function construireWhereProjet() { |
$sql = ''; |
// Récupération des coordonnées depuis l'id station |
extract($this->parametres); |
$projet_sql = isset($projet) ? $this->getSqlWhereProjet($projet) : null; |
if (!$this->etreNull($projet_sql)) { |
$sql = " AND ($projet_sql) "; |
} |
return $sql; |
} |
/** |
* Traitement de $projet pour construction du filtre dans la requête |
*/ |
private function getSqlWhereProjet($projet) { |
$sql = null; |
if (isset($projet) && !$this->etreNull($projet)) { |
$sql = 'co.mots_cles_texte LIKE '.$this->proteger($projet); |
} |
return $sql; |
} |
private function construireWhereTag() { |
$sql = ''; |
extract($this->parametres); |
$tag_sql = isset($tag) ? $this->getSqlWhereObsAvecImagesTaguees($tag) : null; |
if (!$this->etreNull($tag_sql)) { |
$sql = " AND ($tag_sql) "; |
} |
return $sql; |
} |
/** |
* Traitement de $tag pour construction du filtre dans la requête |
*/ |
private function getSqlWhereObsAvecImagesTaguees($tag) { |
$sql = null; |
if (isset($tag) && !$this->etreNull($tag)) { |
$tag_sql = $this->getSqlWhereMotsCles($tag); |
// Construction de la requête |
$requete = 'SELECT DISTINCT coi.id_observation AS id_obs, ci.ce_utilisateur AS utilisateur '. |
'FROM cel_images ci'. |
' LEFT JOIN cel_obs_images coi'. |
' ON (ci.id_image = coi.id_image) '. |
' LEFT JOIN cel_obs AS co '. |
' ON (coi.id_observation = co.id_observation) '. |
' LEFT JOIN cel_zones_geo AS l '. |
" ON (l.id_zone_geo = co.ce_zone_geo) ". |
"WHERE transmission = '1' ". |
$this->construireWhereCoordonnees(). |
$this->construireWhereUtilisateur(). |
$this->construireWhereNumTaxon(). |
$this->construireWhereNomTaxon(). |
$this->construireWhereProjet(). |
(!$this->etreNull($tag_sql) ? "AND ($tag_sql) " : ''). |
'ORDER BY utilisateur ASC, ci.ordre ASC'; |
//$this->debug[] = $requete; |
//die($requete); |
$elements_tag = $this->executerRequete($requete); |
$requete_tag = array(); |
if ($elements_tag != false && count($elements_tag) > 0) { |
$filtres = array(); |
foreach ($elements_tag as $occurence) { |
$utilisateur = $occurence['utilisateur']; |
$id_obs = $occurence['id_obs']; |
if (!array_key_exists($utilisateur, $filtres)) { |
$filtres[$utilisateur] = array(); |
} |
if (!array_key_exists($id_obs, $filtres[$utilisateur])) { |
$filtres[$utilisateur][$id_obs] = $id_obs; |
} |
} |
// Pré-construction du where de la requête |
$tpl_where = "(id_observation IN (%s))"; |
foreach ($filtres as $utilisateur => $id_obs) { |
$requete_tag[] = sprintf($tpl_where, implode(',', $id_obs)); |
} |
} else { |
$this->messages[] = "Aucune observation ne possède d'images avec ce mot-clé."; |
} |
if (count($requete_tag) > 0) { |
$sql = implode(" \nOR ", $requete_tag); |
} |
} |
return $sql; |
} |
/** |
* Traitement de $tag pour construction du filtre dans la requête |
*/ |
private function getSqlWhereMotsCles($tag) { |
$sql = null; |
$mots_cles = $this->decomposerParametreTag($tag); |
$requete_projet = $this->getSqlWhereMotsClesImages($mots_cles); |
$sql = $requete_projet; |
//$this->debug[] = $sql; |
return $sql; |
} |
/** |
* Traitement de $tag pour construction du filtre dans la requête |
*/ |
private function getSqlWhereMotsClesImages($mots_cles_encodes) { |
$where_mots_cles_images = array(); |
foreach ($mots_cles_encodes['motsClesEncodesProteges'] as $mot_cle_encode) { |
$where_mots_cles_images[] = "ci.mots_cles_texte LIKE $mot_cle_encode"; |
} |
$where_mots_cles_images = implode(' '.$mots_cles_encodes['type'].' ', $where_mots_cles_images); |
return $where_mots_cles_images; |
} |
private function decomposerParametreTag($tags) { |
$mots_cles = array('type' => null, 'motsCles' => null, 'motsClesEncodesProteges' => null); |
if (preg_match('/.+OU.+/', $tags)) { |
$mots_cles['type'] = 'OR'; |
$mots_cles['motsCles'] = explode('OU', $tags); |
} else if (preg_match('/.+ET.+/', $tags)) { |
$mots_cles['type'] = 'AND'; |
$mots_cles['motsCles'] = explode('ET', $tags); |
} else { |
$mots_cles['motsCles'][] = $tags; |
} |
foreach ($mots_cles['motsCles'] as $mot) { |
$mots_cles['motsClesEncodesProteges'][] = $this->bdd->quote('%'.$mot.'%'); |
} |
$this->debug[] = $mots_cles; |
return $mots_cles; |
} |
private function decomposerParametreStation() { |
$station_infos = array(); |
if (isset($this->parametres['station'])) { |
$station = $this->parametres['station']; |
$this->debug[] = $station; |
list($type, $coord) = explode(':', $station); |
if ($type == 'UTM') { |
list($utm_x, $utm_y, $secteur) = explode('-', $coord); |
$station_infos = array('utm_x' => $utm_x, 'utm_y' => $utm_y, 'secteur' => $secteur); |
} else if ($type == 'LngLat') { |
list($longitude, $latitude) = explode('-', $coord); |
$station_infos = array('longitude' => $longitude, 'latitude' => $latitude); |
} |
$station_infos['type'] = $type; |
} |
return $station_infos; |
} |
private function decomposerParametreDate() { |
$date_infos = array(null,null); |
if (isset($this->parametres['date'])) { |
$date = $this->parametres['date']; |
if (strpos($date, ':')) { |
list($type, $date) = explode(':', $date); |
} else { |
$type = 'observation'; |
} |
$date = str_replace('/', '-', $date); |
if (preg_match('/(^[0-9]{2})-([0-9]{2})-([0-9]{4}$)/', $date, $matches)) { |
$date = $matches[3].'-'.$matches[2].'-'.$matches[1]; |
} |
$date_infos = array($type, $date); |
} |
return $date_infos; |
} |
private function decomposerParametreTaxon() { |
$nom_infos = array(null, null); |
if (isset($this->parametres['taxon'])) { |
$taxon = $this->parametres['taxon']; |
if (strpos($taxon, ':')) { |
$nom_infos = explode(':', $taxon); |
} else { |
$nom_infos = array('retenu', $taxon); |
} |
} |
return $nom_infos; |
} |
private function decomposerParametreCommentaire() { |
$commentaire_infos = array(null, null); |
if (isset($this->parametres['commentaire'])) { |
$commentaire = $this->parametres['commentaire']; |
if (strpos($commentaire, ':')) { |
$commentaire_infos = explode(':', $commentaire); |
} else { |
$commentaire_infos = array('observation', $commentaire); |
} |
} |
return $commentaire_infos; |
} |
} |
/branches/v1.6-croc/jrest/services/CelWidgetSaisie.php |
---|
New file |
0,0 → 1,581 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Service permettant d'insérer les informations fournie par le widget Saisie dans le CEL. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* Cas d'utilisation : |
* PUT /CelWidgetSaisie : ajout de données en les passant via $_POST |
* |
* @author Jean-Pascal MILCENT <jpm@clapas.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2011, Jean-Pascal MILCENT |
*/ |
class CelWidgetSaisie extends CelMotCle { |
private $projet = null; |
private $tagsObs = null; |
private $tagsImg = null; |
private $champsEtendusObs = null; |
private $utilisateur_id = null; |
const DUREE_DE_VIE_IMG = 86400;// 3600 * 24 * 2 = 172 800 |
const ARRET_SERVICE = false;// Permet de bloquer le service en cas de problème sur le serveur |
private $correspondanceIdImgTags = array(); |
public function createElement($requeteDonnees) { |
if (self::ARRET_SERVICE) { |
$this->messages[] = "Désactivation temporaire du service d'envoi des données au CEL."; |
} else if (array_key_exists('projet', $requeteDonnees)) { |
$this->debug[] = 'Projet : ok'; |
$this->projet = $requeteDonnees['projet']; |
if (array_key_exists('tag-obs', $requeteDonnees) && $requeteDonnees['tag-obs'] != '') { |
$this->tagsObs = explode(',', $requeteDonnees['tag-obs']); |
} |
$this->tagsObs[] = 'Projets coopératifs>'.$this->projet; |
if (array_key_exists('tag-img', $requeteDonnees) && $requeteDonnees['tag-img'] != '') { |
$this->tagsImg = explode(',', $requeteDonnees['tag-img']); |
} |
$this->tagsImg[] = 'Projets coopératifs>'.$this->projet; |
if (array_key_exists('utilisateur', $requeteDonnees)) { |
$this->debug[] = 'Utilisateur : ok'; |
$utilisateur = $requeteDonnees['utilisateur']; |
if (array_key_exists('courriel', $utilisateur)) { |
$this->debug[] = 'Courriel : ok'; |
$utilisateur = $this->affecterChampsManquantsUtilisateur($utilisateur); |
extract($utilisateur); |
$this->utilisateur_id = $id_utilisateur; |
$ordre = $this->getMaxOrdre($id_utilisateur); |
if (!is_null($ordre)) { |
$requeteDonnees = $this->supprimerSlashesProfond($requeteDonnees); |
// Triage et manipulation des données |
$observations = array(); |
foreach ($requeteDonnees as $cle => $obs) { |
if (preg_match('/^obsId[0-9]+$/', $cle)) { |
$ordreObs = $ordre++; |
$this->debug[] = 'commune_nom : '.$obs['commune_nom']; |
$this->debug[] = 'commune_code_insee : '.$obs['commune_code_insee']; |
$obsAAjouter = array(); |
$obsAAjouter['ce_utilisateur'] = $id_utilisateur; |
$obsAAjouter['courriel_utilisateur'] = $courriel; |
$obsAAjouter['prenom_utilisateur'] = $prenom; |
$obsAAjouter['nom_utilisateur'] = $nom; |
$obsAAjouter['ordre'] = $ordreObs; |
$obsAAjouter['nom_sel'] = $obs['nom_sel']; |
$obsAAjouter['nom_sel_nn'] = isset($obs['num_nom_sel']) ? $obs['num_nom_sel'] : null; |
$obsAAjouter['nom_ret'] = isset($obs['nom_ret']) ? $obs['nom_ret'] : null; |
$obsAAjouter['nom_ret_nn'] = isset($obs['num_nom_ret']) ? $obs['num_nom_ret'] : null; |
$obsAAjouter['nt'] = isset($obs['num_taxon']) ? $obs['num_taxon'] : null; |
$obsAAjouter['famille'] = isset($obs['famille']) ? $obs['famille'] : null; |
$obsAAjouter['nom_referentiel'] = isset($obs['referentiel']) ? $obs['referentiel'] : null; |
$obsAAjouter['date_observation'] = $this->transormerDateFrVersMysql($obs['date']); |
$obsAAjouter['commentaire'] = $obs['notes']; |
$obsAAjouter['zone_geo'] = $obs['commune_nom']; |
$obsAAjouter['ce_zone_geo'] = 'INSEE-C:'.$obs['commune_code_insee']; |
$obsAAjouter['lieudit'] = isset($obs['lieudit']) ? $obs['lieudit'] : null; |
$obsAAjouter['station'] = isset($obs['station']) ? $obs['station'] : null; |
$obsAAjouter['milieu'] = $obs['milieu']; |
$obsAAjouter['latitude'] = $obs['latitude']; |
$obsAAjouter['longitude'] = $obs['longitude']; |
$obsAAjouter['geodatum'] = 'WGS84'; |
$obsAAjouter['transmission'] = '1'; |
$obsAAjouter['date_creation'] = date('Y-m-d H:i:s'); |
$obsAAjouter['date_modification'] = $obsAAjouter['date_creation']; |
$obsAAjouter['date_transmission'] = $obsAAjouter['date_creation']; |
$this->champsEtendusObs[$ordreObs] = isset($obs['obs_etendue']) ? $obs['obs_etendue'] : array(); |
$imgAAjouter = null; |
if (!empty($obs['image_nom'])) { |
$imgAAjouter = $this->traiterImagesALierAObs($id_utilisateur, $ordreObs, $obs); |
} |
$observations[$ordreObs] = array( |
'obs' => $this->protegerTableau($obsAAjouter), |
'img' => $imgAAjouter); |
} |
} |
$this->debug[] = 'Nbre obs ajoutée : '.count($observations); |
// Insertion dans la base |
$obs_a_taguer_ordres = array(); |
$img_a_taguer_ids = array(); |
foreach ($observations as $infos) { |
$obs = $infos['obs']; |
$img = $infos['img']; |
$champs = implode(', ', array_keys($obs)); |
$valeurs = implode(', ', $obs); |
$requete = "INSERT INTO cel_obs ($champs) VALUES ($valeurs) "; |
if ($this->executerRequeteSimple($requete) === false) { |
$this->messages[] = "Un problème est survenu lors de l'insertion de l'obs dans la base de données."; |
} else { |
$obs_a_taguer_ordres[] = trim($obs['ordre'], "'"); |
} |
// si le formulaire contient une image on la traite |
if ($img != null) { |
$this->nettoyerImagesUploades(); |
$img_a_taguer_ids = $this->stockerImagesEtLierAObs($img, $id_utilisateur, $utilisateur); |
} |
} |
$obs_a_taguer_ids = $this->obtenirIdsObsPourTableauOrdres($this->utilisateur_id, $obs_a_taguer_ordres); |
$this->taguerObs($obs_a_taguer_ids); |
$this->taguerImg($img_a_taguer_ids); |
// Les champs taggés sont des champs supplémentaires stockés sous forme de clé => valeur |
$this->ajouterChampsEtendusObs($obs_a_taguer_ids, $this->champsEtendusObs); |
} else { |
$this->messages[] = "Un nouveau numéro d'ordre d'observation n'a pu être généré."; |
} |
} else { |
$this->messages[] = "L'identifiant de l'utilisateur (courriel) n'a pas été transmis."; |
} |
} else { |
$this->messages[] = "Les informations concernant l'utilisateur (prénom, nom, courriel) n'ont pas été transmises."; |
} |
} else { |
$this->messages[] = "Les informations concernant le projet coopératif n'ont pas été transmises."; |
} |
$msg = (count($this->messages) > 0) ? 'erreur' : 'ok'; |
$retour = (object) array('msg' => $msg); |
$this->envoyerJson($retour); |
} |
private function ajouterChampsEtendusObs($obs_ids, $obs_a_champs_etendus) { |
$champs_etendus_obs = array(); |
foreach($obs_ids as $id_obs) { |
$champs = array_shift($obs_a_champs_etendus); |
if($champs != null && is_array($champs)) { |
foreach($champs as $champ_etendu => $valeur) { |
$champs_etendus_obs[] = array( |
'id' => $id_obs, |
'cle' => $champ_etendu, |
'valeur' => $valeur |
); |
} |
} |
} |
$gestion_champs_etendus = new GestionChampsEtendus($this->config, 'obs'); |
$ajout_champ_etendus = $gestion_champs_etendus->ajouterChampsEtendusMultiplesAElementsMultiples($champs_etendus_obs); |
return $ajout_champ_etendus; |
} |
private function traiterImagesALierAObs($id_utilisateur, $ordreObs, $obs) { |
$imgAAjouter = null; |
if(is_array($obs['image_nom'])) { |
$imgAAjouter = array(); |
foreach ($obs['image_nom'] as $index => $nom_image) { |
$image = array(); |
$image['id_utilisateur'] = $id_utilisateur; |
$image['id_obs'] = $ordreObs; |
$image['nom'] = $nom_image; |
$image['tags'] = isset($obs['image_tag'][$index]) ? explode(',',$obs['image_tag'][$index]) : ''; |
// on suppose que les b64 des images sont envoyés dans le même ordre que leurs noms |
// TODO: indexer le tableau avec le nom des images |
$image['b64'] = isset($obs['image_b64'][$index]) ? $obs['image_b64'][$index] : ''; |
$this->debug[] = 'Contient B64 : '.(empty($obs['image_b64']) ? 'non' : 'oui'); |
$imgAAjouter[] = $image; |
} |
} else { |
if (!empty($obs['image_nom'])) { |
$imgAAjouter = array(); |
$imgAAjouter['id_utilisateur'] = $id_utilisateur; |
$imgAAjouter['id_obs'] = $ordreObs; |
$imgAAjouter['nom'] = $obs['image_nom']; |
//$imgAAjouter['tags'] = isset($obs['image_tag']) ? explode(',',$obs['image_tag']) : ''; |
$imgAAjouter['b64'] = isset($obs['image_b64']) ? $obs['image_b64'] : array(); |
$this->debug[] = 'Contient B64 : '.(empty($obs['image_b64']) ? 'non' : 'oui'); |
} |
} |
return $imgAAjouter; |
} |
private function stockerImagesEtLierAObs($img, $id_utilisateur, $utilisateur) { |
if(!isset($img['nom']) && is_array($img)) { |
foreach($img as $index => $image) { |
$nomFichierImg = $this->traiterNomFichierImage($image['nom']); |
$cheminImage = $this->config['cel']['chemin_stockage_temp']."/$nomFichierImg"; |
// Si l'image est transmise en base 64 |
if (empty($image['b64']) === false) { |
$this->transformerBase64enFichier($cheminImage, $image['b64']); |
} |
$this->debug[] = 'Nom fichier img debut :'.$nomFichierImg; |
$idImg = $this->ajouterImageSurDdEtBdd($utilisateur, $cheminImage, $nomFichierImg); |
if ($idImg !== false) { |
$liaisonOk = $this->lierObsEtImg($idImg, $id_utilisateur, $image['id_obs']); |
if ($liaisonOk === true) { |
$img_a_taguer_ids[] = $idImg; |
if(isset($image['tags'])) { |
$this->correspondanceIdImgTags[$idImg] = $image['tags']; |
} |
} |
} |
} |
} else { |
$nomFichierImg = $this->traiterNomFichierImage($img['nom']); |
$cheminImage = $this->config['cel']['chemin_stockage_temp']."/$nomFichierImg"; |
// Si l'image est transmise en base 64 |
if (empty($img['b64']) === false) { |
$this->transformerBase64enFichier($cheminImage, $img['b64']); |
} |
$this->debug[] = 'Nom fichier img debut :'.$nomFichierImg; |
$idImg = $this->ajouterImageSurDdEtBdd($utilisateur, $cheminImage, $nomFichierImg); |
if ($idImg !== false) { |
$liaisonOk = $this->lierObsEtImg($idImg, $id_utilisateur, $img['id_obs']); |
if ($liaisonOk === true) { |
$img_a_taguer_ids[] = $idImg; |
if(isset($img['tags'])) { |
$this->correspondanceIdImgTags[$idImg] = $img['tags']; |
} |
} |
} |
} |
return $img_a_taguer_ids; |
} |
private function affecterChampsManquantsUtilisateur($utilisateur) { |
$gestion_utilisateur = new User($this->config); |
$infos_complementaires = $gestion_utilisateur->obtenirUtilisateurSiExiste($utilisateur['courriel']); |
if(!isset($utilisateur['id_utilisateur']) || trim($utilisateur['id_utilisateur']) == '') { |
$utilisateur['id_utilisateur'] = ($infos_complementaires['connecte']) ? $infos_complementaires['id_utilisateur'] : $utilisateur['courriel']; |
$utilisateur['prenom'] = trim($infos_complementaires['prenom']) != '' ? $infos_complementaires['prenom'] : $utilisateur['prenom']; |
$utilisateur['nom'] = trim($infos_complementaires['nom']) != '' ? $infos_complementaires['nom'] : $utilisateur['nom']; |
} |
return $utilisateur; |
} |
private function supprimerSlashesProfond($valeur) { |
$valeur = is_array($valeur) ? array_map(array($this, 'supprimerSlashesProfond'), $valeur) : stripslashes($valeur); |
return $valeur; |
} |
private function getMaxOrdre($id_utilisateur) { |
$ordre = null; |
$identifiant = $this->bdd->quote($id_utilisateur); |
$requete = "SELECT MAX(ordre) AS ordre ". |
"FROM cel_obs ". |
"WHERE ce_utilisateur = ".$this->proteger($id_utilisateur)." "; |
$ordre_max = $this->executerRequete($requete, 'Column'); |
if ($ordre_max !== false) { |
$ordre = $ordre_max + 1; |
} |
return $ordre; |
} |
/** |
* Transforme une date au format français (jj/mm/aaaa) dans un format Mysql (aaaa-mm-jj). |
* @param string $dateFr date au format français (jj/mm/aaaa) |
* @return string date au format Mysql (aaaa-mm-jj) |
*/ |
private function transormerDateFrVersMysql($dateFr) { |
$dateMysql = '0000-00-00'; |
$morceauxDate = explode('/', $dateFr); |
if (count($morceauxDate) == 3) { |
$dateMysql = implode('-', array_reverse($morceauxDate)); |
} |
return $dateMysql; |
} |
private function taguerObs($obs_a_taguer_ids) { |
if (count($obs_a_taguer_ids) > 0) { |
foreach ($this->tagsObs as $hierarchieTag) { |
$tagsALier = explode('>', $hierarchieTag); |
$liaisonOk = $this->lierObsAMotsCles($obs_a_taguer_ids, $tagsALier); |
if ($liaisonOk === false) { |
$e = "Toutes les observations n'ont pas pu être liées aux mots-clés : $hierarchieTag"; |
$this->messages[] = $e; |
} |
} |
} |
} |
private function lierObsAMotsCles($observations_ids, $tags) { |
$idTagParent = self::OBS_RACINE_ID; |
$listeIdsTags = array(); |
foreach ($tags as $tag) { |
$tag = $this->nettoyerTag($tag); |
if ($tag != '') { |
$id_mot_cle = $this->ajouterMotCleObs($this->utilisateur_id, $tag, $idTagParent); |
if ($id_mot_cle !== false) { |
$listeIdsTags[] = $id_mot_cle; |
$idTagParent = $id_mot_cle; |
} |
} |
} |
$liaison_ok = $this->lierMotCleObs($this->utilisateur_id, $listeIdsTags, $observations_ids); |
return $liaison_ok; |
} |
private function taguerImg($img_a_taguer_ids) { |
if (count($img_a_taguer_ids) > 0) { |
$this->debug[] = "Tags img : ".print_r($this->tagsImg, true); |
foreach ($this->tagsImg as $hierarchieTag) { |
$tagsALier = explode('>', $hierarchieTag); |
$liaisonOk = $this->lierImgAMotsCles($img_a_taguer_ids, $tagsALier); |
if ($liaisonOk === false) { |
$e = "Toutes les images n'ont pas pu être liées aux mots-clés : $hierarchieTag"; |
$this->messages[] = $e; |
} |
} |
} |
// Liaison des tags spécifiques à chaque image s'il y en a |
if(count($this->correspondanceIdImgTags) > 0) { |
foreach ($this->correspondanceIdImgTags as $id_img => $tags) { |
if($tags != null && !empty($tags)) { |
$this->lierImgAMotsCles(array($id_img), $tags); |
} |
} |
} |
} |
private function lierImgAMotsCles($images_ids, $tags) { |
$idTagParent = self::IMG_RACINE_ID; |
$listeIdsTags = array(); |
foreach ($tags as $tag) { |
$tag = $this->nettoyerTag($tag); |
if ($tag != '') { |
$id_mot_cle = $this->ajouterMotCleImg($this->utilisateur_id, $tag, $idTagParent); |
if ($id_mot_cle !== false) { |
$listeIdsTags[] = $id_mot_cle; |
$idTagParent = $id_mot_cle; |
} |
} |
} |
$liaison_ok = $this->lierMotCleImg($this->utilisateur_id, $listeIdsTags, $images_ids); |
return $liaison_ok; |
} |
private function nettoyerTag($tag) { |
$tag = trim($tag); |
$tag = preg_replace('/(?:\s+|[,]+)/', ' ', $tag); |
return $tag; |
} |
private function traiterNomFichierImage($fichierNom) { |
$fichierNom = preg_replace('/[.](jpeg|jpg)$/i', '.jpg', strtolower(trim($fichierNom))); |
return $fichierNom; |
} |
/** |
* Décode l'image en base64,enregistre celle-ci sous forme de fichier du type de l'image |
* dans un dossier temporaire. |
*/ |
private function transformerBase64enFichier($cheminImage, $imageInfosB64) { |
// Enleve la partie data:image qui permet la previsalisation pour firefox de l'image en base64 |
$imageBase64 = explode(';', $imageInfosB64); |
$dataBase64 = explode(',',$imageBase64[1]); |
$dataImg = base64_decode($dataBase64[1]); |
$imageRessource = fopen($cheminImage, 'wb'); |
fwrite($imageRessource, $dataImg); |
fclose($imageRessource); |
if (file_exists($cheminImage) == false) { |
$this->messages[] = "Erreur lors de la création du fichier"; |
} |
} |
public function lierObsEtImg($id_image, $utilisateur, $ordre_obs) { |
$id_image = $this->proteger($id_image); |
$id_obs = $this->proteger($this->obtenirIdObsPourIdentifiantEtOrdre($utilisateur, $ordre_obs)); |
$requete = 'INSERT INTO cel_obs_images '. |
' (id_image, id_observation, date_liaison) '. |
"VALUES ($id_image, $id_obs, NOW()) ". |
' ON DUPLICATE KEY UPDATE id_image = id_image'; |
$liaison = true; |
if ($this->executerRequeteSimple($requete) === false) { |
$this->messages[] = "La requête de liaison de l'obs $id_obs à l'image $id_image pour l'utilisateur $id_utilisateur a échouée."; |
$liaison = false; |
} |
return $liaison; |
} |
private function obtenirIdObsPourIdentifiantEtOrdre($id_utilisateur, $ordre) { |
$id_utilisateur = $this->proteger($id_utilisateur); |
$ordre = $this->proteger($ordre); |
$requete = 'SELECT id_observation '. |
'FROM cel_obs '. |
"WHERE ce_utilisateur = $id_utilisateur ". |
" AND ordre = $ordre "; |
$resultat = $this->executerRequete($requete); |
$id_obs = (count($resultat) > 0) ? $resultat[0]['id_observation'] : false; |
return $id_obs; |
} |
private function obtenirIdsObsPourTableauOrdres($id_utilisateur, $ordres) { |
$id_utilisateur = $this->proteger($id_utilisateur); |
$ordres = array_map(array($this,'proteger'), $ordres); |
$requete = 'SELECT id_observation '. |
'FROM cel_obs '. |
"WHERE ce_utilisateur = $id_utilisateur ". |
" AND ordre IN (".implode(',',$ordres).") "; |
$resultat = $this->executerRequete($requete); |
$ids = array(); |
foreach($resultat as $id) { |
$ids[] = $id['id_observation']; |
} |
return $ids; |
} |
public function nettoyerImagesUploades() { |
$dossierStockage = $this->config['cel']['chemin_stockage_temp'].'/'; |
if (is_dir($dossierStockage)) { |
$objets = scandir($dossierStockage); |
if ($objets !== false) { |
foreach ($objets as $objet) { |
$chemin = $dossierStockage.$objet; |
if (is_file($chemin)) { |
$filemtime = @filemtime($chemin); |
if ($filemtime !== false) { |
$suppression = (time() - $filemtime >= self::DUREE_DE_VIE_IMG) ? true : false; |
if ($suppression === true) { |
unlink($chemin); |
} |
} |
} |
} |
} |
} |
} |
/** |
* Ajoute une image dans la base de données et stocke le fichier en fabriquant les miniatures, |
* renvoie le nouvel id d'image en cas de succès |
* |
* @param string $utilisateur l'utilisateur |
* @param string $cheminImage le chemin vers le fichier original de l'image |
* @param string $nomFichierImage le nom du fichier original de l'image |
*/ |
public function ajouterImageSurDdEtBdd($utilisateur, $cheminImage, $nomFichierImage) { |
$idImage = false; |
$idUtilisateur = $utilisateur['id_utilisateur']; |
$nouvelOrdre = $this->obtenirNouvelOrdrePourUtilisateur($idUtilisateur); |
if ($nouvelOrdre !== false) { |
if (file_exists($cheminImage)) { |
$extracteurMetadonnees = new ExtracteurMetadonnees(); |
$metadonnees = $extracteurMetadonnees->extraireMetadonnees($cheminImage) ; |
if ($metadonnees !== false) { |
$infosImage = $metadonnees; |
$infosImage['ordre'] = $nouvelOrdre; |
$infosImage['publiable_eflore'] = 'false'; |
$infosImage['nom_original'] = $nomFichierImage; |
$infosImage['ce_utilisateur'] = $idUtilisateur; |
$infosImage['courriel_utilisateur'] = $utilisateur['courriel']; |
$infosImage['nom_utilisateur'] = $utilisateur['nom']; |
$infosImage['prenom_utilisateur'] = $utilisateur['prenom']; |
$infosImage['md5'] = md5_file($cheminImage); |
$this->debug[] = 'Nom fichier img meta :'.$nomFichierImage; |
$requete = $this->construireRequeteInsertionImage($infosImage); |
$resultat = $this->executerRequeteSimple($requete); |
if ($resultat !== false) { |
$idImage = $this->obtenirIdImagePourIdentifiantEtOrdre($idUtilisateur, $nouvelOrdre); |
if ($idImage !== false) { |
$manipulateurImage = new ImageRecreation($this->config); |
$stockageOk = $manipulateurImage->stockerFichierEtCreerMiniatures($cheminImage, $idImage); |
if ($stockageOk) { |
$miniatureChemin = str_replace('.jpg', '_min.jpg', $cheminImage); |
if (file_exists($miniatureChemin)) { |
if (@unlink($miniatureChemin) === false) { |
$this->messages[] = "La miniature de l'image n'a pu être supprimée."; |
} |
} |
} else { |
$this->messages[] = "Une erreur s'est produite lors du stockage du fichier."; |
} |
} else { |
$this->messages[] = "Impossible d'obtenir le nouvel identifiant de l'image"; |
} |
} else { |
$this->messages[] = "Echec de l'insertion dans la base de donnees des informations de l'image."; |
} |
} else { |
$this->messages[] = "Erreur lors de l'extraction des metadonnées."; |
} |
} else { |
$this->messages[] = "L'image originale est introuvable sur le serveur."; |
} |
} else { |
$this->messages[] = "Erreur lors du calcul du nouvel ordre de l'image."; |
} |
return $idImage; |
} |
private function obtenirNouvelOrdrePourUtilisateur($id_utilisateur) { |
$id_utilisateur = $this->proteger($id_utilisateur); |
$requete = 'SELECT MAX(ordre) as max_ordre '. |
'FROM cel_images '. |
"WHERE ce_utilisateur = $id_utilisateur "; |
$resultat = $this->executerRequete($requete); |
$ordre = ($resultat) ? ++$resultat[0]['max_ordre'] : 0; |
return $ordre; |
} |
private function obtenirIdImagePourIdentifiantEtOrdre($id_utilisateur, $ordre) { |
$id_utilisateur = $this->proteger($id_utilisateur); |
$ordre = $this->proteger($ordre); |
$requete = 'SELECT id_image '. |
'FROM cel_images '. |
"WHERE ce_utilisateur = $id_utilisateur ". |
" AND ordre = $ordre "; |
$resultat = $this->executerRequete($requete); |
$id_image = (count($resultat) > 0) ? $resultat[0]['id_image'] : false; |
return $id_image; |
} |
private function construireRequeteInsertionImage($informations) { |
$champs = array('date_creation'); |
$valeurs = array('CURRENT_TIMESTAMP()'); |
foreach ($informations as $champ => $valeur) { |
$champs[] = $champ; |
$valeurs[] = is_null($valeur) ? 'NULL' : $this->proteger($valeur); |
if ($champ == 'date_creation' && $valeur != 'NULL') { |
$champs[] = 'date_creation'; |
$valeurs[] = $this->proteger($valeur); |
} |
} |
$champs = implode(', ', $champs); |
$valeurs = implode(', ', $valeurs); |
$requete = "INSERT INTO cel_images ($champs) VALUES ($valeurs) "; |
return $requete; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/CelImage.php |
---|
New file |
0,0 → 1,86 |
<?php |
// declare(encoding='UTF-8'); |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* Service fournissant la liste des ids des images liées à une observation. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* Cas d'utilisation : |
* /CelImage/liste-ids?obsId=[0-9]+ : ids des images liées à l'observation possédant l'identifiant 'obsId'. |
* |
* Sortie : |
* Type de sortie : json (par défaut), HTML en cas d'erreur. |
* |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org) |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version $Id$ |
*/ |
class CelImage extends Cel { |
/** |
* Méthode appelée avec une requête de type GET. |
*/ |
public function getElement($params) { |
$parametres = $this->traiterParametres(array('mode'), $params, false); |
extract($parametres); |
$contenu = ''; |
$retour = null; |
if (isset($mode)) { |
$methode = $this->traiterNomMethodeGet($mode); |
if (method_exists($this, $methode)) { |
$this->parametres = array_shift($params); |
$retour = $this->$methode(); |
} else { |
$service = get_class($this); |
$this->messages[] = "Ce type de mode '$mode' pour le service '$service' n'est pas disponible."; |
} |
} else { |
$this->messages[] = "Vous devez indiquer un type de mode d'interrogation."; |
} |
if (is_null($retour)) { |
$this->messages[] = "Un problème est survenu lors de l'appel au service CelImage"; |
} |
$this->envoyerJson($retour); |
} |
/** |
* Carte par défaut |
*/ |
private function getListeIds() { |
$ids = array(); |
if (isset($_GET['obsId'])) { |
$observations = $this->traiterValeursMultiples($_GET['obsId']); |
if (! is_null($observations)) { |
$requete = 'SELECT co.id_observation, cim.id_image '. |
'FROM cel_obs AS co '. |
' LEFT JOIN cel_obs_images AS coi '. |
' ON (coi.id_observation = co.id_observation) '. |
' LEFT JOIN cel_images AS cim '. |
' ON (coi.id_image = cim.id_image) '. |
"WHERE co.id_observation IN ($observations) "; |
$resultat_requete_images = $this->requeter($requete); |
$infos = array(); |
if(is_array($resultat_requete_images)) { |
$infos = $resultat_requete_images; |
} |
foreach ($infos as $info) { |
if(is_numeric($info['id_image'])) { |
$ids[$info['id_observation']][] = (int) $info['id_image']; |
} |
} |
} |
} |
return $ids; |
} |
} |
/branches/v1.6-croc/jrest/services/NameSearch.php |
---|
New file |
0,0 → 1,75 |
<?php |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david.delon@clapas.net> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* |
* in : utf8 |
* out : utf8 |
* |
* NameSearch.php |
* |
* Cas d'utilisation : |
* Service completion nom scientifique |
* |
* 1 : L'application recoit un debut de nom scientifique ainsi qu'un code de référentiel |
* 2 : Si le genre recu est >1, l'application retourne les 50 premieres genre commencant par ce prefixe |
* 3 : Si l'espece est presente l'application retourne les 50 premieres genre+espece commencant par ce prefixe |
*/ |
class NameSearch extends Cel { |
public function getRessource(){ |
//TODO: description du service à renvoyer |
print "[]"; |
return; |
} |
public function getElement($uid){ |
$liste_genre_espece = array(); |
$referentiel = null; |
$genre = null; |
$espece = null; |
if(isset($uid[0])) { |
$referentiel = $uid[0]; |
} |
if(isset($uid[1])) { |
$genre = $uid[1]; |
} |
if(isset($uid[2])) { |
$espece = $uid[2]; |
} |
$chercheur_infos_taxon = new RechercheInfosTaxonBeta($this->config, $referentiel); |
$liste_genre_espece = $chercheur_infos_taxon->rechercherGenreEspeceSurPrefixe($genre,$espece); |
$this->envoyerJson($liste_genre_espece); |
return true; |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.6 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.5 2007-05-21 18:13:30 ddelon |
* Refactoring et documentation |
* |
* |
*/ |
?> |
/branches/v1.6-croc/jrest/services/CelMotCle.php |
---|
New file |
0,0 → 1,550 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Classe mère permettant de rassembler les manipulation concernant les mots clés. |
* Pour l'utiliser, il suffit d'étendre votre service avec cette classe à la place de Cel. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @author Aurélien PERONNET <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2011, Tela-Botanica |
*/ |
// TODO : compléter la classe avec des méthdodes de modification, suppression et consultation des mots-clés. |
// TODO : ajout vérification de la non présence du caractère '|' dans les chaines utilisateurs... |
class CelMotCle extends Cel { |
const OBS_RACINE_ID = 'racine_obs'; |
const OBS_RACINE_NOM = 'Projets'; |
const OBS_TABLE_SUFFIXE = '_obs'; |
const IMG_RACINE_ID = 'racine'; |
const IMG_RACINE_NOM = 'Mots clés'; |
const IMG_TABLE_SUFFIXE = '_images'; |
const SEPARATEUR_MOT_CLE_TEXTE = ','; |
const SEPARATEUR_MOT_CLE_ID_OBS = ','; |
const SEPARATEUR_MOT_CLE_ID_IMG = ','; |
/** |
* @var String permet de savoir si nous avons à faire à un mot clé d'observation ou d'image. |
*/ |
private $suffix = ''; |
/** |
* @var String identifiant de l'utilisateur dont nous gérons les mots-clés. |
*/ |
private $utilisateur_id = ''; |
public function lierMotCleObs($utilisateur_id, Array $mots_cles_ids, Array $ids) { |
$this->suffix = self::OBS_TABLE_SUFFIXE; |
$this->utilisateur_id = $utilisateur_id; |
return $this->lierMotCle($utilisateur_id, $mots_cles_ids, $ids); |
} |
public function lierMotCleImg($utilisateur_id, Array $mots_cles_ids, Array $ids) { |
$this->suffix = self::IMG_TABLE_SUFFIXE; |
$this->utilisateur_id = $utilisateur_id; |
return $this->lierMotCle($utilisateur_id, $mots_cles_ids, $ids); |
} |
/** |
* Lie un mot-clé à une ou plusieurs images ou obs suivant le suffixe en cours. |
* |
* @param String $utilisateur_id identifiant de l'utilisateur. |
* @param Array $mots_cles_ids tableau d'ids des mot-clé. |
* @param Array $ids un tableau d'ids d'obs ou img (int) qui seront associées aux mots clés. |
*/ |
public function lierMotCle($utilisateur_id, Array $mots_cles_ids, Array $ids) { |
$retour = false; |
if ($this->contenirNbresEntiers($ids)) { |
$champ_objet_lie = ($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'id_observation' : 'id_image'; |
$champ_mot_cle = ($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'id_mot_cle_obs' : 'id_mot_cle_image'; |
// le mot clé ignore est spécifique mysql, mais il est utilisé ici pour des raisons |
// de performance, à remplacer par un test sur les mots clés déjà existant si ça gène |
$requete = "INSERT IGNORE INTO cel{$this->suffix}_mots_cles ". |
'('.$champ_objet_lie.', '.$champ_mot_cle.') '. |
'VALUES '; |
foreach($ids as $id) { |
foreach($mots_cles_ids as $mot) { |
$requete .= '('.$id.','.$this->proteger($mot).'),'; |
} |
} |
$requete = rtrim($requete,','); |
$resultat = $this->executer($requete); |
// J'en suis ici |
if ($resultat) { |
$retour = true; |
foreach ($ids as $id) { |
$regeneration = $this->regenererIndexTexteMotCle($id); |
if ($regeneration === false) { |
$retour = false; |
} |
} |
} else { |
$e = "Erreur de mise à jour des mots clés d'une obs : $requete"; |
$this->logger('CEL_bugs', $e); |
$this->messages[] = $e; |
} |
} else { |
$this->messages[] = "Le tableau des ordres des obs ne contenait pas que des nombres entiers."; |
} |
return $retour; |
} |
private function contenirNbresEntiers($ordres) { |
$ok = true; |
foreach ($ordres as $ordre) { |
if (! preg_match('/^[0-9]+$/', $ordre)) { |
$this->debug[] = "Ordre pb : $ordre"; |
$ok = false; |
} |
} |
return $ok; |
} |
private function regenererIndexTexteMotCle($id) { |
$ok = false; |
$mots_cles = $this->obtenirMotsClesTexte($id); |
$mots_cles_concatenes = $this->concatenerMotsCles($mots_cles); |
$ok = $this->mettreAJourMotsClesConcatenes($mots_cles_concatenes, $id); |
return $ok; |
} |
private function obtenirMotsClesTexte($id_image_ou_obs) { |
$requete = 'SELECT mot_cle '. |
'FROM '.'cel_mots_cles'.$this->suffix.' '. |
'WHERE id_mot_cle_'.(($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'obs' : 'image').' IN '. |
'('. |
'SELECT id_mot_cle_'.(($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'obs' : 'image').' '. |
'FROM cel'.$this->suffix.'_mots_cles '. |
'WHERE '.(($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'id_observation' : 'id_image').' = '.$this->proteger($id_image_ou_obs). |
')'; |
$resultats = $this->requeter($requete); |
return $resultats; |
} |
private function formaterIdsMotClePourClauseInSql($mot_cle_ids) { |
$mot_cle_ids = $this->nettoyerMotsCles($mot_cle_ids); |
$mot_cle_ids = str_replace(self::SEPARATEUR_MOT_CLE_ID_OBS, ',', $mot_cle_ids); |
$mot_cle_ids = trim($mot_cle_ids, ','); |
$mot_cle_ids_proteges = implode(',', $this->protegerTableau(explode(',', $mot_cle_ids))); |
return $mot_cle_ids_proteges; |
} |
private function concatenerMotsCles(Array $mots_cles) { |
$mot_cles_concatenes = ''; |
if (count($mots_cles) > 0) { |
foreach ($mots_cles as $mot_cle) { |
$mot_cles_concatenes .= $mot_cle['mot_cle'].self::SEPARATEUR_MOT_CLE_TEXTE; |
} |
} |
$mot_cles_concatenes = rtrim($mot_cles_concatenes, self::SEPARATEUR_MOT_CLE_TEXTE); |
return $mot_cles_concatenes; |
} |
private function mettreAJourMotsClesConcatenes($mots_cles, $id) { |
$mots_cles = $this->proteger($mots_cles); |
$utilisateur_id = $this->proteger($this->utilisateur_id); |
$requete = 'UPDATE cel'.$this->suffix." ". |
"SET mots_cles_texte = $mots_cles ". |
"WHERE id_".(($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'observation' : 'image')." = $id "; |
$ok = $this->executer($requete) ? true : false; |
return $ok; |
} |
private function nettoyerMotsCles($chaine) { |
$valeur = str_replace('null', '', $chaine); |
$valeur = trim($valeur, ';;'); |
return $valeur; |
} |
public function ajouterMotCleObs($utilisateur_id, $mot_cle, $mot_cle_parent_id) { |
$this->suffix = self::OBS_TABLE_SUFFIXE; |
$this->utilisateur_id = $utilisateur_id; |
return $this->ajouterMotCle($mot_cle, $mot_cle_parent_id); |
} |
public function ajouterMotCleImg($utilisateur_id, $mot_cle, $mot_cle_parent_id) { |
$this->suffix = self::IMG_TABLE_SUFFIXE; |
$this->utilisateur_id = $utilisateur_id; |
return $this->ajouterMotCle($mot_cle, $mot_cle_parent_id); |
} |
private function ajouterMotCle($mot_cle, $mot_cle_parent_id) { |
$retour = true; |
$this->ajouterMotCleRacine(); |
if ($this->verifierAbsence($mot_cle, $mot_cle_parent_id)) { |
$mot_cle_id = $this->genererTagId($mot_cle); |
$this->commencerTransaction(); |
$bornes = $this->retrouverBornesEtNiveau($mot_cle_parent_id); |
$borne_pere = $bornes['bd']; |
$niveau = $bornes['niveau'] + 1; |
$bg = $bornes['bd']; |
$bd = $bg + 1; |
$mot_cle_encode = $this->encoderMotCle($mot_cle); |
$mot_cle_protege = $this->proteger($mot_cle); |
$bg = $this->proteger($bg); |
$bd = $this->proteger($bd); |
$mot_cle_encode = $this->proteger($mot_cle_encode); |
$mot_cle_id = $this->proteger($mot_cle_id); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
$mot_cle_parent_id_protege = $this->proteger($mot_cle_parent_id); |
$niveau = $this->proteger($niveau); |
$transaction_reussie_1 = $this->decalerBornesPlusDeux($borne_pere) ? true : false; |
$requete = "INSERT INTO cel_mots_cles{$this->suffix} ". |
"VALUES ($mot_cle_id, $id_utilisateur, $mot_cle_protege, $mot_cle_encode,". |
" $bg, $bd, $niveau, $mot_cle_parent_id_protege) "; |
$transaction_reussie_2 = $this->executerSQL($requete); |
if (!$transaction_reussie_2) { |
$e = "Échec d'insertion du mot-clé : $requete "; |
$this->messages[] = $e; |
} |
if ($transaction_reussie_1 && $transaction_reussie_2) { |
$retour = $this->completerTransaction(); |
} else { |
$retour = $this->annulerTransaction(); |
} |
} else { |
$e = "Le mot-clé '$mot_cle' existe déjà dans la table cel_mots_cles{$this->suffix}."; |
$this->debug[] = $e; |
} |
$id = ($retour) ? $this->getIdMotCle($mot_cle, $mot_cle_parent_id) : false; |
return $id; |
} |
private function genererTagId($tag) { |
$id = ($this->getHashCode($tag) + ((mt_rand() / (double)mt_getrandmax()) * 10000)); |
$id = str_replace(',', '.', $id); |
return $id; |
} |
private function getHashCode($chaine){ |
$hash = 0; |
$stringLength = strlen($chaine); |
for ($i = 0; $i < $stringLength; $i++) { |
$hash = 31 * $hash + $chaine[$i]; |
} |
return $hash; |
} |
private function ajouterMotCleRacine() { |
$nbre_mots_cles = $this->compterMotsCles(); |
$this->debug[] = "Nbre de mots-clés : $nbre_mots_cles"; |
if ($nbre_mots_cles == 0) { |
switch ($this->suffix) { |
case self::OBS_TABLE_SUFFIXE : |
$nom_racine = self::OBS_RACINE_NOM; |
$id_racine = self::OBS_RACINE_ID; |
break; |
case self::IMG_TABLE_SUFFIXE : |
$nom_racine = self::IMG_RACINE_NOM; |
$id_racine = self::IMG_RACINE_ID; |
break; |
default: |
$nom_racine = $this->suffix; |
$id_racine = $this->suffix; |
} |
$md5_racine = $this->proteger($this->encoderMotCle($nom_racine)); |
$nom_racine = $this->proteger($nom_racine); |
$id_racine = $this->proteger($id_racine); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
$requete = "INSERT INTO cel_mots_cles{$this->suffix} ". |
"VALUES ($id_racine, $id_utilisateur, $nom_racine, $md5_racine,". |
" 1, 2, 0, '') "; |
if ($this->executerSQL($requete) === false) { |
$e = "La requête d'insertion du mot-clé racine a échoué."; |
$this->messages[] = $e; |
} |
} |
} |
private function verifierAbsence($mot_cle, $mot_cle_parent_id) { |
$absence = false; |
$mot_cle = $this->proteger($mot_cle); |
$mot_cle_parent_id = $this->proteger($mot_cle_parent_id); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
$requete = 'SELECT COUNT(*) AS nbre '. |
"FROM cel_mots_cles{$this->suffix} ". |
"WHERE mot_cle = $mot_cle ". |
" AND id_utilisateur = $id_utilisateur ". |
" AND ce_mot_cle_".(($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'obs' : 'image')."_parent = $mot_cle_parent_id"; |
$nbre = $this->recupererValeur($requete); |
if ($nbre === false) { |
$e = "La requête de vérification d'absence d'un mot-clé a échoué."; |
$this->messages[] = $e; |
} else if ($nbre == 0) { |
$absence = true; |
} |
return $absence; |
} |
private function getIdMotCle($mot_cle, $mot_cle_parent_id) { |
$mot_cle = $this->proteger($mot_cle); |
$mot_cle_parent_id = $this->proteger($mot_cle_parent_id); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
$requete = 'SELECT id_mot_cle_'.(($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'obs' : 'image').' AS id '. |
"FROM cel_mots_cles{$this->suffix} ". |
"WHERE mot_cle = $mot_cle ". |
" AND id_utilisateur = $id_utilisateur ". |
" AND ce_mot_cle_".(($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'obs' : 'image')."_parent = $mot_cle_parent_id"; |
$resultat = $this->recupererResultat($requete); |
$mot_cle_id = ($resultat) ? $resultat['id'] : false; |
return $mot_cle_id; |
} |
private function compterMotsCles() { |
$nbre = 0; |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
$requete = 'SELECT COUNT(*) AS nbre '. |
"FROM cel_mots_cles{$this->suffix} ". |
"WHERE id_utilisateur = $id_utilisateur "; |
$nbre = $this->recupererValeur($requete); |
if ($nbre === false) { |
$e = "La requête de comptage du nombre de mots-clés a échoué."; |
$this->messages[] = $e; |
} |
return $nbre; |
} |
/** |
* Désactive l'auto-commit puis débute la transaction |
*/ |
private function commencerTransaction() { |
// Désactive l'autocommit le temps de la manipulation de l'arbre |
$requete = 'SET AUTOCOMMIT = 0 '; |
$reussite_autocommit = $this->executerSQL($requete); |
// Débute une nouvelle transaction |
$requete = 'BEGIN '; |
$reussite_begin = $this->executerSQL($requete); |
} |
/** |
* Termine la transaction puis réactive l'auto-commit |
*/ |
private function completerTransaction() { |
// Complète la transaction |
$requete = 'COMMIT '; |
$reussite_commit = $this->executerSQL($requete); |
// Réactive l'autocommit le temps de la manipulation de l'arbre |
$requete = 'SET AUTOCOMMIT = 1 '; |
$reussite_autocommit = $this->executerSQL($requete); |
return true; |
} |
/** |
* Annule la transaction et réactive l'auto-commit |
*/ |
private function annulerTransaction() { |
// Annule la transaction |
$requete = 'ROLLBACK '; |
$reussite_rollback = $this->executerSQL($requete); |
// Réactive l'autocommit le temps de la manipulation de l'arbre |
$requete = 'SET AUTOCOMMIT = 1 '; |
$reussite_autocommit = $this->executerSQL($requete); |
return false; |
} |
/** |
* Renvoie les bornes d'un noeud de l'arbre des mots clés |
*/ |
private function retrouverBornesEtNiveau($mot_cle_id) { |
$mot_cle_id = $this->proteger($mot_cle_id); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
$requete = 'SELECT bd, bg, niveau '. |
"FROM cel_mots_cles{$this->suffix} ". |
"WHERE id_mot_cle_".(($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'obs' : 'image')." = $mot_cle_id ". |
" AND id_utilisateur = $id_utilisateur "; |
$resultat = $this->recupererResultat($requete); |
return $resultat; |
} |
/** |
* Décale les bornes de deux pour insérer un nouvel élément |
*/ |
private function decalerBornesPlusDeux($valeur) { |
// Décalage borne droite |
$valeur = $this->proteger($valeur); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
$requete = "UPDATE cel_mots_cles{$this->suffix} ". |
'SET bd = bd + 2 '. |
"WHERE bd >= $valeur ". |
" AND id_utilisateur = $id_utilisateur "; |
$reussi_1 = $this->executerSQL($requete); |
if (!$reussi_1) { |
$e = "Échec du décalage de la borne droite de +2 : $requete "; |
$this->messages[] = $e; |
} |
// Décalage borne gauche |
$requete = "UPDATE cel_mots_cles{$this->suffix} ". |
'SET bg = bg + 2 '. |
"WHERE bg >= $valeur ". |
" AND id_utilisateur = $id_utilisateur "; |
$reussi_2 = $this->executerSQL($requete); |
if (!$reussi_2) { |
$e = "Échec du décalage de la borne gauche de +2 : $requete"; |
$this->messages[] = $e; |
} |
return ($reussi_1 && $reussi_2); |
} |
/** |
* Décale les bornes d'un intervalle négatif donné (pour la suppression d'un sous arbre). |
*/ |
private function decalerBornesMoinsIntervalle($bg, $bd) { |
$decalage = $bd - $bg + 1; |
$bg = $this->proteger($bg); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
// Décalage borne droite |
$requete = "UPDATE cel_mots_cles{$this->suffix} ". |
"SET bd = cmc_bd - $decalage ". |
"WHERE bd >= $bg ". |
" AND id_utilisateur = $id_utilisateur "; |
$reussi_1 = $this->executerSQL($requete); |
// Décalage borne gauche |
$requete = "UPDATE cel_mots_cles{$this->suffix} ". |
"SET bg = bg - $decalage ". |
"WHERE bg > $bg ". |
" AND id_utilisateur = $id_utilisateur "; |
$reussi_2 = $this->executerSQL($requete); |
return $reussi_1 && $reussi_2; |
} |
/** |
* Décale à droite des bornes donées d'un intervalle positif donné (pour l'ajout d'un sous arbre). |
*/ |
private function decalerBornesPlusIntervalle($valeur_bornes, $largeur) { |
$valeur_bornes = $this->proteger($valeur_bornes); |
$largeur = $this->proteger($largeur); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
// Décalage borne droite |
$requete = "UPDATE cel_mots_cles{$this->suffix} ". |
"SET bd = bd + $largeur ". |
"WHERE bd >= $valeur_bornes ". |
" AND id_utilisateur = $id_utilisateur "; |
$reussi_1 = $this->executerSQL($requete); |
// Décalage borne gauche |
$requete = "UPDATE cel_mots_cles{$this->suffix} ". |
"SET bg = bg + $largeur ". |
"WHERE bg >= $valeur_bornes ". |
" AND id_utilisateur = $id_utilisateur| "; |
$reussi_2 = $this->executerSQL($requete); |
return $reussi_1 && $reussi_2; |
} |
/** |
* Inverse les bornes d'un intervalle pour l'exclure des modifications sur l'arbre sans changer la hiérarchie. |
*/ |
private function exclureIntervalle($bg, $bd) { |
$bg = $this->proteger($bg); |
$bd = $this->proteger($bd); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
$requete = "UPDATE cel_mots_cles{$this->suffix} ". |
"SET bd = bd - $bd - 1 , ". |
" bg = bg - $bd - 1 ". |
"WHERE bd <= $bd ". |
" AND bg >= $bg ". |
" AND id_utilisateur = $id_utilisateur "; |
return $this->executerSQL($requete); |
} |
/** |
* Recale les bornes dun intervalle pour l'inclure dans l'arbre à la bonne place. |
* Décalage borne droite |
*/ |
private function inclureIntervalle($bg, $bd, $largeur, $modif_niveau) { |
$bg = $this->proteger($bg); |
$bd = $this->proteger($bd); |
$largeur = $this->proteger($largeur); |
$modif_niveau = $this->proteger($modif_niveau); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
$requete = "UPDATE cel_mots_cles{$this->suffix} ". |
"SET bg = bg + $largeur , ". |
" bd = bd + $largeur, ". |
" niveau = niveau + $modif_niveau ". |
"WHERE bg >= $bg ". |
" AND bd <= $bd ". |
" AND id_utilisateur = $id_utilisateur "; |
return $this->executerSQL($requete); |
} |
private function changerPere($mot_cle_id, $id_pere) { |
$mot_cle_id = $this->proteger($mot_cle_id); |
$id_pere = $this->proteger($id_pere); |
$id_utilisateur = $this->proteger($this->utilisateur_id); |
$requete = "UPDATE cel_mots_cles{$this->suffix} ". |
"SET ce_mot_cle_".(($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'obs' : 'image')."_parent = $id_pere ". |
"WHERE id_mot_cle_".(($this->suffix == self::OBS_TABLE_SUFFIXE) ? 'obs' : 'image')." = $mot_cle_id ". |
" AND id_utilisateur = $id_utilisateur "; |
return $this->executerSQL($requete); |
} |
private function executerSQL($requete) { |
$execution = $this->executer($requete); |
$execution = ($execution === false) ? false : true; |
return $execution; |
} |
private function recupererValeur($requete) { |
$resultat = $this->requeter($requete, Cel::SQL_RETOUR_COLONNE); |
return $resultat; |
} |
private function recupererResultat($requete) { |
$resultat = $this->requeter($requete, Cel::SQL_RETOUR_LIGNE, Cel::SQL_MODE_ASSOC); |
return $resultat; |
} |
private function recupererResultats($requete) { |
$resultat = $this->requeter($requete, Cel::SQL_RETOUR_COMPLET, Cel::SQL_MODE_ASSOC); |
return $resultat; |
} |
private function verifierLignesAffectees($requete) { |
$execution = $this->executer($requete); |
return $execution; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/CelMessage.php |
---|
New file |
0,0 → 1,86 |
<?php |
class CelMessage extends Cel { |
private $mode = 'obs'; |
/** |
* Méthode appelée avec une requête de type POST avec un identifiant d'obs. |
* Envoi un message à l'utilisateur ayant saisi l'observation |
* |
* @param int $uid[0] mode interrogation (obs ou image) |
* @param int $uid[1] identifiant observation ou image suivant le mode |
* @param pairs array tableau contenant les valeurs du formulaire de messagerie |
* (même format que le web service messagerie utilisateur de l'annuaire) |
*/ |
public function updateElement($uid,$pairs) |
{ |
$this->verifierParametresObligatoires($uid, $pairs); |
if(isset($pairs['type_envoi'])) { |
unset($pairs['type_envoi']); |
} |
if($uid[0] != 'obs' && $uid[0] != 'image') { |
$info = array(); |
$info = 'Aucun mode n\'a été indiqué '; |
$this->envoyer($info, 'text/html', 'utf-8', false); |
exit; |
} else { |
$this->mode = $uid[0]; |
$id = $uid[1]; |
$methode = 'obtenirCourrielUtilisateurPourId'.ucwords($this->mode); |
$courriel_utilisateur = $this->$methode($id); |
if($courriel_utilisateur !== false) { |
$resultat = $this->envoyerRequeteMessage($courriel_utilisateur, $pairs); |
$this->envoyerJson($resultat); |
exit; |
} else { |
$info = array(); |
$info = 'Impossible de trouver le courriel associé à cet identifiant '; |
$this->envoyer($info, 'text/html', 'utf-8', false); |
exit; |
} |
} |
} |
private function envoyerRequeteMessage($courriel_utilisateur, $pairs) { |
$base_url = $this->config['settings']['baseURLServicesAnnuaireTpl']; |
$rest_client = $this->getRestClient(); |
$url_messagerie = str_replace('%s', "utilisateur/".urlencode($courriel_utilisateur)."/message", $base_url); |
$resultat_json = $rest_client->modifier($url_messagerie, $pairs); |
$resultat = json_decode($resultat_json); |
return $resultat; |
} |
private function verifierParametresObligatoires($uid ,$params) { |
$params_obligatoires = array('sujet', 'message', 'utilisateur_courriel', 'destinataire_id'); |
$info = array(); |
if(!isset($uid[1]) || !is_numeric($uid[1])) { |
$info .= 'l\' identifiant doit être un entier '; |
} |
foreach($params_obligatoires as $param) { |
if(!isset($params[$param]) || trim($params[$param]) == "") { |
$info = 'le paramètre '.$param.' doit exister et ne peut pas être vide '; |
} |
} |
if(!empty($info)) { |
$this->envoyer($info, 'text/html', 'utf-8', false); |
exit; |
} |
} |
private function obtenirCourrielUtilisateurPourIdObs($id_obs) { |
$rechercheObservation = new RechercheObservation($this->config); |
return $rechercheObservation->obtenirCourrielUtilisateurPourIdObs($id_obs); |
} |
private function obtenirCourrielUtilisateurPourIdImage($id_image) { |
$rechercheImage = new RechercheImage($this->config); |
return $rechercheImage->obtenirCourrielUtilisateurPourIdImage($id_image); |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryImageCount.php |
---|
New file |
0,0 → 1,58 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2010, Aurélien Peronnet |
*/ |
/** |
* InventoryImageCount.php |
* |
* in : utf8 |
* out : utf8 |
* Cas d'utilisation : |
* Service recherche du nombre a partir de divers critères |
* |
* 2: Le service recherche le nombre d'images correspondant aux critères demandés |
* 3: Le service renvoie le nombre calculé |
*/ |
class InventoryImageCount extends Cel { |
/** |
* renvoie le nombre d'images correspondant aux criteres |
* uid[0] : utilisateur obligatoire |
* uid[1] : critères de filtrage de la forme critère1=valeur1;critère2=valeur2 |
*/ |
function getElement($uid) |
{ |
//TODO : remplacer le contenu du $uid[1] par le tableau $_GET; |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
$chercheur_images = new RechercheImage($this->config); |
$numero_page = 0; |
$taille_page = 50; |
$criteres = array(); |
$criteres = $_GET; |
$retour = $chercheur_images->compterImages($uid[0], $criteres); |
$retour_encode = json_encode($retour) ; |
$retour_encode = $this->nettoyerCaracteresNuls($retour_encode); |
header("content-type: application/json"); |
print $retour_encode ; |
exit() ; |
} |
private function nettoyerCaracteresNuls($chaine) { |
return str_replace('\u0000','',$chaine); |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/CelSyndicationImage.php |
---|
New file |
0,0 → 1,710 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* Service fournissant des informations concernant les images du CEL au format RSS1, RSS2 ou ATOM. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright 2010 |
*/ |
// TODO : résoudre le problème des images liées à plusieurs obs. Cela créé plusieurs item avec le même id pour atom... |
class CelSyndicationImage extends Cel { |
private $parametres_origines = null; |
private $format = null; |
private $service = null; |
private $squelette = null; |
private $squelette_dossier = null; |
private $auteurs = array(); |
private $flux = array(); |
private $format_image = 'XL'; |
private $criteres = array( |
'utilisateur' => 'c.courriel_utilisateur', |
'commune' => 'b.zone_geo', |
'dept' => 'b.ce_zone_geo', |
'taxon' => 'b.nom_ret', |
'num_taxon' => 'b.nt', |
'commentaire' => 'c.commentaire', |
'date' => 'c.date_prise_de_vue', |
'tag' => 'tag', |
'motcle' => 'tag', |
'projet' => 'projet'); |
/** |
* Méthode appelée avec une requête de type GET. |
*/ |
public function getElement($params = array()) { |
// Initialisation des variables |
$this->parametres_origines = $params; |
$info = array(); |
$contenu = ''; |
if (! $this->etreFluxAdmin() || $this->authentifierAdmin()) { |
// Pré traitement des paramêtres |
$pour_bdd = false; |
$p = $this->traiterParametres(array('service', 'format'), $params, $pour_bdd); |
extract($p); |
$this->parametres = $params; |
$this->squelette_dossier = dirname(__FILE__).DIRECTORY_SEPARATOR.'squelettes'.DIRECTORY_SEPARATOR; |
// Récupération de la liste des flux |
$this->chargerListeDesFlux(); |
// Chargement du bon type de service demandé |
if (isset($service)) { |
$this->service = $this->traiterNomService($service); |
$methode = $this->getNomMethodeService(); |
if (method_exists($this, $methode)) { |
if (isset($format) && preg_match('/^(?:rss1|rss2|atom)$/i', $format)) { |
// Mise en minuscule de l'indication du format |
$this->format = strtolower($format); |
// Définition du fichier squelette demandé |
$this->squelette = $this->squelette_dossier.$this->format.'.tpl.xml'; |
} else if (isset($this->flux[$this->service])) { |
$this->format = ''; |
$this->messages[] = "Le service CEL Syndication nécessite d'indiquer en second paramètre le format : rss1, rss2 ou atom."; |
} |
if (!isset($this->flux[$this->service]) || isset($this->format)) { |
// Suppression des deux premiers paramètres (service et format) pour le reste des méthodes |
array_shift($this->parametres); |
array_shift($this->parametres); |
// Récupération du contenu à renvoyer |
$contenu = $this->$methode(); |
} |
} else { |
$this->messages[] = "Le type d'information demandé '$this->service' n'est pas disponible."; |
} |
} else { |
$this->messages[] = "Le service CEL Syndication Image nécessite d'indiquer en premier paramètre le type d'information demandé."; |
} |
} |
// Envoie sur la sortie standard |
$encodage = 'utf-8'; |
$mime = $this->getTypeMime(); |
$formatage_json = $this->getFormatageJson(); |
$this->envoyer($contenu, $mime, $encodage, $formatage_json); |
} |
private function chargerListeDesFlux() { |
$this->setFlux('simple', 'Nouvelles images liées à une observation dans le CEL', |
"Ce flux fournit l'url des nouvelles images du CEL liées à une observation."); |
$this->setFlux('complet', 'Nouvelles images liées à une observation dans le CEL (détails)', |
"Ce flux fournit les informations sur les nouvelles images du CEL liées à une observation."); |
$this->setFlux('par-mots-cles', 'Flux de syndication obsolète', |
"Ce flux est désormais accessible via le flux multicriteres/atom/M?tag='mot-cle'."); |
$this->setFlux('par-commune','Flux de syndication obsolète', |
"Ce flux est désormais accessible via le flux multicriteres/atom/M?commune='commune'."); |
$this->setFlux('multicriteres','Flux de syndication des nouvelles images liées à une observation publique du CEL '. |
'filtrées par un ou plusieurs critères', |
"Ce flux fournit des informations sur les nouvelles images liées à une observation du CEL filtrées par ". |
"auteur (mail), commune (nom), departement (code postal), taxon (nom scientifique), commentaire, tag ". |
"et/ou date."); |
} |
private function setFlux($nom, $titre, $description) { |
$url_base = $this->config['settings']['baseURLAbsoluDyn'].'CelSyndicationImage/'; |
$formats = array('atom', 'rss2', 'rss1'); |
$flux = array(); |
foreach ($formats as $format) { |
$url = $url_base.$nom.'/'.$format; |
$flux[$format] = $url; |
} |
$this->flux[$nom] = array('titre' => $titre, 'description' => $description, 'urls' => $flux); |
} |
private function getFlux($nom) { |
return isset($this->flux[$nom]) ? $this->flux[$nom] : array(); |
} |
private function traiterNomService($nom) { |
$nom = strtolower($nom); |
return $nom; |
} |
private function getNomMethodeService() { |
$methode = ''; |
$service_formate = str_replace(' ', '', ucwords(implode(' ', explode('-', $this->service)))); |
$methode = 'getService'.$service_formate; |
return $methode; |
} |
private function getUrlBase() { |
$url_base = sprintf($this->config['settings']['baseURLAbsolu'], get_class($this).'/'); |
return $url_base; |
} |
private function getUrlServiceBase() { |
$url_service = $this->getUrlBase().implode('/', $this->parametres_origines); |
return $url_service; |
} |
private function getTypeMime() { |
$mime = ''; |
switch ($this->format) { |
case 'atom' : |
$mime = 'application/atom+xml'; |
break; |
case 'rss1' : |
case 'rss2' : |
$mime = 'application/rss+xml'; |
break; |
case 'opml' : |
$mime = 'text/x-opml'; |
break; |
default: |
$mime = 'text/html'; |
} |
return $mime; |
} |
private function getFormatageJson() { |
$json = false; |
switch ($this->service) { |
case 'liste-des-flux' : |
$json = true; |
break; |
default: |
$json = false; |
} |
return $json; |
} |
private function creerCategorie($element) { |
$categorie = ''; |
$categorie = 'Image'; |
$categorie = $this->nettoyerTexte($categorie); |
return $categorie; |
} |
private function etreFluxAdmin() { |
return (isset($_GET['admin']) && $_GET['admin'] == '1') ? true : false; |
} |
private function creerUrlService() { |
$url_service = $this->getUrlServiceBase(); |
if (count($_GET) > 0) { |
$parametres_get = array(); |
foreach ($_GET as $cle => $valeur) { |
$parametres_get[] = $cle.'='.$valeur; |
} |
$url_service .= '?'.implode('&', $parametres_get); |
} |
return $url_service; |
} |
protected function executerRequete($requete, $retour = 'All', $mode = PDO::FETCH_ASSOC) { |
$infos = null; |
try { |
$infos = $this->bdd->query($requete)->fetchAll(PDO::FETCH_ASSOC); |
if ($infos === false) { |
$this->messages[] = "La requête suivante a retourné aucun résultat :\n$requete"; |
} |
} catch (PDOException $e) { |
$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage()); |
} |
return $infos; |
} |
private function executerService($elements) { |
// Prétraitement des données |
$donnees = $this->construireDonneesCommunesAuFlux($elements); |
foreach ($elements as $element) { |
$identifiants[$element['courriel_utilisateur']] = $element['courriel_utilisateur']; |
} |
$this->auteurs = $this->creerAuteurs($identifiants); |
foreach ($elements as $element) { |
$donnees['items'][] = $this->construireDonneesCommunesAuxItems($element); |
} |
// Création du contenu à partir d'un template PHP |
$contenu = Cel::traiterSquelettePhp($this->squelette, $donnees); |
return $contenu; |
} |
private function construireDonneesCommunesAuFlux($infos) { |
$donnees = $this->getFlux($this->service); |
$donnees['guid'] = $this->getUrlServiceBase(); |
$donnees['lien_service'] = $this->creerUrlService(); |
$donnees['lien_cel'] = (isset($infos['nom_sel_nn']) && $infos['nom_sel_nn'] != '' && $infos['nom_sel_nn'] != 0) ? |
sprintf($this->config['settings']['efloreUrlTpl'], $infos['nom_sel_nn'], 'illustration') : ''; |
$donnees['editeur'] = $this->config['settings']['editeur']; |
$derniere_info_en_date = reset($infos); |
$date_modification_timestamp = strtotime($derniere_info_en_date['date_creation']); |
$donnees['date_maj_RSS'] = date(DATE_RSS, $date_modification_timestamp); |
$donnees['date_maj_ATOM'] = date(DATE_ATOM, $date_modification_timestamp); |
$donnees['date_maj_W3C'] = date(DATE_W3C, $date_modification_timestamp); |
$donnees['annee_courante'] = date('Y'); |
$donnees['generateur'] = 'CEL - Jrest - CelSyndicationImage'; |
$donnees['generateur_version'] = (preg_match('/([0-9]+)/', '$Revision$', $match)) ? $match[1] : '0'; |
return $donnees; |
} |
private function construireDonneesCommunesAuxItems($info) { |
$item = array(); |
$date_modification_timestamp = $this->convertirDateHeureMysqlEnTimestamp($info['date_creation']); |
$item['date_maj_simple'] = strftime('%A %d %B %Y à %H:%M', $date_modification_timestamp); |
$item['date_maj_RSS'] = date(DATE_RSS, $date_modification_timestamp); |
$item['date_maj_ATOM'] = date(DATE_ATOM, $date_modification_timestamp); |
$item['date_maj_W3C'] = date(DATE_W3C, $date_modification_timestamp); |
$item['titre'] = $this->creerTitre($info); |
$item['guid'] = $this->creerGuidItem($info); |
$item['lien'] = $this->creerLienItem($info); |
$item['categorie'] = $this->creerCategorie($item); |
$item['description'] = $this->creerDescription($this->protegerCaracteresHtmlDansChamps($info), $item); |
$item['description_encodee'] = htmlspecialchars($this->creerDescription($info, $item)); |
$item['modifier_par'] = $this->getIntituleAuteur($info['courriel_utilisateur']); |
return $item; |
} |
private function creerGuidItem($element) { |
$guid = $this->getUrlImage($element['id_image']); |
return $guid; |
} |
private function creerTitre($element) { |
$methode = 'creerTitre'.$this->service; |
$methode = (method_exists($this, $methode)) ? $methode : 'creerTitreSimple'; |
$titre = $this->$methode($element); |
$titre = $this->nettoyerTexte($titre); |
return $titre; |
} |
private function creerDescription($donnees, $item) { |
$methode = 'creerDescription'.$this->service; |
$methode = (method_exists($this, $methode)) ? $methode : 'creerDescriptionComplet'; |
$description = $this->$methode($donnees, $item); |
$description = $this->nettoyerTexte($description); |
return $description; |
} |
private function creerLienItem($element) { |
if ($this->etreNull($element['id_observation'])) { |
// Lien vers image grand format |
$lien = $this->getUrlImage($element['id_image'], $this->format_image); |
} else { |
// Lien vers fiche eFlore onglet Illustration |
$lien = sprintf($this->config['settings']['efloreUrlTpl'], $element['nom_sel_nn'], 'illustration'); |
} |
return $lien; |
} |
private function getServiceListeDesFlux() { |
return $this->flux; |
} |
private function getServiceOpml() { |
$donnees = array(); |
$id = 1; |
foreach ($this->flux as $flux_nom => $flux){ |
$info = array(); |
$info['type'] = 'atom'; |
$info['titre'] = $flux['titre']; |
$info['texte'] = "CEL - Images - $flux_nom"; |
$info['description'] = $flux['description']; |
$info['url_xml'] = $this->getUrlBase().$flux_nom.'/atom'; |
$info['url_html'] = $this->config['settings']['aideCelUrl'].'FluxSyndication'; |
$donnees['liste_flux'][] = $info; |
} |
$this->squelette = $this->squelette_dossier.'opml.tpl.xml'; |
$contenu = Cel::traiterSquelettePhp($this->squelette, $donnees); |
return $contenu; |
} |
private function getServiceSimple() { |
if (isset($this->parametres[0])) { |
$this->format_image = $this->parametres[0]; |
} |
// Construction de la requête |
$requete = (isset($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' ci.*, '. |
' cim.id_image, cim.ce_utilisateur, nom_original, cim.date_creation, cim.mots_cles_texte as mots_cles_texte_images, |
ci.mots_cles_texte as mots_cles_texte_images_obs, cim.commentaire, note_qualite '. |
'FROM cel_obs_images AS coi '. |
'LEFT JOIN cel_obs AS ci '. |
'ON (coi.id_observation = ci.id_observation) '. |
'LEFT JOIN cel_images AS cim '. |
'ON (coi.id_image = cim.id_image) '. |
'WHERE ci.transmission = 1 '. |
' AND ci.ce_utilisateur = cim.ce_utilisateur '. |
'ORDER BY '.(isset($this->orderby) && (!is_null($this->orderby)) ? $this->orderby : 'cim.date_creation DESC').' '. |
"LIMIT $this->start, $this->limit "; |
$elements = $this->executerRequete($requete); |
// Création du contenu |
$contenu = $this->executerService($elements); |
return $contenu; |
} |
private function creerTitreSimple($element) { |
$date = $element['date_observation']; |
$date = date("d/m/Y", strtotime($date)); |
if ($this->etreNull($element['nom_sel']) && $this->etreNull($element['nom_sel_nn'])) { |
$titre = "Ajout d'une photo par ".$this->getIntituleAuteur($element['courriel_utilisateur']).' le '.$date;; |
} else { |
$titre = $element['nom_sel'].' [nn'.$element['nom_sel_nn'].'] par '.$this->getIntituleAuteur($element['courriel_utilisateur']).' le '.$date;; |
} |
return $titre; |
} |
private function creerDescriptionSimple($donnees, $item) { |
$description = sprintf($this->config['settings']['efloreUrlTpl'], urlencode($donnees['nom_sel_nn']), 'illustration'); |
return $description; |
} |
private function getServiceComplet() { |
// Construction de la requête |
$requete = (isset($this->distinct) ? 'SELECT DISTINCT' : 'SELECT').' ci.*, '. |
' cim.id_image, ci.ce_utilisateur, nom_original, cim.date_creation, cim.mots_cles_texte as mots_cles_texte_images, '. |
' ci.mots_cles_texte as mots_cles_texte_obs, cim.commentaire as commentaire_img, note_qualite, '. |
' ci.commentaire as commentaire_obs '. |
'FROM cel_images AS cim '. |
' LEFT JOIN cel_obs_images AS coi '. |
' ON (coi.id_image = cim.id_image) '. |
' LEFT JOIN cel_obs AS ci '. |
' ON (coi.id_observation = ci.id_observation) '. |
(($this->etreFluxAdmin()) ? '' : 'WHERE ci.transmission = 1 '). |
'ORDER BY '.(isset($this->orderby) && (!is_null($this->orderby)) ? $this->orderby : 'cim.date_creation DESC').' '. |
"LIMIT $this->start, $this->limit "; |
//echo $requete; |
$elements = $this->executerRequete($requete); |
// Création du contenu |
if ($elements != false && count($elements) > 0) { |
$contenu = $this->executerService($elements); |
} else { |
$this->messages[] = "Aucune image disponible."; |
$contenu = array(); |
} |
return $contenu; |
} |
private function getServiceMultiCriteres() { |
$contenu = ''; |
if (isset($_GET['debut'])) $this->start = $_GET['debut']; |
if (isset($_GET['limite'])) $this->limite = $_GET['limite']; |
if ($this->parametresSontDemandes()) { |
$requete = $this->creerRequeteAvecParametres(); |
} else { |
$requete = $this->creerRequeteSansParametres(); |
} |
$elements = $this->executerRequete($requete); |
// Création du contenu |
if ($elements != false && count($elements) > 0) { |
$contenu = $this->executerService($elements); |
} else { |
$this->messages[] = "Aucune image disponible."; |
} |
return $contenu; |
} |
private function parametresSontDemandes() { |
$criteres = $this->traiterCriteresMultiples($_GET) ; |
return (isset($_GET['recherche']) && $_GET['recherche'] != '') || !empty($criteres); |
} |
private function creerRequeteSansParametres() { |
// Première sous requete pour que le limite se fasse d'abord sur les images |
// et pas la jointure de toutes les tables |
$sous_requete = 'SELECT * '. |
'FROM cel_images c '. |
'WHERE id_image '. |
' IN (SELECT id_image FROM cel_obs_images a '. |
(($this->etreFluxAdmin()) ? '' : 'INNER JOIN cel_obs b ON b.id_observation = a.id_observation AND b.transmission = 1 '). |
') '; |
$sous_requete .= ' ORDER BY '.(isset($this->orderby) && (!is_null($this->orderby)) ? $this->orderby : 'c.date_creation DESC').' '. |
"LIMIT $this->start,$this->limit "; |
// Construction de la requête |
$requete = 'SELECT *, b.mots_cles_texte as mots_cles_texte_obs, c.mots_cles_texte as mots_cles_texte_images, '. |
' b.commentaire as commentaire_obs, c.commentaire as commentaire_img '. |
'FROM ('.$sous_requete.') as c '. |
' INNER JOIN cel_obs_images AS a '. |
' ON (a.id_image = c.id_image) '. |
' INNER JOIN cel_obs AS b '. |
' ON (a.id_observation = b.id_observation) AND b.ce_utilisateur = c.ce_utilisateur '; |
//echo $requete; |
return $requete; |
} |
private function creerRequeteAvecParametres() { |
// Construction de la requête |
$requete = 'SELECT *, b.mots_cles_texte as mots_cles_texte_obs, c.mots_cles_texte as mots_cles_texte_images, '. |
' b.commentaire as commentaire_obs, c.commentaire as commentaire_img '. |
'FROM cel_obs_images AS a '. |
' INNER JOIN cel_obs AS b '. |
' ON (a.id_observation = b.id_observation) '. |
' INNER JOIN cel_images AS c '. |
' ON (a.id_image = c.id_image) '. |
'WHERE b.ce_utilisateur = c.ce_utilisateur '. |
(($this->etreFluxAdmin()) ? '' : 'AND b.transmission = 1 '). |
' AND '; |
if ($this->estUneRechercheGenerale()) { |
$chaine_requete = $_GET['recherche']; |
$requete .= $this->creerSousRequeteRechercheGenerale($chaine_requete); |
} else { |
$criteres = $this->traiterCriteresMultiples($_GET) ; |
if (!empty($criteres)) { |
$requete .= $this->creerSousRequeteRechercheParCriteres($criteres); |
} |
} |
$requete = str_replace(' AND ) ',' ', $requete); |
$requete = rtrim($requete, 'AND '); |
$requete .= ' ORDER BY '.(isset($this->orderby) && (!is_null($this->orderby)) ? $this->orderby : |
'c.date_creation DESC').' '."LIMIT $this->start,$this->limit "; |
//echo $requete; |
return $requete; |
} |
private function creerSousRequeteRechercheParCriteres($criteres) { |
$requete = ''; |
foreach ($criteres as $pair) { |
$nom_valeur = explode("=",$pair); |
if (sizeof($nom_valeur) != 0) { |
switch ($nom_valeur[0]) { |
case "ci_limite" : $this->limite = $this->bdd->quote($nom_valeur[1]); break; |
case "c.ci_numero_page" : $this->limite*$this->bdd->quote($nom_valeur[1]); break; |
case "c.commentaire" : $mots_comment_liste = explode(" " , $nom_valeur[1]); |
foreach($mots_comment_liste as $mot_comment) { |
$mot_comment = trim($mot_comment) ; |
$requete .= $nom_valeur[0].' LIKE '.$this->bdd->quote('%'.$mot_comment.'%').' AND '; |
} |
break; |
case "c.date_prise_de_vue" : |
$nom_valeur[1] = str_replace('/', '-', $nom_valeur[1]); |
if (preg_match('/(^[0-9]{2})-([0-9]{2})-([0-9]{4}$)/', $nom_valeur[1], $matches)) { |
$nom_valeur[1] = $matches[3].'-'.$matches[2].'-'.$matches[1]; |
} |
$requete .= $nom_valeur[0].' LIKE '.$this->bdd->quote($nom_valeur[1]."%").' AND '; break; |
case "b.ce_zone_geo" : |
$requete .= ' ('.$nom_valeur[0].' LIKE "%INSEE-C:'.$nom_valeur[1].'%") AND '; break; |
case "b.nom_ret" : |
if ($nom_valeur[1] == "indetermine") $nom_valeur[1] = 'null'; |
$requete .= ' ('.$nom_valeur[0].' LIKE "%'.$nom_valeur[1].'%" OR b.nom_sel LIKE "%'. |
$nom_valeur[1].'%") AND '; break; |
case "tag" : $requete .= $this->creerSousRequeteMotsCles($nom_valeur[1]).' AND '; break; |
case "projet" : $requete .= $this->creerSousRequeteProjet($nom_valeur[1]).' AND '; break; |
default : $requete .= $nom_valeur[0].' = "'.$nom_valeur[1].'" AND '; break; |
} |
} |
} |
$requete = rtrim($requete,' AND '); |
return $requete; |
} |
private function creerSousRequeteMotsCles($mot_cle) { |
$requete = ''; |
if (preg_match('/.*OU.*/', $mot_cle)) { |
$mots_cles_tab = explode('OU',$mot_cle); |
foreach($mots_cles_tab as $mot_cle_item) { |
$requete .= '(c.mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') OR '; |
} |
$requete = '('.rtrim($requete,'OR ').')'; |
} else if (preg_match('/.*ET.*/', $mot_cle)) { |
$mots_cles_tab = explode('ET',$mot_cle); |
foreach($mots_cles_tab as $mot_cle_item) { |
$requete .= '(c.mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') AND '; |
} |
$requete = '('.rtrim($requete, 'AND ').') '; |
} else { |
$requete = "(c.mots_cles_texte LIKE ".$this->proteger('%'.$mot_cle.'%').') '; |
} |
return $requete; |
} |
private function creerSousRequeteProjet($mot_cle) { |
$requete = ''; |
if (preg_match('/.*OU.*/', $mot_cle)) { |
$mots_cles_tab = explode('OU',$mot_cle); |
foreach($mots_cles_tab as $mot_cle_item) { |
$requete .= '(b.mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') OR '; |
} |
$requete = '('.rtrim($requete,'OR ').')'; |
} else if (preg_match('/.*ET.*/', $mot_cle)) { |
$mots_cles_tab = explode('ET',$mot_cle); |
foreach($mots_cles_tab as $mot_cle_item) { |
$requete .= '(b.mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') AND '; |
} |
$requete = '('.rtrim($requete, 'AND ').') '; |
} else { |
$requete = "(b.mots_cles_texte LIKE ".$this->proteger('%'.$mot_cle.'%').') '; |
} |
return $requete; |
} |
private function creerSousRequeteRechercheGenerale($chaine_requete) { |
$requete = ''; |
if (trim($chaine_requete) != '') { |
$chaine_requete = strtolower($chaine_requete); |
$chaine_requete = str_replace(' ', '_', $chaine_requete); |
$requete = ' ('. |
'b.nom_ret LIKE "'.$chaine_requete.'%"'. |
' OR '. |
'b.nom_sel LIKE "'.$chaine_requete.'%"'. |
' OR '. |
'b.zone_geo LIKE "'.$chaine_requete.'%" '. |
' OR '. |
'b.ce_zone_geo LIKE "INSEE-C:'.$chaine_requete.'%" '. |
' OR '. |
'b.ce_zone_geo LIKE "'.$chaine_requete.'%" '. |
' OR '. |
'c.ce_utilisateur LIKE "'.$chaine_requete.'%" '. |
' OR '. |
'c.courriel_utilisateur LIKE "'.$chaine_requete.'%" '. |
' OR '. |
'b.mots_cles_texte LIKE "'.$chaine_requete.'%" '. |
' OR '. |
'c.mots_cles_texte LIKE "'.$chaine_requete.'%" '. |
') '; |
} |
return $requete; |
} |
private function estUneRechercheGenerale() { |
return isset($_GET['recherche']); |
} |
private function traiterCriteresMultiples($tableau_criteres) { |
$tableau_criteres_pour_bdd = array(); |
foreach($tableau_criteres as $nom_critere => $valeur_critere) { |
if (isset($this->criteres[$nom_critere])) { |
$tableau_criteres_pour_bdd[] = $this->criteres[$nom_critere].'='.$valeur_critere; |
} |
} |
return $tableau_criteres_pour_bdd; |
} |
private function creerDescriptionComplet($donnees, $item) { |
$auteur = $this->getIntituleAuteur($donnees['courriel_utilisateur']); |
$auteur_mail = $donnees['courriel_utilisateur']; |
$id_img = $donnees['id_image']; |
$nom_fichier = $donnees['nom_original']; |
$url_img = $this->getUrlImage($donnees['id_image'], 'CS'); |
$url_img_normale = $this->getUrlImage($donnees['id_image'], 'XL'); |
// |
$mots_cles_image = $donnees['mots_cles_texte_images']; |
$note = ($donnees['note_qualite'] +1).'/5'; |
$commentaire_img = $donnees['commentaire_img']; |
$id_obs = $donnees['id_observation']; |
$famille = $donnees['famille']; |
$nom_saisi = $donnees['nom_sel']; |
$nom_retenu = $donnees['nom_ret']; |
// |
$mots_cles_obs = $donnees['mots_cles_texte_obs']; |
$lieu = $donnees['zone_geo'].' ('.$this->convertirCodeZoneGeoVersCodeInsee($donnees['ce_zone_geo']).') > '.$donnees['lieudit'].' > '.$donnees['station']; |
$milieu = $donnees['milieu']; |
$coordonnees = ($this->etreNull($donnees['latitude']) && $this->etreNull($donnees['longitude'])) ? '' : $donnees['latitude'].'/'.$donnees['longitude']; |
$commentaire_obs = $donnees['commentaire_obs']; |
$date_observation = $this->formaterDate($donnees['date_observation'], '%A %d %B %Y'); |
$date_transmission = $this->formaterDate($donnees['date_transmission']); |
$date_modification = $this->formaterDate($donnees['date_modification']); |
$date_creation = $this->formaterDate($donnees['date_creation']); |
$transmission = $donnees['transmission'] == 1 ? "oui ($date_transmission)" : 'non'; |
$description = '<style>.champ{color:grey} .gauche{float:left;padding:0 20px 0 0;} ul{list-style-type:none;padding:0;}</style>'. |
'<h2>'.(!$this->etreNull($id_obs) ? "Image #$id_img liée à l'observation #$id_obs" : "Image #$id_img non liée à une observation.").'</h2>'. |
'<a href="'.$url_img_normale.'"><img class="gauche" src="'.$url_img.'" alt="'.$nom_fichier.'" /></a>'. |
'<div class="gauche">'. |
'<h3>'.'Image'.'</h3>'. |
'<ul>'. |
'<li>'.'<span class="champ">URL :</span> <a href="'.$url_img_normale.'" onclick="javascript:window.open(this.href);return false;">'.$url_img_normale.'</a></li>'. |
'<li>'.'<span class="champ">Importée le :</span> '.$item['date_maj_simple'].'</li>'. |
'<li>'.'<span class="champ">Par :</span> '. |
(($this->etreFluxAdmin()) ? '<a href="mailto:'.$auteur_mail.'">'.$auteur.'</a>' : $auteur). |
'</li>'. |
'<li>'.'<span class="champ">Nom du fichier :</span> '.$nom_fichier.'</li>'. |
'<li>'.'<span class="champ">Note qualité :</span> '.$note.'</li>'. |
'<li>'.'<span class="champ">Commentaires :</span> '.$commentaire_img.'</li>'. |
'<li>'.'<span class="champ">Mots-clés :</span> '.$mots_cles_image.'</li>'. |
'</ul>'. |
'</div>'; |
// TODO : ajouter le champ commentaire EXIF. |
if (! $this->etreNull($id_obs)) { |
$description .= |
'<div class="gauche">'. |
'<h3>'.'Observation'.'</h3>'. |
'<ul>'. |
'<li>'.'<span class="champ">Famille :</span> '.$famille.'</li>'. |
'<li>'.'<span class="champ">Nom saisi :</span> '.$nom_saisi.'</li>'. |
'<li>'.'<span class="champ">Nom retenu :</span> '.$nom_retenu.'</li>'. |
'<li>'.'<span class="champ">Observée le :</span> '.$date_observation.'</li>'. |
'<li>'.'<span class="champ">Lieu :</span> '.$lieu.'</li>'. |
'<li>'.'<span class="champ">Milieu :</span> '.$milieu.'</li>'. |
(($this->etreFluxAdmin()) ? '<li><span class="champ">Coordonnées (Lat/Long) :</span> '.$coordonnees.'</li>' : ''). |
'<li>'.'<span class="champ">Commentaire :</span> '.$commentaire_obs.'</li>'. |
'<li>'.'<span class="champ">Mots-clés :</span> '.$mots_cles_obs.'</li>'. |
(($this->etreFluxAdmin()) ? '<li><span class="champ">Transmis (= public) :</span> '.$transmission.'</li>' : ''). |
'<li><span class="champ">Modifiée le :</span> '.$date_modification.'</li>'. |
'<li><span class="champ">Créée le :</span> '.$date_creation.'</li>'. |
'</ul>'. |
'</div>'; |
} |
$description = $this->nettoyerTexte($description); |
return $description; |
} |
private function getServiceParMotsCles() { |
$infos=array(); |
$infos[0]['nom_sel_nn'] = ''; |
$infos[0]['date_creation'] = '2011-06-28'; |
$donnees = $this->construireDonneesCommunesAuFlux($infos); |
$donnees['items'][0]['guid'] = 0; |
$donnees['items'][0]['description'] = 'Ce flux est devenu obsolète. Veuillez utiliser le flux '. |
'<b>http://www.tela-botanica.org/eflore/cel2/jrest/CelSyndicationImage/multicriteres/atom?tag='; |
if (isset($this->parametres[0])) { |
$donnees['items'][0]['description'] .= $this->parametres[0].'</b>'; |
} else { |
$donnees['items'][0]['description'] .= '</b>'; |
} |
$donnees['items'][0]['titre'] = ''; |
$contenu = Cel::traiterSquelettePhp($this->squelette, $donnees); |
return $contenu; |
} |
private function getServiceParCommune() { |
$infos=array(); |
$infos[0]['nom_sel_nn'] = ''; |
$infos[0]['date_creation'] = '2011-06-28'; |
$donnees = $this->construireDonneesCommunesAuFlux($infos); |
$donnees['items'][0]['guid'] = 0; |
$donnees['items'][0]['description'] = 'Ce flux est devenu obsolète. Veuillez utiliser le flux '. |
'<b>http://www.tela-botanica.org/eflore/cel2/jrest/CelSyndicationImage/multicriteres/atom?commune='; |
if (isset($this->parametres[0])) { |
$donnees['items'][0]['description'] .= $this->parametres[0].'</b>'; |
} else { |
$donnees['items'][0]['description'] .= '</b>'; |
} |
$donnees['items'][0]['titre'] = ''; |
$contenu = Cel::traiterSquelettePhp($this->squelette, $donnees); |
return $contenu; |
} |
private function getIntituleAuteur($courriel) { |
$courriel = strtolower($courriel); |
$intitule = $this->auteurs[$courriel]; |
return $intitule; |
} |
} |
/branches/v1.6-croc/jrest/services/ImageDateList.php |
---|
New file |
0,0 → 1,98 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package papyrus_bp |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/papyrus_bp/ |
*/ |
/** |
* Liste les date des images par utilisateur |
* |
* in=utf8 |
* out=utf8 |
* |
* uid[0] : utilisateur obligatoire |
* uid[1] : si absent : valeur 'all' (annee) |
* uid[2] : si absent : valeur 'all' (mois) |
* uid[3] : si absent : valeur 'all' (jour) |
**/ |
class ImageDateList extends Cel { |
private $correspondance_fonction = array(1 => 'year', 2 => 'month', 3 => 'day'); |
function getElement($uid){ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if(!is_numeric($uid[0])) { |
return; |
} |
$condition_requete = $this->traiterParametresEtConstruireRequete($uid); |
$requete_liste_dates = 'SELECT DISTINCT '. |
'date_prise_de_vue AS id '. |
'FROM cel_images WHERE '.$condition_requete.' '. |
'ORDER BY date_prise_de_vue'; |
$liste_dates = $this->executerRequete($requete_liste_dates); |
$liste_dates = $this->formaterListeResultats($liste_dates); |
$this->envoyerJson($liste_dates); |
return true; |
} |
private function formaterListeResultats($liste_dates) { |
if (!$liste_dates) { |
$liste_dates = array(); |
} |
foreach($liste_dates as &$date) { |
if($date['id'] == null || trim($date['id']) == '' || $date['id'] == 'null') { |
$date = '0000-00-00'; |
} else { |
$date_heures = explode(' ',$date['id']); |
if(count($date_heures) > 1) { |
$date = $date_heures[0]; |
} else { |
$date = $date['id']; |
} |
} |
} |
return $liste_dates; |
} |
private function traiterParametresEtConstruireRequete($params) { |
$requete_condition = ' ce_utilisateur = '.$this->proteger($params[0]); |
$taille_tableau_parametres = count($params); |
for($i=1; $i < $taille_tableau_parametres; $i++) { |
if($this->estUnParametreDate($params[$i])) { |
$fonction_date = $this->correspondance_fonction[$i]; |
$requete_condition .= ' AND '.$fonction_date.'(date_prise_de_vue) = '.$this->proteger($params[$i]); |
} |
} |
return $requete_condition; |
} |
private function estUnParametreDate($valeur) { |
return is_numeric($valeur) && $valeur != "all"; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryImageLink.php |
---|
New file |
0,0 → 1,165 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* InventoryImageLink.php |
* |
* in : utf8 |
* out : utf8 |
* |
* Cas d'utilisation : |
* Service de liaisons d'images à des observations |
* |
* 2: Le service lie une ou plusieurs images à une ou plusieurs observations |
* 3: Le service renvoie les observations liées à une image |
*/ |
class InventoryImageLink extends Cel { |
function createElement($pairs) |
{ |
// Controle detournement utilisateur |
$this->controleUtilisateur($pairs['ce_utilisateur']); |
$ids_images = $pairs['id_image'] ; |
$ids_images = rtrim($ids_images,',') ; |
$ids_images_liste = explode(",",$ids_images) ; |
$utilisateur = $pairs['ce_utilisateur'] ; |
$ids_observations = $pairs['id_observation'] ; |
$ids_observations = rtrim($ids_observations,',') ; |
$ids_observations_liste = explode(",",$ids_observations) ; |
$retour = false; |
foreach($ids_images_liste as $image) |
{ |
foreach($ids_observations_liste as $observation) |
{ |
$requete_creation_lien = 'INSERT INTO cel_obs_images (id_image, id_observation, date_liaison) '. |
'VALUES '. |
'('.$this->proteger($image).','.$this->proteger($observation).', NOW()) '. |
'ON DUPLICATE KEY UPDATE id_image = id_image' ; |
$resultat_creation_lien = $this->executer($requete_creation_lien); |
if ($resultat_creation_lien) { |
$retour = "OK"; |
} |
} |
} |
echo $retour ; |
exit ; |
} |
/** |
* renvoie les numeros des images liées à une observation ou l'inverse, suivant le paramètre |
* uid[0] : utilisateur obligatoire |
* uid[1] : ordre_observation=valeur ou bien id_image=valeur |
* |
*/ |
function getElement($uid) |
{ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
if($uid) { |
$param = $uid[1] ; |
//TODO utiliser le GET plutôt pour récuperer id image ou observation |
$tab_param = explode('=',$param) ; |
$field = $tab_param[0] ; |
$value = $tab_param[1] ; |
$requete_selection_liaison = "" ; |
if ($field == 'id_observation') |
{ |
$column = 'id_image' ; |
$requete_selection_liaison = 'SELECT id_image, hauteur , largeur '. |
'FROM cel_images '. |
'WHERE id_image IN ( '. |
'SELECT id_image '. |
'FROM cel_obs_images '. |
'WHERE id_observation = '.$this->proteger($value).' '. |
')'; |
} |
else |
{ |
$column = 'id_observation' ; |
$requete_selection_liaison = 'SELECT * from cel_obs WHERE id_observation IN (SELECT '.$column.' FROM cel_obs_images WHERE '.$field.' = '.$this->proteger($value).') ' ; |
} |
} |
$resultat_selection_liaison = $this->requeter($requete_selection_liaison); |
$liaisons = array(); |
if (is_array($resultat_selection_liaison) && count($resultat_selection_liaison) > 0) { |
$liaisons = $resultat_selection_liaison; |
if($field == 'id_image') { |
foreach($liaisons as &$liaison) { |
$liaison['ce_zone_geo'] = $this->convertirCodeZoneGeoVersCodeInsee($liaison['ce_zone_geo']); |
} |
} |
} |
$this->envoyerJson($liaisons); |
return true; |
} |
function updateElement($uid,$pairs) |
{ |
} |
/** |
* Supprimme une ou plusieurs liaisons entre images et observations |
* uid[0] : utilisateur obligatoire |
* uid[1] : identifiant(s) image(s) obligatoire(s) |
* uid[2] : identifiant(s) observations |
* |
*/ |
function deleteElement($uid) |
{ |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
$id_img = $uid[1] ; |
$id_obs = $this->proteger($uid[2]) ; |
$id = $uid[0] ; |
if (isset($id)) { |
$requete_suppression_lien = "DELETE FROM cel_obs_images ". |
"WHERE id_image IN (".$id_img.") ". |
"AND id_observation IN (".$id_obs.") " ; |
} |
$resultat_suppression_lien = $this->executer($requete_suppression_lien); |
$retour = false; |
if ($resultat_suppression_lien) { |
$retour = "OK"; |
} |
echo $retour; |
exit() ; |
} |
} |
?> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v1.6-croc/jrest/services/ImageRDF.php |
---|
New file |
0,0 → 1,115 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* Retourne un RDF des images pour eflore |
* |
* @category PHP |
* @package jrest |
* @author david <david@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
class ImageRDF extends Cel { |
/** |
* Recherche des images associee au numero nomenclatural |
* @param numeric $uid [0] : numero nomenclatural obligatoire , $uid[1] (optionnel) : taille image : S , M, L (default) |
*/ |
function getElement($uid){ |
// TODO : recherche taxon ? |
// Taille |
if (isset($uid[1])) { |
$taille = $uid[1]; // S , M ou L |
} |
else { |
$taille = 'L'; |
} |
// Recherche de toutes les observations transmises du taxon pour lesquelles une photo est associee. |
$requete_obs_publiques_images_taxon = 'SELECT * FROM cel_obs, cel_obs_images, cel_images '. |
' WHERE cel_obs.nom_sel_nn = '.$this->proteger($uid[0]). |
' AND cel_obs_images.id_observation = cel_obs.id_observation '. |
' AND cel_obs.transmission = 1 '. |
' AND cel_images.id_image = cel_obs_images.id_image'; |
$resultat_requete_obs_images_taxon = $this->requeter($requete_obs_publiques_images_taxon); |
$picture_path = $this->config['cel']['url_images']; |
// Formatage du xml |
$xml = '<?xml version="1.0" encoding="utf-8"?>'."\n"; |
$xml .= '<rdf:RDF'."\n"; |
$xml .= ' xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"'."\n"; |
$xml .= ' xmlns:dc="http://purl.org/dc/elements/1.1/"'."\n"; |
$xml .= ' xmlns:dcterms="http://purl.org/dc/terms">'."\n"; |
$images_obs_taxon = array(); |
if (is_array($resultat_requete_obs_images_taxon)) { |
$images_obs_taxon = $resultat_requete_obs_images_taxon; |
} |
foreach ($images_obs_taxon as $picture) { |
// Calcul du chemin sur le serveur en fonction de l'identifiant (id) |
$id = $picture['id_image']; |
$id = sprintf('%09s', $id) ; |
$id = wordwrap($id, 3 , '_', true) ; |
$id_fichier = $id.".jpg" ; |
$niveauDossier = explode("_", $id) ; |
$dossierNiveau1 = $niveauDossier[0] ; |
$dossierNiveau2 = $niveauDossier[1] ; |
$picture_path_with_level = $picture_path.'/'.$dossierNiveau1.'/'.$dossierNiveau2 ; |
// TODO: mettre nom prénom dans créateur ? ou mail ? |
$xml .= ' <rdf:Description about="'.$picture_path_with_level.'/'.$taille.'/'.$id.'_'.$taille.'.jpg'.'"'."\n"; |
$xml .= ' dc:identifier="'.'urn:lsid:tela-botanica.org:celpic:'.$picture['id_image'].'"'."\n"; |
$xml .= ' dc:title="'.$picture['nom_sel'].'"'."\n"; |
$xml .= ' dc:description="'.$picture['nom_sel']." - [fichier_origine:".$picture['nom_original'].'][image_identifiant:'.$picture['id_image'].']'; |
$xml .= '[image_ordre:'.$picture['ordre'].']'; |
$xml .= '[observation_identifiant:'.$picture['id_observation'].']'; |
$xml .= '[observation_ordre:'.$picture['ordre'].']'.'"'."\n"; |
$xml .= ' dc:creator="'.$picture['courriel_utilisateur'].'"'."\n"; |
$xml .= ' dc:publisher="CEL"'."\n"; |
$xml .= ' dcterms:spatial="'.utf8_decode($picture['zone_geo'])." (".$picture['ce_zone_geo'].")".'"'."\n"; |
if ($picture['date_observation'] != '0000-00-00 00:00:00') { |
list($year,$month,$day) = explode('-',$picture['date_observation']); |
list($day) = explode(' ',$day); |
$created = $day.'/'.$month.'/'.$year; |
$xml .= ' dcterms:created="'.$created.'"'."\n"; |
} |
$xml .= ' dcterms:licence="CC BY-SA"/>'."\n"; |
} |
$xml .= '</rdf:RDF>'."\n"; |
// Envoi du xml au navigateur |
header("Content-Type: text/xml"); |
echo utf8_encode(str_replace(' & ', ' & ', $xml)); |
} |
function envoyerRequete($url) { |
$contenu = false; |
$contexte = stream_context_create(array( |
'http' => array( |
'method' => 'GET', |
'header' => "Content-type: application/x-www-form-urlencoded\r\n"))); |
$flux = @fopen($url, 'r', false, $contexte); |
$contenu = json_decode(stream_get_contents($flux)); |
fclose($flux); |
return $contenu; |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/User.php |
---|
New file |
0,0 → 1,242 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <devid.delon@clapas.net> |
* @author Aurélien Peronnet <devid.delon@clapas.net> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* User.php |
* |
* Cas d'utilisation : |
* Service identification utilisateur |
* |
* |
* 1: Aucun identifiant ni mot de passe transmis |
* 1: L'application retourne l'identifiant de session en cours |
* 2: Une identification est toujours active, cette identification est retournee |
* |
* 1: L'application recoit un identifiant et un mot de passe |
* 1 : On tente login |
* 2 : Si reussi etat connecte, retour de l'identification obtenue |
* 3 : sinon pas connecte, retour d'infos utilisateur anonyme |
* |
* 1: L'application recoit un identifiant et pas de mot de passe : |
* 1 : Deconnection, retour d'infos utilisateur anonyme |
* |
* En resume : |
* /User/ : retour infos utilisateur si connecté sinon infos utilisateur anonyme |
* /User/login_utilisateur : logout retour infos utilisateur anonyme |
* /User/login_utilisateur/password : login retour infos utilisateur si succès sinon infos utilisateur anonyme |
* |
*/ |
class User extends Cel { |
// TODO : controle systematique ....dans tous les services |
// Si connected : name cookie = name service |
function getRessource(){ |
$temps_expiration = 60*60*24*100; // 100 jours |
session_set_cookie_params($temps_expiration); |
$utilisateur = $this->getUtilisateurAnonyme(); |
$login_utilisateur = $this->utilisateurEstIdentifie(); |
if ($login_utilisateur) { |
$utilisateur = $this->chargerInfosUtilisateur($login_utilisateur); |
$utilisateur['connecte'] = true; |
} |
$this->envoyerInfosUtilisateur($utilisateur); |
} |
function getElement($uid){ |
$utilisateur = $this->getUtilisateurAnonyme(); |
if ($this->identificationEstDemandee($uid)) { |
if (!$utilisateur = $this->utilisateurEstIdentifie()) { |
if ($this->identifierUtilisateur($uid[0],$uid[1],1)) { |
$utilisateur= $this->chargerInfosUtilisateur($uid[0]); |
$utilisateur['connecte'] = true; |
} |
} |
else { |
$utilisateur = $this->chargerInfosUtilisateur($utilisateur); |
$utilisateur['connecte'] = true; |
} |
} |
else { |
$this->deconnecterUtilisateur(); |
} |
$this->envoyerInfosUtilisateur($utilisateur); |
} |
public function obtenirUtilisateurSiExiste($login_utilisateur) { |
$utilisateur = $this->getUtilisateurAnonyme(); |
if($utilisateur_existe = $this->chargerInfosUtilisateur($login_utilisateur)) { |
$utilisateur = $utilisateur_existe; |
$utilisateur['connecte'] = true; |
} |
return $utilisateur; |
} |
private function identificationEstDemandee($tableau_param) { |
return (isset($tableau_param[1]) && trim($tableau_param[1] != '')); |
} |
private function envoyerInfosUtilisateur($utilisateur) { |
$utilisateur['connecte'] = ($utilisateur['connecte']) ? true : false; |
$utilisateur['licence_acceptee'] = ($utilisateur['licence_acceptee']) ? true : false; |
$utilisateur['admin'] = ($utilisateur['admin']) ? true : false; |
$this->envoyerJson($utilisateur); |
return true; |
} |
function chargerInfosUtilisateur($login) { |
$requete_selection_utilisateur = 'SELECT * FROM cel_utilisateurs cu '. |
'WHERE courriel = '.$this->proteger($login); |
$resultat_selection_utilisateur = $this->requeter($requete_selection_utilisateur); |
$retour = false; |
if(is_array($resultat_selection_utilisateur) && count($resultat_selection_utilisateur) > 0) { |
$retour = $resultat_selection_utilisateur[0]; |
} |
if(is_array($retour) && ($retour['date_premiere_utilisation'] == NULL || $retour['date_premiere_utilisation'] == '0000-00-00 00:00:00')) { |
$this->initialiserInfosUtilisateur($retour['id_utilisateur']); |
$this->affecterDonneesWidgetSaisie($login, $retour); |
} |
return $retour; |
} |
private function utilisateurEstIdentifie() { |
$login_utilisateur = false; |
if (!$login_utilisateur = $this->utilisateurEstIdentifieSession()) {$login_utilisateur = $this->utilisateurEstIdentifieCookie();} |
return $login_utilisateur; |
} |
function utilisateurEstIdentifieSession() { |
return (isset($_SESSION["user"]) && isset($_SESSION["user"]["courriel"])) ? $_SESSION["user"]["courriel"] : false; |
} |
function utilisateurEstIdentifieCookie() { |
return isset($_COOKIE["cel_name"]) && ($this->identifierUtilisateurSansEncryptionMotDePasse($_COOKIE["cel_name"], $_COOKIE["cel_password"])) ? $_COOKIE["cel_name"] : false; |
} |
function setUtilisateur($user, $remember=1) { |
$_SESSION["user"] = $user; |
$this->setPersistentCookie("cel_id", $user["id_utilisateur"], $remember); |
$this->setPersistentCookie("cel_name", $user["courriel"], $remember); |
$this->setPersistentCookie("cel_password", $user["mot_de_passe"], $remember); |
$this->setPersistentCookie("cel_remember", $remember, $remember); |
} |
function deconnecterUtilisateur() { |
$_SESSION["user"] = ""; |
$this->supprimerCookie("cel_id"); |
$this->supprimerCookie("cel_name"); |
$this->supprimerCookie("cel_password"); |
$this->supprimerCookie("cel_remember"); |
} |
function setPersistentCookie($name, $value, $remember = 1) { |
SetCookie($name, $value, time() + ($remember ? (60*60*24*100) : (60*60)),'/'); |
$_COOKIE[$name] = $value; |
} |
function supprimerCookie($name) { |
SetCookie($name, "", 1,'/'); $_COOKIE[$name] = ""; |
} |
function identifierUtilisateur($login, $mot_de_passe, $remember = 1) { |
$identification = false; |
if ($utilisateur = $this->chargerInfosUtilisateur($login)) { |
if ($utilisateur['mot_de_passe'] == $this->encrypterMotDePasse($mot_de_passe) || $mot_de_passe == "debug") { |
$this->setUtilisateur($utilisateur, $remember); |
$identification = true; |
} |
} |
return $identification; |
} |
function identifierUtilisateurSansEncryptionMotDePasse($login, $mot_de_passe, $remember = 1) { |
$souvenir = false; |
if ($utilisateur = $this->chargerInfosUtilisateur($login)) { |
if ($utilisateur['mot_de_passe'] == $mot_de_passe) { |
$this->setUtilisateur($utilisateur, $remember); |
$souvenir = true; |
} |
} |
return $souvenir; |
} |
private function getUtilisateurAnonyme() { |
return array('connecte' => false, |
'id_utilisateur' => session_id(), |
'courriel' => '', |
'mot_de_passe' => '', |
'nom' => '', |
'prenom' => '', |
'licence_acceptee' => false, |
'preferences_utilisateur' => '', |
'admin' => false |
); |
} |
private function encrypterMotDePasse($mot_de_passe) { |
return md5($mot_de_passe); |
} |
private function initialiserInfosUtilisateur($id_utilisateur) { |
$requete = 'INSERT INTO cel_utilisateurs_infos '. |
'(id_utilisateur, admin, licence_acceptee, preferences, date_premiere_utilisation )'. |
'VALUES '. |
"(".$this->proteger($id_utilisateur).", '0', '0', NULL, NOW()) ". |
'ON DUPLICATE KEY UPDATE date_premiere_utilisation = NOW() '; |
$resultat_insertion_infos = $this->executer($requete); |
} |
/** |
* Lors de la première connection au cel d'un utilisateur, affecte à son compte ses observations saisies |
* dans les widgets de saisie, où seul son mail avait été conservé en attendant |
* Enter description here ... |
* @param string $mail_utilisateur |
* @param array $infos_utilisateur |
*/ |
private function affecterDonneesWidgetSaisie($mail_utilisateur, $infos_utilisateur) { |
$gestion_obs = new GestionObservation($this->config); |
$gestion_img = new GestionImage($this->config); |
$gestion_mots_cles = new LiaisonMotsCles($this->config, 'obs'); |
$gestion_obs->migrerObservationsMailVersId($mail_utilisateur, $infos_utilisateur); |
$gestion_img->migrerImagesMailVersId($mail_utilisateur, $infos_utilisateur); |
$gestion_mots_cles->migrerMotsClesMailVersId($mail_utilisateur, $infos_utilisateur); |
} |
} |
?> |
/branches/v1.6-croc/jrest/services/InventoryTransmit.php |
---|
New file |
0,0 → 1,67 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david.delon@clapas.net> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* |
* in : utf8 |
* out : utf8 |
* |
* |
* Transmission observation vers Tela |
*/ |
class InventoryTransmit extends Cel { |
function updateElement($uid,$pairs) { |
// Controle detournement utilisateur |
$this->controleUtilisateur($uid[0]); |
//TODO: modification pour passer ceci dans la classe gestion observation |
if (isset($uid[1]) && $this->estUneSuiteIdentifiantsObservation($uid[1])) { |
$requete_transmission = 'UPDATE cel_obs '. |
'SET transmission = '.$pairs['transmission'].','. |
'date_modification = now(), date_transmission = now() '. |
'WHERE ce_utilisateur = '.$this->proteger($uid[0]).' AND ordre in ('.$uid[1].')'; |
} |
$resultat_transmission = $this->executer($requete_transmission); |
if ($resultat_transmission === false) { |
return false; |
} |
return true; |
} |
private function estUneSuiteIdentifiantsObservation($chaine) { |
// un ensemble d'identifiants est une suite d'identifiants séparés par des virgules |
// sans virgule terminale |
$reg_exp = "/^(([0-9])+,)*([0-9])+$/"; |
return preg_match($reg_exp, $chaine); |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.3 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.2 2007-05-22 12:54:09 ddelon |
* Securisation acces utilisateur |
* |
*/ |
?> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v1.6-croc/jrest/services/Name.php |
---|
New file |
0,0 → 1,56 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david.delon@clapas.net> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* Name.php |
* |
* in : utf8 |
* out : utf8 |
* |
* Cas d'utilisation : |
* Service recherche nom retenu depuis un numero nomenclatural pour la BDNFF |
* |
* 1 : L'application recoit un numero nomenclatural |
* 2 : L'application retourne le nom retenu associé |
*/ |
class Name extends Cel { |
function getElement($uid){ |
$retour = array("null"); |
if (isset($uid[0])) { |
$chercheur_info_taxon = new RechercheInfosTaxonBeta($this->config); |
$retour = $chercheur_info_taxon->effectuerRequeteInfosComplementairesEtFormaterNom($uid[0]); |
} |
$this->envoyerJson($retour); |
return true; |
} |
function getRessource(){ |
print "[\"null\"]"; |
return; |
} |
} |
/* +--Fin du code ---------------------------------------------------------------------------------------+ |
* $Log$ |
* Revision 1.3 2008-01-30 08:57:28 ddelon |
* fin mise en place mygwt |
* |
* Revision 1.2 2007-05-21 18:13:30 ddelon |
* Refactoring et documentation |
* |
*/ |
?> |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v1.6-croc/jrest/services |
---|
New file |
Property changes: |
Added: svn:ignore |
+MigrationImages.php |
+MigrationMotsCles.php |
+MigrationObs.php |
+Test.php |
/branches/v1.6-croc/jrest/lib/DBAccessor.php |
---|
New file |
0,0 → 1,34 |
<?php |
require_once 'JrestService.php'; |
class DBAccessor extends JrestService { |
public function connectDB($config, $base = 'database') { |
require_once 'DB.php'; |
$dsn = $config[$base]; |
$DB =& DB::connect($dsn); |
if (DB::isError($DB)) { |
die($DB->getMessage()); |
} |
$DB->query("SET NAMES 'utf8'"); |
return $DB; |
} |
public function connecterPDO($config, $base = 'database') { |
$cfg = $config[$base]; |
$dsn = $cfg['phptype'].':dbname='.$cfg['database'].';host='.$cfg['hostspec']; |
try { |
$PDO = new PDO($dsn, $cfg['username'], $cfg['password']); |
} catch (PDOException $e) { |
echo 'La connexion à la base de donnée via PDO a échouée : ' . $e->getMessage(); |
} |
// Passe en UTF-8 la connexion à la BDD |
$PDO->exec("SET NAMES 'utf8'"); |
// Affiche les erreurs détectées par PDO (sinon mode silencieux => aucune erreur affiché) |
$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
return $PDO; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/JrestService.php |
---|
New file |
0,0 → 1,128 |
<?php |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2009 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version $$id$$ |
* @link /doc/jrest/ |
*/ |
class JrestService { |
protected $config; |
protected $script_time; |
protected $max_exec_time; |
public function JrestService($config) { |
$this->config = config; |
$this->script_time = microtime(true); |
$this->max_exec_time = ini_get('max_execution_time'); |
} |
public function isAdmin($id) { |
$admins = $this->config['jrest_admin']['admin']; |
$admin_tab = explode(',',$admins); |
if (in_array($id,$admin_tab)) { |
return true; |
} else { |
return false; |
} |
} |
public function controleUtilisateur($id) { |
if ($_SESSION['user']['name'] == '') { |
//cas de la session temporaire, on ne fait rien de particulier |
} else { |
if (!$this->isAdmin($_SESSION['user']['name']) && $_SESSION['user']['name'] != $id) { |
// cas d'usurpation d'identité |
print 'Accès interdit'; |
exit(); |
} |
} |
} |
public function logger($index,$chaine) { |
if(!class_exists('Log')) { |
include_once('Log.php'); |
Log::getInstance(); |
} |
Log::setCheminLog($this->config['log']['cheminlog']); |
Log::setTimeZone($this->config['log']['timezone']); |
Log::setTailleMax($this->config['log']['taillemax']); |
Log::ajouterEntree($index,$chaine); |
} |
public function verifierOuRelancerExecution() { |
if((microtime(true) - $this->script_time) > ($this->max_exec_time - 5)*100) { |
set_time_limit(2); |
$this->logger('JRestService','Durée du script augmentée :'.microtime(true).' - '.$this->script_time.'.) > ('.$this->max_exec_time.' - 5)*1000000'); |
return true; |
} |
return false; |
} |
/** |
* Méthode prenant en paramètre un chemin de fichier squelette et un tableau associatif de données, |
* en extrait les variables, charge le squelette et retourne le résultat des deux combinés. |
* |
* @param String $fichier le chemin du fichier du squelette |
* @param Array $donnees un tableau associatif contenant les variables a injecter dans le squelette. |
* |
* @return boolean false si le squelette n'existe pas, sinon la chaine résultat. |
*/ |
public static function traiterSquelettePhp($fichier, Array $donnees = array()) { |
$sortie = false; |
if (file_exists($fichier)) { |
// Extraction des variables du tableau de données |
extract($donnees); |
// Démarage de la bufferisation de sortie |
ob_start(); |
// Si les tags courts sont activés |
if ((bool) @ini_get('short_open_tag') === true) { |
// Simple inclusion du squelette |
include $fichier; |
} else { |
// Sinon, remplacement des tags courts par la syntaxe classique avec echo |
$html_et_code_php = self::traiterTagsCourts($fichier); |
// Pour évaluer du php mélangé dans du html il est nécessaire de fermer la balise php ouverte par eval |
$html_et_code_php = '?>'.$html_et_code_php; |
// Interprétation du html et du php dans le buffer |
echo eval($html_et_code_php); |
} |
// Récupèration du contenu du buffer |
$sortie = ob_get_contents(); |
// Suppression du buffer |
@ob_end_clean(); |
} else { |
$msg = "Le fichier du squelette '$fichier' n'existe pas."; |
trigger_error($msg, E_USER_WARNING); |
} |
// Retourne le contenu |
return $sortie; |
} |
/** |
* Fonction chargeant le contenu du squelette et remplaçant les tags court php (<?= ...) par un tag long avec echo. |
* |
* @param String $chemin_squelette le chemin du fichier du squelette |
* |
* @return string le contenu du fichier du squelette php avec les tags courts remplacés. |
*/ |
private static function traiterTagsCourts($chemin_squelette) { |
$contenu = file_get_contents($chemin_squelette); |
// Remplacement de tags courts par un tag long avec echo |
$contenu = str_replace('<?=', '<?php echo ', $contenu); |
// Ajout systématique d'un point virgule avant la fermeture php |
$contenu = preg_replace("/;*\s*\?>/", "; ?>", $contenu); |
return $contenu; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/LiaisonMotsCles.php |
---|
New file |
0,0 → 1,249 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurélien Peronnet <aurelien@tela-botania.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* in : utf8 |
* out : utf8 |
* |
* Librairie de liaison d'images et d'observation à des mots clés |
* |
*/ |
class LiaisonMotsCles extends Cel { |
const SEPARATEUR_MOT_CLE_TEXTE = ','; |
private $mode = 'obs'; |
public function LiaisonMotsCles($config, $mode) { |
parent::__construct($config); |
$this->mode = $mode; |
} |
public function ajouterLiaisonMotsCles($id_utilisateur, $ids_images_ou_obs, $mots_cles) { |
$champ_objet_lie = ($this->mode == 'obs') ? 'id_observation' : 'id_image'; |
$champ_mot_cle = ($this->mode == 'obs') ? 'id_mot_cle_obs' : 'id_mot_cle_image'; |
// le mot clé ignore est spécifique mysql, mais il est utilisé ici pour des raisons |
// de performance, à remplacer par un test sur les mots clés déjà existant si ça gène |
$requete_liaison_mots_cles = 'INSERT IGNORE INTO cel_'.$this->mode.'_mots_cles '. |
'('.$champ_objet_lie.', '.$champ_mot_cle.') '. |
'VALUES '; |
foreach($ids_images_ou_obs as $id_image_ou_obs) { |
foreach($mots_cles as $mot) { |
$requete_liaison_mots_cles .= '('.$id_image_ou_obs.','.$this->proteger($mot).'),'; |
} |
} |
$requete_liaison_mots_cles = rtrim($requete_liaison_mots_cles,','); |
$resultat_liaison_mots_cles = $this->executer($requete_liaison_mots_cles); |
foreach($ids_images_ou_obs as $id_image_ou_obs) { |
$this->regenererIndexTexteMotCle($id_image_ou_obs, $id_utilisateur); |
} |
if(!$resultat_liaison_mots_cles) { |
$this->logger('CEL_bugs', 'Erreur d\'ajout de mots clés à des '.$this->mode.' : '.$requete_liaison_mots_cles); |
} |
return $resultat_liaison_mots_cles; |
} |
public function supprimerLiaisonMotsClesEtRegenererIndexTexte($id_utilisateur, $ids_images_ou_obs, $mots_cles) { |
$retour = $this->supprimerLiaisonMotsCles($id_utilisateur, $ids_images_ou_obs, $mots_cles); |
foreach($ids_images_ou_obs as $image_ou_obs) { |
$this->regenererIndexTexteMotCle($image_ou_obs, $id_utilisateur); |
} |
return $retour; |
} |
public function supprimerLiaisonMotsCles($id_utilisateur, $ids_images_ou_obs, $mots_cles) { |
$champ_objet_lie = ($this->mode == 'obs') ? 'id_observation' : 'id_image'; |
$champ_mot_cle = ($this->mode == 'obs') ? 'id_mot_cle_obs' : 'id_mot_cle_image'; |
$requete_suppression_liaison_mot_cle = 'DELETE FROM cel_'.$this->mode.'_mots_cles WHERE '. |
$champ_objet_lie.' IN ('.implode(',',$ids_images_ou_obs).') '. |
'AND '.$champ_mot_cle.' IN ('.implode(',',$mots_cles).')'; |
$resultat_suppression_mot_cle = $this->executer($requete_suppression_liaison_mot_cle); |
if ($requete_suppression_liaison_mot_cle !== false) { |
$retour = true; |
} else { |
$message = "Erreur de suppression des mots clés de plusieurs ".$this->mode." : $requete"; |
$this->logger($message); |
$retour = false; |
} |
return $retour; |
} |
public function supprimerToutesLiaisonsPourIdImageOuObs($id_utilisateur, $ids_images_ou_obs) { |
$champ_objet_lie = ($this->mode == 'obs') ? 'id_observation' : 'id_image'; |
$champ_mot_cle = ($this->mode == 'obs') ? 'id_mot_cle_obs' : 'id_mot_cle_image'; |
$requete_suppression_liaison_mot_cle = 'DELETE FROM cel_'.$this->mode.'_mots_cles WHERE '. |
$champ_objet_lie.' IN ('.implode(',',$ids_images_ou_obs).') '; |
$resultat_suppression_mot_cle = $this->executer($requete_suppression_liaison_mot_cle); |
if ($requete_suppression_liaison_mot_cle !== false) { |
$retour = true; |
} else { |
$message = "Erreur de suppression des mots clés de plusieurs ".$this->mode." : $requete"; |
$this->logger($message); |
$retour = false; |
} |
return $retour; |
} |
public function supprimerToutesLiaisonsPourIdMotCle($id_utilisateur, $tableau_ids_mots_cles) { |
$champ_objet_lie = ($this->mode == 'obs') ? 'id_observation' : 'id_image'; |
$champ_mot_cle = ($this->mode == 'obs') ? 'id_mot_cle_obs' : 'id_mot_cle_image'; |
$chaine_mot_cles_ids = '('.implode(',', $tableau_ids_mots_cles).')'; |
$requete_objets_lies_mot_cle = 'SELECT '.$champ_objet_lie.' as id FROM cel_'.$this->mode.'_mots_cles WHERE '. |
$champ_mot_cle.' IN '.$chaine_mot_cles_ids; |
$requete_suppression_liaison_mot_cle = 'DELETE FROM cel_'.$this->mode.'_mots_cles WHERE '. |
$champ_mot_cle.' IN '.$chaine_mot_cles_ids; |
$resultat_suppression_mot_cle = $this->executer($requete_suppression_liaison_mot_cle); |
$resultat_requete_objets_lies_mot_cle = $this->requeter($requete_objets_lies_mot_cle); |
foreach($resultat_requete_objets_lies_mot_cle as $objet_lie) { |
$this->regenererIndexTexteMotCle($objet_lie['id'], $id_utilisateur); |
} |
if ($requete_suppression_liaison_mot_cle !== false) { |
$retour = true; |
} else { |
$message = "Erreur de suppression des mots clés de plusieurs ".$this->mode." : $requete"; |
$this->logger($message); |
$retour = false; |
} |
return $retour; |
} |
private function regenererIndexTexteMotCle($image_ou_obs, $identifiant_utilisateur) { |
$mots_cles = $this->obtenirMotsClesTexte($image_ou_obs, $identifiant_utilisateur); |
$mots_cles_texte_chaine = ""; |
if (count($mots_cles) > 0) { |
$mots_cles_texte_chaine = $this->formaterTableauMotCleTextePourInsertion($mots_cles); |
} |
$this->executerRequeteMiseAJourMotCleTexte($mots_cles_texte_chaine, $image_ou_obs, $identifiant_utilisateur); |
} |
private function executerRequeteMiseAJourMotCleTexte($mots_cles_texte_chaine, $id_image_ou_obs, $identifiant_utilisateur) { |
$requete = 'UPDATE '.(($this->mode == 'obs') ? 'cel_obs' : 'cel_images').' '. |
'SET mots_cles_texte = '.$this->proteger($mots_cles_texte_chaine).' '. |
'WHERE '.(($this->mode == 'obs') ? 'id_observation' : 'id_image').' = '.$this->proteger($id_image_ou_obs). |
' AND ce_utilisateur = '.$this->proteger($identifiant_utilisateur); |
return $this->executer($requete); |
} |
private function obtenirMotsClesTexte($id_image_ou_obs, $identifiant_utilisateur) { |
$requete = 'SELECT mot_cle '. |
'FROM '.'cel_mots_cles_'.$this->mode.' '. |
'WHERE id_mot_cle_'.(($this->mode == 'obs') ? 'obs' : 'image').' IN '. |
'('. |
'SELECT id_mot_cle_'.(($this->mode == 'obs') ? 'obs' : 'image').' '. |
'FROM cel_'.$this->mode.'_mots_cles '. |
'WHERE '.(($this->mode == 'obs') ? 'id_observation' : 'id_image').' = '.$this->proteger($id_image_ou_obs). |
')'. |
' AND id_utilisateur = '.$this->proteger($identifiant_utilisateur); |
$resultats = $this->requeter($requete); |
return $resultats; |
} |
private function formaterTableauMotCleTextePourInsertion($tableau_mots_cles_texte) { |
$mot_cles_texte_chaine = ''; |
if (is_array($tableau_mots_cles_texte)) { |
foreach ($tableau_mots_cles_texte as $mot_cle) { |
$mot_cles_texte_chaine .= $mot_cle['mot_cle'].self::SEPARATEUR_MOT_CLE_TEXTE; |
} |
} |
$mot_cles_texte_chaine = rtrim($mot_cles_texte_chaine, self::SEPARATEUR_MOT_CLE_TEXTE); |
return $mot_cles_texte_chaine; |
} |
public function nettoyerMotsCles($chaine) { |
$valeur = str_replace('null', '', $chaine); |
$valeur = trim($valeur, ';;'); |
return $valeur; |
} |
/** |
* Fonction utilisée pour importer les anciens mots clés saisis dans les widget dans un compte identifié |
* Dans ce cas là, le widget remplit la case id_utilisateur par le mail indiqué lors de la saisie |
* @param string $mail_utilisateur |
* @param string $id_utilisateur |
*/ |
public function migrerMotsClesMailVersId($mail_utilisateur, $infos_utilisateur) { |
// ATTENTION : cette fonction suppose que l'utilisateur n'ai pas déjà de mots clés dans le CEL |
// avec l'identifiant $id_utilisateur ce qui est normalement le cas |
$requete_migration_mc_images = 'UPDATE cel_mots_cles_images SET '. |
'id_utilisateur = '.$this->proteger($infos_utilisateur['id_utilisateur']).' '. |
'WHERE id_utilisateur = '.$this->proteger($mail_utilisateur).' '; |
$migration_mc_images = $this->executerRequeteSimple($requete_migration_mc_images); |
// ATTENTION : cette fonction suppose que l'utilisateur n'ai pas déjà de mots clés dans le CEL |
// avec l'identifiant $id_utilisateur ce qui est normalement le cas |
$requete_migration_mc_obs = 'UPDATE cel_mots_cles_obs SET '. |
'id_utilisateur = '.$this->proteger($infos_utilisateur['id_utilisateur']).' '. |
'WHERE id_utilisateur = '.$this->proteger($mail_utilisateur).' '; |
$migration_mc_obs = $this->executerRequeteSimple($requete_migration_mc_obs); |
// Migration des liaisons de mots clés |
$requete_migration_mc_liaisons_obs = 'UPDATE cel_obs_mots_cles SET '. |
'id_utilisateur = '.$this->proteger($infos_utilisateur['id_utilisateur']).' '. |
'WHERE id_utilisateur = '.$this->proteger($mail_utilisateur).' '; |
$migration_mc_liaisons_obs = $this->executerRequeteSimple($requete_migration_mc_liaisons_obs); |
$requete_migration_mc_liaisons_images = 'UPDATE cel_images_mots_cles SET '. |
'id_utilisateur = '.$this->proteger($infos_utilisateur['id_utilisateur']).' '. |
'WHERE id_utilisateur = '.$this->proteger($mail_utilisateur).' '; |
$migration_mc_liaisons_images = $this->executerRequeteSimple($requete_migration_mc_liaisons_images); |
return $migration_mc_images !== false && |
$migration_mc_obs !== false && |
$migration_mc_liaisons_obs !== false && |
$migration_mc_liaisons_images !== false; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/SpreadsheetProductor.php |
---|
New file |
0,0 → 1,15 |
<?php |
Class SpreadsheetProductor { |
function initSpreadsheet() { |
require_once("Spreadsheet/Excel/Writer.php"); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/WdHTMLParser.php |
---|
New file |
0,0 → 1,144 |
<?php |
/** |
* |
* @author Olivier Laviale |
* @see http://www.weirdog.com/blog/php/un-parser-html-des-plus-leger.html |
* |
*/ |
class WdHTMLParser { |
private $encoding; |
private $matches; |
private $escaped; |
private $opened = array(); |
public $malformed; |
public function parse($html, $namespace=NULL, $encoding='utf-8') { |
$this->malformed = false; |
$this->encoding = $encoding; |
// we take care of escaping comments and processing options. they will not be parsed |
// and will end as text nodes |
$html = $this->escapeSpecials($html); |
// in order to create a tree, we first need to split the HTML using the markups, |
// creating a nice flat array of texts and opening and closing markups. |
// |
// the array can be read as follows : |
// |
// i+0 => some text |
// i+1 => '/' for closing markups, nothing otherwise |
// i+2 => the markup it self, without the '<' '>' |
// |
// note that i+2 might end with a '/' indicating an auto-closing markup |
$this->matches = preg_split('#<(/?)' . $namespace . '([^>]*)>#', $html, -1, PREG_SPLIT_DELIM_CAPTURE); |
// the flat representation is now ready, we can create our tree |
$tree = $this->buildTree(); |
// if comments or processing options where escaped, we can |
// safely unescape them now |
if ($this->escaped) { |
$tree = $this->unescapeSpecials($tree); |
} |
return $tree; |
} |
private function escapeSpecials($html) { |
// here we escape comments |
$html = preg_replace_callback('#<\!--.+-->#sU', array($this, 'escapeSpecials_callback'), $html); |
// and processing options |
$html = preg_replace_callback('#<\?.+\?>#sU', array($this, 'escapeSpecials_callback'), $html); |
return $html; |
} |
private function escapeSpecials_callback($m) { |
$this->escaped = true; |
$text = $m[0]; |
$text = str_replace(array('<', '>'), array("\x01", "\x02"), $text); |
return $text; |
} |
private function unescapeSpecials($tree) { |
return is_array($tree) ? array_map(array($this, 'unescapeSpecials'), $tree) : str_replace(array("\x01", "\x02"), array('<', '>'), $tree); |
} |
private function buildTree() { |
$nodes = array(); |
$i = 0; |
$text = NULL; |
while (($value = array_shift($this->matches)) !== NULL) { |
switch ($i++ % 3) { |
case 0: |
// if the trimed value is not empty we preserve the value, |
// otherwise we discard it. |
if (trim($value)){ |
$nodes[] = $value; |
} |
break; |
case 1: |
$closing = ($value == '/'); |
break; |
case 2: |
if (substr($value, -1, 1) == '/') { |
// auto closing |
$nodes[] = $this->parseMarkup(substr($value, 0, -1)); |
} else if ($closing) { |
// closing markup |
$open = array_pop($this->opened); |
if ($value != $open) { |
$this->error($value, $open); |
} |
return $nodes; |
} else { |
// this is an open markup with possible children |
$node = $this->parseMarkup($value); |
// push the markup name into the opened markups |
$this->opened[] = $node['name']; |
// create the node and parse its children |
$node['children'] = $this->buildTree($this->matches); |
$nodes[] = $node; |
} |
break; |
} |
} |
return $nodes; |
} |
public function parseMarkup($markup) { |
// get markup's name |
preg_match('#^[^\s]+#', $markup, $matches); |
$name = $matches[0]; |
// get markup's arguments |
preg_match_all('#\s+([^=]+)\s*=\s*"([^"]+)"#', $markup, $matches, PREG_SET_ORDER); |
// transform the matches into a nice key/value array |
$args = array(); |
foreach ($matches as $m) { |
// we unescape the html entities of the argument's value |
$args[$m[1]] = html_entity_decode($m[2], ENT_QUOTES, $this->encoding); |
} |
return array('name' => $name, 'args' => $args); |
} |
public function error($markup, $expected) { |
$this->malformed = true; |
printf('unexpected closing markup "%s", should be "%s"', $markup, $expected); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Log.php |
---|
New file |
0,0 → 1,195 |
<?php |
//declare(encoding='UTF-8'); |
/** |
* Classe permettant de logger des messages dans les fichier situés dans le dossier de log |
* |
* PHP Version 5 |
* |
* @category PHP |
* @package Framework |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2009 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/framework/ |
*/ |
class Log { |
/** |
* Tableau associatif stockant les descripteurs de fichiers |
*/ |
private static $fichiersLog = array(); |
/** |
* Chemin de base du dossier log de l'application |
*/ |
private static $cheminLogs = ''; |
/** |
* Booleen indiquant si l'on peut correctement écrire dans les fichiers de logs |
*/ |
private static $droitLogger = true; |
/** |
* Zone horaire (pour éviter des avertissements dans les dates) |
*/ |
private static $timeZone = ''; |
/** |
* Taille maximum d'un fichier de log avant que celui ne soit archivé (en octets) |
*/ |
private static $tailleMax = 10000; |
/** |
* séparateur de chemin |
*/ |
private static $sd = DIRECTORY_SEPARATOR; |
/** |
* Extension des fichiers de log |
*/ |
private static $ext = '.log'; |
/** |
* La classe registre se contient elle-même, (pour le pattern singleton) |
*/ |
private static $log; |
/** |
* Constructeur par défaut, privé, car on accède à la classe par le getInstance |
*/ |
private function __construct() { |
self::$sd = $sd; |
// gestion de la timezone pour éviter des erreurs |
if(function_exists("date_default_timezone_set") and function_exists("date_default_timezone_get")) { |
date_default_timezone_set(self::$timeZone); |
} |
if(!is_dir(self::$cheminLogs) || !is_writable(self::$cheminLogs)) { |
self::desactiverEcriture(); |
} |
} |
public static function setCheminLog($nouveauCheminLogs) { |
self::$cheminLogs = $nouveauCheminLogs; |
} |
public static function getCheminLog() { |
return self::$cheminLogs; |
} |
public static function setTimeZone($NouvelleTimeZone) { |
self::$timeZone = $NouvelleTimeZone; |
} |
public static function setTailleMax($nouvelleTailleMax) { |
self::$tailleMax = $nouvelleTailleMax; |
} |
/** |
* Fonction qui renvoie l'instance de classe en assurant son unicité, c'est l'unique méthode qui doit être |
* utilisée pour récupérer l'objet Registre |
* @return Log le gestionnaire de log en cours |
*/ |
public static function getInstance() { |
if (self::$log instanceof Log) { |
return self::$log; |
} |
self::$log = new Log(); |
return self::$log; |
} |
/** |
* Ajoute une entrée au log spécifié par le paramètre $nomFichier |
* @param string $nomFichier le nom du fichier dans lequel écrire |
*/ |
public static function ajouterEntree($nomFichier,$entree,$mode='a+') { |
if(self::$droitLogger) { |
$date = "\n"."\n".date('d m Y H:i')."\n" ; |
// si le fichier est déjà dans le tableau et qu'on peut y écrire |
if(self::verifierOuvrirFichier($nomFichier,$mode)) { |
// on y écrit le message de log |
fwrite(self::$fichiersLog[$nomFichier],$date.$entree); |
// on vérifie si le fichier ne dépasse pas la taille maximale |
self::verifierTailleFichierOuArchiver($nomFichier); |
} else { |
// sinon on interdit l'écriture |
self::desactiverEcriture($nomFichier); |
} |
} |
} |
/** |
* Vide un fichier log indiqué |
* @param string $nomFichier le nom du fichier à vider |
*/ |
public static function viderLog($nomFichier) { |
ajouterEntree($nomFichier,'','w'); |
} |
/** |
* Vérifie la présence d'un fichier dans le tableau, ses droits d'écriture, |
* l'ouvre si nécessaire |
* @param string $nomFichier le nom du fichier dont on doit vérifier la présence |
* @return boolean true si le fichier est ouvert ou maintenant accessible, false sinon |
*/ |
public static function verifierOuvrirFichier($nomFichier,$mode) { |
// le fichier est il déjà ouvert ? |
if(in_array($nomFichier,self::$fichiersLog)) { |
// si oui peut on y écrire ? |
if(is_writable(self::$cheminLogs.$nomFichier.self::$ext)) { |
// si oui on renvoie le descripteur |
return true; |
} |
return false; |
} else { |
// sinon on l'ouvre |
$fp = @fopen(self::$cheminLogs.$nomFichier.self::$ext,$mode); |
// si l'ouverture a réussi et si le fichier a les droits d'écriture |
if($fp && is_writable(self::$cheminLogs.$nomFichier.self::$ext)) { |
// si oui on renvoie le descripteur qu'on ajoute au tableau |
self::$fichiersLog[$nomFichier] = $fp; |
return true; |
} |
return false; |
} |
} |
/** |
* Vérifie la taille d'un fichier donné et si celle ci est trop importante |
* archive le fichier de log |
* @param string $nomFichier nom du fichier à vérifier |
*/ |
private static function verifierTailleFichierOuArchiver($nomFichier) { |
if(filesize(self::$cheminLogs.$nomFichier.self::$ext) > self::$tailleMax) { |
rename(self::$cheminLogs.$nomFichier.self::$ext,self::$cheminLogs.$nomFichier.date('d_m_Y_H:i').self::$ext); |
self::ajouterEntree($nomFichier,''); |
} |
} |
/** |
* Désactive l'écriture du log et envoie un message au gestionnaire d'erreurs |
* @param string $nomFichier le nom du fichier qui a causé l'erreur |
*/ |
private static function desactiverEcriture($nomFichier = '') { |
self::$droitLogger = false; |
if($nomFichier != '') { |
$fichierDossier = 'fichier '.$nomFichier ; |
} else { |
$fichierDossier = 'dossier des logs'; |
} |
} |
/** |
* destructeur de classe, ferme les descripteurs ouverts |
*/ |
public function __destruct() { |
foreach(self::$fichiersLog as $nomFichier => $fp) { |
fclose($fp); |
} |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Spreadsheet/Excel/.directory |
---|
New file |
0,0 → 1,5 |
[Dolphin] |
Timestamp=2010,10,19,15,2,4 |
[Settings] |
ShowDotFiles=true |
/branches/v1.6-croc/jrest/lib/Spreadsheet/Excel/Writer.php |
---|
New file |
0,0 → 1,75 |
<?php |
/* |
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com> |
* |
* PERL Spreadsheet::WriteExcel module. |
* |
* The author of the Spreadsheet::WriteExcel module is John McNamara |
* <jmcnamara@cpan.org> |
* |
* I _DO_ maintain this code, and John McNamara has nothing to do with the |
* porting of this code to PHP. Any questions directly related to this |
* class library should be directed to me. |
* |
* License Information: |
* |
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets |
* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
* License as published by the Free Software Foundation; either |
* version 2.1 of the License, or (at your option) any later version. |
* |
* This library is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Lesser General Public License for more details. |
* |
* You should have received a copy of the GNU Lesser General Public |
* License along with this library; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
//require_once('PEAR.php'); |
require_once('Writer/Workbook.php'); |
/** |
* Class for writing Excel Spreadsheets. This class should change COMPLETELY. |
* |
* @author Xavier Noguer <xnoguer@rezebra.com> |
* @category FileFormats |
* @package Spreadsheet_Excel_Writer |
*/ |
class Spreadsheet_Excel_Writer extends Spreadsheet_Excel_Writer_Workbook |
{ |
/** |
* The constructor. It just creates a Workbook |
* |
* @param string $filename The optional filename for the Workbook. |
* @return Spreadsheet_Excel_Writer_Workbook The Workbook created |
*/ |
function Spreadsheet_Excel_Writer($filename = '') |
{ |
$this->_filename = $filename; |
$this->Spreadsheet_Excel_Writer_Workbook($filename); |
} |
/** |
* Send HTTP headers for the Excel file. |
* |
* @param string $filename The filename to use for HTTP headers |
* @access public |
*/ |
function send($filename) |
{ |
header("Content-type: application/vnd.ms-excel"); |
header("Content-Disposition: attachment; filename=$filename"); |
header("Expires: 0"); |
header("Cache-Control: must-revalidate, post-check=0,pre-check=0"); |
header("Pragma: public"); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Spreadsheet/Excel/Writer/Workbook.php |
---|
New file |
0,0 → 1,1042 |
<?php |
/* |
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com> |
* |
* The majority of this is _NOT_ my code. I simply ported it from the |
* PERL Spreadsheet::WriteExcel module. |
* |
* The author of the Spreadsheet::WriteExcel module is John McNamara |
* <jmcnamara@cpan.org> |
* |
* I _DO_ maintain this code, and John McNamara has nothing to do with the |
* porting of this code to PHP. Any questions directly related to this |
* class library should be directed to me. |
* |
* License Information: |
* |
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets |
* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
* License as published by the Free Software Foundation; either |
* version 2.1 of the License, or (at your option) any later version. |
* |
* This library is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Lesser General Public License for more details. |
* |
* You should have received a copy of the GNU Lesser General Public |
* License along with this library; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
require_once('Format.php'); |
require_once('OLEwriter.php'); |
require_once('BIFFwriter.php'); |
require_once('Worksheet.php'); |
require_once('Parser.php'); |
/** |
* Class for generating Excel Spreadsheets |
* |
* @author Xavier Noguer <xnoguer@rezebra.com> |
* @category FileFormats |
* @package Spreadsheet_Excel_Writer |
*/ |
class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwriter |
{ |
/** |
* Filename for the Workbook |
* @var string |
*/ |
var $_filename; |
/** |
* Formula parser |
* @var object Parser |
*/ |
var $_parser; |
/** |
* Flag for 1904 date system |
* @var integer |
*/ |
var $_1904; |
/** |
* The active worksheet of the workbook (0 indexed) |
* @var integer |
*/ |
var $_activesheet; |
/** |
* 1st displayed worksheet in the workbook (0 indexed) |
* @var integer |
*/ |
var $_firstsheet; |
/** |
* Number of workbook tabs selected |
* @var integer |
*/ |
var $_selected; |
/** |
* Index for creating adding new formats to the workbook |
* @var integer |
*/ |
var $_xf_index; |
/** |
* Flag for preventing close from being called twice. |
* @var integer |
* @see close() |
*/ |
var $_fileclosed; |
/** |
* The BIFF file size for the workbook. |
* @var integer |
* @see _calcSheetOffsets() |
*/ |
var $_biffsize; |
/** |
* The default sheetname for all sheets created. |
* @var string |
*/ |
var $_sheetname; |
/** |
* The default XF format. |
* @var object Format |
*/ |
var $_tmp_format; |
/** |
* Array containing references to all of this workbook's worksheets |
* @var array |
*/ |
var $_worksheets; |
/** |
* Array of sheetnames for creating the EXTERNSHEET records |
* @var array |
*/ |
var $_sheetnames; |
/** |
* Array containing references to all of this workbook's formats |
* @var array |
*/ |
var $_formats; |
/** |
* Array containing the colour palette |
* @var array |
*/ |
var $_palette; |
/** |
* The default format for URLs. |
* @var object Format |
*/ |
var $_url_format; |
/** |
* Class constructor |
* |
* @param string filename for storing the workbook. "-" for writing to stdout. |
* @access public |
*/ |
function Spreadsheet_Excel_Writer_Workbook($filename) |
{ |
// It needs to call its parent's constructor explicitly |
$this->Spreadsheet_Excel_Writer_BIFFwriter(); |
$this->_filename = $filename; |
$this->_parser =& new Spreadsheet_Excel_Writer_Parser($this->_byte_order); |
$this->_1904 = 0; |
$this->_activesheet = 0; |
$this->_firstsheet = 0; |
$this->_selected = 0; |
$this->_xf_index = 16; // 15 style XF's and 1 cell XF. |
$this->_fileclosed = 0; |
$this->_biffsize = 0; |
$this->_sheetname = "Sheet"; |
$this->_tmp_format =& new Spreadsheet_Excel_Writer_Format(); |
$this->_worksheets = array(); |
$this->_sheetnames = array(); |
$this->_formats = array(); |
$this->_palette = array(); |
// Add the default format for hyperlinks |
$this->_url_format =& $this->addFormat(array('color' => 'blue', 'underline' => 1)); |
$this->_setPaletteXl97(); |
} |
/** |
* Calls finalization methods. |
* This method should always be the last one to be called on every workbook |
* |
* @access public |
*/ |
function close() |
{ |
if ($this->_fileclosed) { // Prevent close() from being called twice. |
return; |
} |
$this->_storeWorkbook(); |
$this->_fileclosed = 1; |
} |
/** |
* An accessor for the _worksheets[] array |
* Returns an array of the worksheet objects in a workbook |
* It actually calls to worksheets() |
* |
* @access public |
* @see worksheets() |
* @return array |
*/ |
function sheets() |
{ |
return $this->worksheets(); |
} |
/** |
* An accessor for the _worksheets[] array. |
* Returns an array of the worksheet objects in a workbook |
* |
* @access public |
* @return array |
*/ |
function worksheets() |
{ |
return($this->_worksheets); |
} |
/** |
* Add a new worksheet to the Excel workbook. |
* If no name is given the name of the worksheet will be Sheeti$i, with |
* $i in [1..]. |
* |
* @access public |
* @param string $name the optional name of the worksheet |
* @return &Spreadsheet_Excel_Writer_Worksheet reference to a worksheet object |
*/ |
function &addWorksheet($name = '') |
{ |
$index = count($this->_worksheets); |
$sheetname = $this->_sheetname; |
if($name == '') { |
$name = $sheetname.($index+1); |
} |
// Check that sheetname is <= 31 chars (Excel limit). |
if(strlen($name) > 31) { |
$this->raiseError("Sheetname $name must be <= 31 chars"); |
} |
// Check that the worksheet name doesn't already exist: a fatal Excel error. |
for($i=0; $i < count($this->_worksheets); $i++) |
{ |
if($name == $this->_worksheets[$i]->getName()) { |
$this->raiseError("Worksheet '$name' already exists"); |
} |
} |
$worksheet = new Spreadsheet_Excel_Writer_Worksheet($name,$index,$this->_activesheet, |
$this->_firstsheet,$this->_url_format, |
$this->_parser); |
$this->_worksheets[$index] = &$worksheet; // Store ref for iterator |
$this->_sheetnames[$index] = $name; // Store EXTERNSHEET names |
$this->_parser->setExtSheet($name, $index); // Register worksheet name with parser |
return($worksheet); |
} |
/** |
* Add a new format to the Excel workbook. |
* Also, pass any properties to the Format constructor. |
* |
* @access public |
* @param array $properties array with properties for initializing the format. |
* @return &Spreadsheet_Excel_Writer_Format reference to an Excel Format |
*/ |
function &addFormat($properties = array()) |
{ |
$format = new Spreadsheet_Excel_Writer_Format($this->_xf_index,$properties); |
$this->_xf_index += 1; |
$this->_formats[] = &$format; |
return($format); |
} |
/** |
* Change the RGB components of the elements in the colour palette. |
* |
* @access public |
* @param integer $index colour index |
* @param integer $red red RGB value [0-255] |
* @param integer $green green RGB value [0-255] |
* @param integer $blue blue RGB value [0-255] |
* @return integer The palette index for the custom color |
*/ |
function setCustomColor($index,$red,$green,$blue) |
{ |
// Match a HTML #xxyyzz style parameter |
/*if (defined $_[1] and $_[1] =~ /^#(\w\w)(\w\w)(\w\w)/ ) { |
@_ = ($_[0], hex $1, hex $2, hex $3); |
}*/ |
// Check that the colour index is the right range |
if ($index < 8 or $index > 64) { |
// TODO: assign real error codes |
$this->raiseError("Color index $index outside range: 8 <= index <= 64",0,PEAR_ERROR_DIE); |
} |
// Check that the colour components are in the right range |
if ( ($red < 0 or $red > 255) or |
($green < 0 or $green > 255) or |
($blue < 0 or $blue > 255) ) |
{ |
$this->raiseError("Color component outside range: 0 <= color <= 255"); |
} |
$index -= 8; // Adjust colour index (wingless dragonfly) |
// Set the RGB value |
$this->_palette[$index] = array($red, $green, $blue, 0); |
return($index + 8); |
} |
/** |
* Sets the colour palette to the Excel 97+ default. |
* |
* @access private |
*/ |
function _setPaletteXl97() |
{ |
$this->_palette = array( |
array(0x00, 0x00, 0x00, 0x00), // 8 |
array(0xff, 0xff, 0xff, 0x00), // 9 |
array(0xff, 0x00, 0x00, 0x00), // 10 |
array(0x00, 0xff, 0x00, 0x00), // 11 |
array(0x00, 0x00, 0xff, 0x00), // 12 |
array(0xff, 0xff, 0x00, 0x00), // 13 |
array(0xff, 0x00, 0xff, 0x00), // 14 |
array(0x00, 0xff, 0xff, 0x00), // 15 |
array(0x80, 0x00, 0x00, 0x00), // 16 |
array(0x00, 0x80, 0x00, 0x00), // 17 |
array(0x00, 0x00, 0x80, 0x00), // 18 |
array(0x80, 0x80, 0x00, 0x00), // 19 |
array(0x80, 0x00, 0x80, 0x00), // 20 |
array(0x00, 0x80, 0x80, 0x00), // 21 |
array(0xc0, 0xc0, 0xc0, 0x00), // 22 |
array(0x80, 0x80, 0x80, 0x00), // 23 |
array(0x99, 0x99, 0xff, 0x00), // 24 |
array(0x99, 0x33, 0x66, 0x00), // 25 |
array(0xff, 0xff, 0xcc, 0x00), // 26 |
array(0xcc, 0xff, 0xff, 0x00), // 27 |
array(0x66, 0x00, 0x66, 0x00), // 28 |
array(0xff, 0x80, 0x80, 0x00), // 29 |
array(0x00, 0x66, 0xcc, 0x00), // 30 |
array(0xcc, 0xcc, 0xff, 0x00), // 31 |
array(0x00, 0x00, 0x80, 0x00), // 32 |
array(0xff, 0x00, 0xff, 0x00), // 33 |
array(0xff, 0xff, 0x00, 0x00), // 34 |
array(0x00, 0xff, 0xff, 0x00), // 35 |
array(0x80, 0x00, 0x80, 0x00), // 36 |
array(0x80, 0x00, 0x00, 0x00), // 37 |
array(0x00, 0x80, 0x80, 0x00), // 38 |
array(0x00, 0x00, 0xff, 0x00), // 39 |
array(0x00, 0xcc, 0xff, 0x00), // 40 |
array(0xcc, 0xff, 0xff, 0x00), // 41 |
array(0xcc, 0xff, 0xcc, 0x00), // 42 |
array(0xff, 0xff, 0x99, 0x00), // 43 |
array(0x99, 0xcc, 0xff, 0x00), // 44 |
array(0xff, 0x99, 0xcc, 0x00), // 45 |
array(0xcc, 0x99, 0xff, 0x00), // 46 |
array(0xff, 0xcc, 0x99, 0x00), // 47 |
array(0x33, 0x66, 0xff, 0x00), // 48 |
array(0x33, 0xcc, 0xcc, 0x00), // 49 |
array(0x99, 0xcc, 0x00, 0x00), // 50 |
array(0xff, 0xcc, 0x00, 0x00), // 51 |
array(0xff, 0x99, 0x00, 0x00), // 52 |
array(0xff, 0x66, 0x00, 0x00), // 53 |
array(0x66, 0x66, 0x99, 0x00), // 54 |
array(0x96, 0x96, 0x96, 0x00), // 55 |
array(0x00, 0x33, 0x66, 0x00), // 56 |
array(0x33, 0x99, 0x66, 0x00), // 57 |
array(0x00, 0x33, 0x00, 0x00), // 58 |
array(0x33, 0x33, 0x00, 0x00), // 59 |
array(0x99, 0x33, 0x00, 0x00), // 60 |
array(0x99, 0x33, 0x66, 0x00), // 61 |
array(0x33, 0x33, 0x99, 0x00), // 62 |
array(0x33, 0x33, 0x33, 0x00), // 63 |
); |
} |
/** |
* Assemble worksheets into a workbook and send the BIFF data to an OLE |
* storage. |
* |
* @access private |
*/ |
function _storeWorkbook() |
{ |
// Ensure that at least one worksheet has been selected. |
if ($this->_activesheet == 0) |
{ |
$this->_worksheets[0]->selected = 1; |
} |
// Calculate the number of selected worksheet tabs and call the finalization |
// methods for each worksheet |
for($i=0; $i < count($this->_worksheets); $i++) |
{ |
if($this->_worksheets[$i]->selected) { |
$this->_selected++; |
} |
$this->_worksheets[$i]->close($this->_sheetnames); |
} |
// Add Workbook globals |
$this->_storeBof(0x0005); |
$this->_storeExterns(); // For print area and repeat rows |
$this->_storeNames(); // For print area and repeat rows |
$this->_storeWindow1(); |
$this->_store1904(); |
$this->_storeAllFonts(); |
$this->_storeAllNumFormats(); |
$this->_storeAllXfs(); |
$this->_storeAllStyles(); |
$this->_storePalette(); |
$this->_calcSheetOffsets(); |
// Add BOUNDSHEET records |
for($i=0; $i < count($this->_worksheets); $i++) { |
$this->_storeBoundsheet($this->_worksheets[$i]->name,$this->_worksheets[$i]->offset); |
} |
// End Workbook globals |
$this->_storeEof(); |
// Store the workbook in an OLE container |
$this->_storeOLEFile(); |
} |
/** |
* Store the workbook in an OLE container if the total size of the workbook data |
* is less than ~ 7MB. |
* |
* @access private |
*/ |
function _storeOLEFile() |
{ |
$OLE = new Spreadsheet_Excel_Writer_OLEwriter($this->_filename); |
$this->_tmp_filename = $OLE->_tmp_filename; |
// Write Worksheet data if data <~ 7MB |
if ($OLE->setSize($this->_biffsize)) |
{ |
$OLE->writeHeader(); |
$OLE->write($this->_data); |
foreach($this->_worksheets as $sheet) |
{ |
while ($tmp = $sheet->getData()) { |
$OLE->write($tmp); |
} |
} |
} |
$OLE->close(); |
} |
/** |
* Calculate offsets for Worksheet BOF records. |
* |
* @access private |
*/ |
function _calcSheetOffsets() |
{ |
$BOF = 11; |
$EOF = 4; |
$offset = $this->_datasize; |
for($i=0; $i < count($this->_worksheets); $i++) { |
$offset += $BOF + strlen($this->_worksheets[$i]->name); |
} |
$offset += $EOF; |
for($i=0; $i < count($this->_worksheets); $i++) { |
$this->_worksheets[$i]->offset = $offset; |
$offset += $this->_worksheets[$i]->_datasize; |
} |
$this->_biffsize = $offset; |
} |
/** |
* Store the Excel FONT records. |
* |
* @access private |
*/ |
function _storeAllFonts() |
{ |
// tmp_format is added by the constructor. We use this to write the default XF's |
$format = $this->_tmp_format; |
$font = $format->getFont(); |
// Note: Fonts are 0-indexed. According to the SDK there is no index 4, |
// so the following fonts are 0, 1, 2, 3, 5 |
// |
for($i=1; $i <= 5; $i++){ |
$this->_append($font); |
} |
// Iterate through the XF objects and write a FONT record if it isn't the |
// same as the default FONT and if it hasn't already been used. |
// |
$fonts = array(); |
$index = 6; // The first user defined FONT |
$key = $format->getFontKey(); // The default font from _tmp_format |
$fonts[$key] = 0; // Index of the default font |
for($i=0; $i < count($this->_formats); $i++) { |
$key = $this->_formats[$i]->getFontKey(); |
if (isset($fonts[$key])) { |
// FONT has already been used |
$this->_formats[$i]->font_index = $fonts[$key]; |
} |
else { |
// Add a new FONT record |
$fonts[$key] = $index; |
$this->_formats[$i]->font_index = $index; |
$index++; |
$font = $this->_formats[$i]->getFont(); |
$this->_append($font); |
} |
} |
} |
/** |
* Store user defined numerical formats i.e. FORMAT records |
* |
* @access private |
*/ |
function _storeAllNumFormats() |
{ |
// Leaning num_format syndrome |
$hash_num_formats = array(); |
$num_formats = array(); |
$index = 164; |
// Iterate through the XF objects and write a FORMAT record if it isn't a |
// built-in format type and if the FORMAT string hasn't already been used. |
// |
for($i=0; $i < count($this->_formats); $i++) |
{ |
$num_format = $this->_formats[$i]->_num_format; |
// Check if $num_format is an index to a built-in format. |
// Also check for a string of zeros, which is a valid format string |
// but would evaluate to zero. |
// |
if (!preg_match("/^0+\d/",$num_format)) |
{ |
if (preg_match("/^\d+$/",$num_format)) { // built-in format |
continue; |
} |
} |
if (isset($hash_num_formats[$num_format])) { |
// FORMAT has already been used |
$this->_formats[$i]->_num_format = $hash_num_formats[$num_format]; |
} |
else{ |
// Add a new FORMAT |
$hash_num_formats[$num_format] = $index; |
$this->_formats[$i]->_num_format = $index; |
array_push($num_formats,$num_format); |
$index++; |
} |
} |
// Write the new FORMAT records starting from 0xA4 |
$index = 164; |
foreach ($num_formats as $num_format) { |
$this->_storeNumFormat($num_format,$index); |
$index++; |
} |
} |
/** |
* Write all XF records. |
* |
* @access private |
*/ |
function _storeAllXfs() |
{ |
// _tmp_format is added by the constructor. We use this to write the default XF's |
// The default font index is 0 |
// |
$format = $this->_tmp_format; |
for ($i=0; $i <= 14; $i++) { |
$xf = $format->getXf('style'); // Style XF |
$this->_append($xf); |
} |
$xf = $format->getXf('cell'); // Cell XF |
$this->_append($xf); |
// User defined XFs |
for($i=0; $i < count($this->_formats); $i++) { |
$xf = $this->_formats[$i]->getXf('cell'); |
$this->_append($xf); |
} |
} |
/** |
* Write all STYLE records. |
* |
* @access private |
*/ |
function _storeAllStyles() |
{ |
$this->_storeStyle(); |
} |
/** |
* Write the EXTERNCOUNT and EXTERNSHEET records. These are used as indexes for |
* the NAME records. |
* |
* @access private |
*/ |
function _storeExterns() |
{ |
// Create EXTERNCOUNT with number of worksheets |
$this->_storeExterncount(count($this->_worksheets)); |
// Create EXTERNSHEET for each worksheet |
foreach ($this->_sheetnames as $sheetname) { |
$this->_storeExternsheet($sheetname); |
} |
} |
/** |
* Write the NAME record to define the print area and the repeat rows and cols. |
* |
* @access private |
*/ |
function _storeNames() |
{ |
// Create the print area NAME records |
foreach ($this->_worksheets as $worksheet) { |
// Write a Name record if the print area has been defined |
if (isset($worksheet->print_rowmin)) |
{ |
$this->_storeNameShort( |
$worksheet->index, |
0x06, // NAME type |
$worksheet->print_rowmin, |
$worksheet->print_rowmax, |
$worksheet->print_colmin, |
$worksheet->print_colmax |
); |
} |
} |
// Create the print title NAME records |
foreach ($this->_worksheets as $worksheet) |
{ |
$rowmin = $worksheet->title_rowmin; |
$rowmax = $worksheet->title_rowmax; |
$colmin = $worksheet->title_colmin; |
$colmax = $worksheet->title_colmax; |
// Determine if row + col, row, col or nothing has been defined |
// and write the appropriate record |
// |
if (isset($rowmin) and isset($colmin)) { |
// Row and column titles have been defined. |
// Row title has been defined. |
$this->_storeNameLong( |
$worksheet->index, |
0x07, // NAME type |
$rowmin, |
$rowmax, |
$colmin, |
$colmax |
); |
} |
elseif (isset($rowmin)) { |
// Row title has been defined. |
$this->_storeNameShort( |
$worksheet->index, |
0x07, // NAME type |
$rowmin, |
$rowmax, |
0x00, |
0xff |
); |
} |
elseif (isset($colmin)) { |
// Column title has been defined. |
$this->_storeNameShort( |
$worksheet->index, |
0x07, // NAME type |
0x0000, |
0x3fff, |
$colmin, |
$colmax |
); |
} |
else { |
// Print title hasn't been defined. |
} |
} |
} |
/****************************************************************************** |
* |
* BIFF RECORDS |
* |
*/ |
/** |
* Write Excel BIFF WINDOW1 record. |
* |
* @access private |
*/ |
function _storeWindow1() |
{ |
$record = 0x003D; // Record identifier |
$length = 0x0012; // Number of bytes to follow |
$xWn = 0x0000; // Horizontal position of window |
$yWn = 0x0000; // Vertical position of window |
$dxWn = 0x25BC; // Width of window |
$dyWn = 0x1572; // Height of window |
$grbit = 0x0038; // Option flags |
$ctabsel = $this->_selected; // Number of workbook tabs selected |
$wTabRatio = 0x0258; // Tab to scrollbar ratio |
$itabFirst = $this->_firstsheet; // 1st displayed worksheet |
$itabCur = $this->_activesheet; // Active worksheet |
$header = pack("vv", $record, $length); |
$data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, |
$grbit, |
$itabCur, $itabFirst, |
$ctabsel, $wTabRatio); |
$this->_append($header.$data); |
} |
/** |
* Writes Excel BIFF BOUNDSHEET record. |
* |
* @param string $sheetname Worksheet name |
* @param integer $offset Location of worksheet BOF |
* @access private |
*/ |
function _storeBoundsheet($sheetname,$offset) |
{ |
$record = 0x0085; // Record identifier |
$length = 0x07 + strlen($sheetname); // Number of bytes to follow |
$grbit = 0x0000; // Sheet identifier |
$cch = strlen($sheetname); // Length of sheet name |
$header = pack("vv", $record, $length); |
$data = pack("VvC", $offset, $grbit, $cch); |
$this->_append($header.$data.$sheetname); |
} |
/** |
* Write Excel BIFF STYLE records. |
* |
* @access private |
*/ |
function _storeStyle() |
{ |
$record = 0x0293; // Record identifier |
$length = 0x0004; // Bytes to follow |
$ixfe = 0x8000; // Index to style XF |
$BuiltIn = 0x00; // Built-in style |
$iLevel = 0xff; // Outline style level |
$header = pack("vv", $record, $length); |
$data = pack("vCC", $ixfe, $BuiltIn, $iLevel); |
$this->_append($header.$data); |
} |
/** |
* Writes Excel FORMAT record for non "built-in" numerical formats. |
* |
* @param string $format Custom format string |
* @param integer $ifmt Format index code |
* @access private |
*/ |
function _storeNumFormat($format,$ifmt) |
{ |
$record = 0x041E; // Record identifier |
$length = 0x03 + strlen($format); // Number of bytes to follow |
$cch = strlen($format); // Length of format string |
$header = pack("vv", $record, $length); |
$data = pack("vC", $ifmt, $cch); |
$this->_append($header.$data.$format); |
} |
/** |
* Write Excel 1904 record to indicate the date system in use. |
* |
* @access private |
*/ |
function _store1904() |
{ |
$record = 0x0022; // Record identifier |
$length = 0x0002; // Bytes to follow |
$f1904 = $this->_1904; // Flag for 1904 date system |
$header = pack("vv", $record, $length); |
$data = pack("v", $f1904); |
$this->_append($header.$data); |
} |
/** |
* Write BIFF record EXTERNCOUNT to indicate the number of external sheet |
* references in the workbook. |
* |
* Excel only stores references to external sheets that are used in NAME. |
* The workbook NAME record is required to define the print area and the repeat |
* rows and columns. |
* |
* A similar method is used in Worksheet.php for a slightly different purpose. |
* |
* @param integer $cxals Number of external references |
* @access private |
*/ |
function _storeExterncount($cxals) |
{ |
$record = 0x0016; // Record identifier |
$length = 0x0002; // Number of bytes to follow |
$header = pack("vv", $record, $length); |
$data = pack("v", $cxals); |
$this->_append($header.$data); |
} |
/** |
* Writes the Excel BIFF EXTERNSHEET record. These references are used by |
* formulas. NAME record is required to define the print area and the repeat |
* rows and columns. |
* |
* A similar method is used in Worksheet.php for a slightly different purpose. |
* |
* @param string $sheetname Worksheet name |
* @access private |
*/ |
function _storeExternsheet($sheetname) |
{ |
$record = 0x0017; // Record identifier |
$length = 0x02 + strlen($sheetname); // Number of bytes to follow |
$cch = strlen($sheetname); // Length of sheet name |
$rgch = 0x03; // Filename encoding |
$header = pack("vv", $record, $length); |
$data = pack("CC", $cch, $rgch); |
$this->_append($header.$data.$sheetname); |
} |
/** |
* Store the NAME record in the short format that is used for storing the print |
* area, repeat rows only and repeat columns only. |
* |
* @param integer $index Sheet index |
* @param integer $type Built-in name type |
* @param integer $rowmin Start row |
* @param integer $rowmax End row |
* @param integer $colmin Start colum |
* @param integer $colmax End column |
* @access private |
*/ |
function _storeNameShort($index,$type,$rowmin,$rowmax,$colmin,$colmax) |
{ |
$record = 0x0018; // Record identifier |
$length = 0x0024; // Number of bytes to follow |
$grbit = 0x0020; // Option flags |
$chKey = 0x00; // Keyboard shortcut |
$cch = 0x01; // Length of text name |
$cce = 0x0015; // Length of text definition |
$ixals = $index + 1; // Sheet index |
$itab = $ixals; // Equal to ixals |
$cchCustMenu = 0x00; // Length of cust menu text |
$cchDescription = 0x00; // Length of description text |
$cchHelptopic = 0x00; // Length of help topic text |
$cchStatustext = 0x00; // Length of status bar text |
$rgch = $type; // Built-in name type |
$unknown03 = 0x3b; |
$unknown04 = 0xffff-$index; |
$unknown05 = 0x0000; |
$unknown06 = 0x0000; |
$unknown07 = 0x1087; |
$unknown08 = 0x8005; |
$header = pack("vv", $record, $length); |
$data = pack("v", $grbit); |
$data .= pack("C", $chKey); |
$data .= pack("C", $cch); |
$data .= pack("v", $cce); |
$data .= pack("v", $ixals); |
$data .= pack("v", $itab); |
$data .= pack("C", $cchCustMenu); |
$data .= pack("C", $cchDescription); |
$data .= pack("C", $cchHelptopic); |
$data .= pack("C", $cchStatustext); |
$data .= pack("C", $rgch); |
$data .= pack("C", $unknown03); |
$data .= pack("v", $unknown04); |
$data .= pack("v", $unknown05); |
$data .= pack("v", $unknown06); |
$data .= pack("v", $unknown07); |
$data .= pack("v", $unknown08); |
$data .= pack("v", $index); |
$data .= pack("v", $index); |
$data .= pack("v", $rowmin); |
$data .= pack("v", $rowmax); |
$data .= pack("C", $colmin); |
$data .= pack("C", $colmax); |
$this->_append($header.$data); |
} |
/** |
* Store the NAME record in the long format that is used for storing the repeat |
* rows and columns when both are specified. This shares a lot of code with |
* _storeNameShort() but we use a separate method to keep the code clean. |
* Code abstraction for reuse can be carried too far, and I should know. ;-) |
* |
* @param integer $index Sheet index |
* @param integer $type Built-in name type |
* @param integer $rowmin Start row |
* @param integer $rowmax End row |
* @param integer $colmin Start colum |
* @param integer $colmax End column |
* @access private |
*/ |
function _storeNameLong($index,$type,$rowmin,$rowmax,$colmin,$colmax) |
{ |
$record = 0x0018; // Record identifier |
$length = 0x003d; // Number of bytes to follow |
$grbit = 0x0020; // Option flags |
$chKey = 0x00; // Keyboard shortcut |
$cch = 0x01; // Length of text name |
$cce = 0x002e; // Length of text definition |
$ixals = $index + 1; // Sheet index |
$itab = $ixals; // Equal to ixals |
$cchCustMenu = 0x00; // Length of cust menu text |
$cchDescription = 0x00; // Length of description text |
$cchHelptopic = 0x00; // Length of help topic text |
$cchStatustext = 0x00; // Length of status bar text |
$rgch = $type; // Built-in name type |
$unknown01 = 0x29; |
$unknown02 = 0x002b; |
$unknown03 = 0x3b; |
$unknown04 = 0xffff-$index; |
$unknown05 = 0x0000; |
$unknown06 = 0x0000; |
$unknown07 = 0x1087; |
$unknown08 = 0x8008; |
$header = pack("vv", $record, $length); |
$data = pack("v", $grbit); |
$data .= pack("C", $chKey); |
$data .= pack("C", $cch); |
$data .= pack("v", $cce); |
$data .= pack("v", $ixals); |
$data .= pack("v", $itab); |
$data .= pack("C", $cchCustMenu); |
$data .= pack("C", $cchDescription); |
$data .= pack("C", $cchHelptopic); |
$data .= pack("C", $cchStatustext); |
$data .= pack("C", $rgch); |
$data .= pack("C", $unknown01); |
$data .= pack("v", $unknown02); |
// Column definition |
$data .= pack("C", $unknown03); |
$data .= pack("v", $unknown04); |
$data .= pack("v", $unknown05); |
$data .= pack("v", $unknown06); |
$data .= pack("v", $unknown07); |
$data .= pack("v", $unknown08); |
$data .= pack("v", $index); |
$data .= pack("v", $index); |
$data .= pack("v", 0x0000); |
$data .= pack("v", 0x3fff); |
$data .= pack("C", $colmin); |
$data .= pack("C", $colmax); |
// Row definition |
$data .= pack("C", $unknown03); |
$data .= pack("v", $unknown04); |
$data .= pack("v", $unknown05); |
$data .= pack("v", $unknown06); |
$data .= pack("v", $unknown07); |
$data .= pack("v", $unknown08); |
$data .= pack("v", $index); |
$data .= pack("v", $index); |
$data .= pack("v", $rowmin); |
$data .= pack("v", $rowmax); |
$data .= pack("C", 0x00); |
$data .= pack("C", 0xff); |
// End of data |
$data .= pack("C", 0x10); |
$this->_append($header.$data); |
} |
/** |
* Stores the PALETTE biff record. |
* |
* @access private |
*/ |
function _storePalette() |
{ |
$aref = $this->_palette; |
$record = 0x0092; // Record identifier |
$length = 2 + 4 * count($aref); // Number of bytes to follow |
$ccv = count($aref); // Number of RGB values to follow |
$data = ''; // The RGB data |
// Pack the RGB data |
foreach($aref as $color) |
{ |
foreach($color as $byte) { |
$data .= pack("C",$byte); |
} |
} |
$header = pack("vvv", $record, $length, $ccv); |
$this->_append($header.$data); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Spreadsheet/Excel/Writer/BIFFwriter.php |
---|
New file |
0,0 → 1,235 |
<?php |
/* |
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com> |
* |
* The majority of this is _NOT_ my code. I simply ported it from the |
* PERL Spreadsheet::WriteExcel module. |
* |
* The author of the Spreadsheet::WriteExcel module is John McNamara |
* <jmcnamara@cpan.org> |
* |
* I _DO_ maintain this code, and John McNamara has nothing to do with the |
* porting of this code to PHP. Any questions directly related to this |
* class library should be directed to me. |
* |
* License Information: |
* |
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets |
* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
* License as published by the Free Software Foundation; either |
* version 2.1 of the License, or (at your option) any later version. |
* |
* This library is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Lesser General Public License for more details. |
* |
* You should have received a copy of the GNU Lesser General Public |
* License along with this library; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
//require_once('PEAR.php'); |
/** |
* Class for writing Excel BIFF records. |
* |
* From "MICROSOFT EXCEL BINARY FILE FORMAT" by Mark O'Brien (Microsoft Corporation): |
* |
* BIFF (BInary File Format) is the file format in which Excel documents are |
* saved on disk. A BIFF file is a complete description of an Excel document. |
* BIFF files consist of sequences of variable-length records. There are many |
* different types of BIFF records. For example, one record type describes a |
* formula entered into a cell; one describes the size and location of a |
* window into a document; another describes a picture format. |
* |
* @author Xavier Noguer <xnoguer@rezebra.com> |
* @category FileFormats |
* @package Spreadsheet_Excel_Writer |
*/ |
class Spreadsheet_Excel_Writer_BIFFwriter extends PEAR |
{ |
/** |
* The BIFF/Excel version (5). |
* @var integer |
*/ |
var $_BIFF_version = 0x0500; |
/** |
* The byte order of this architecture. 0 => little endian, 1 => big endian |
* @var integer |
*/ |
var $_byte_order; |
/** |
* The string containing the data of the BIFF stream |
* @var string |
*/ |
var $_data; |
/** |
* The size of the data in bytes. Should be the same as strlen($this->_data) |
* @var integer |
*/ |
var $_datasize; |
/** |
* The maximun length for a BIFF record. See _addContinue() |
* @var integer |
* @see _addContinue() |
*/ |
var $_limit; |
/** |
* Constructor |
* |
* @access public |
*/ |
function Spreadsheet_Excel_Writer_BIFFwriter() |
{ |
$this->_byte_order = ''; |
$this->_data = ''; |
$this->_datasize = 0; |
$this->_limit = 2080; |
// Set the byte order |
$this->_setByteOrder(); |
} |
/** |
* Determine the byte order and store it as class data to avoid |
* recalculating it for each call to new(). |
* |
* @access private |
*/ |
function _setByteOrder() |
{ |
if ($this->_byte_order == '') |
{ |
// Check if "pack" gives the required IEEE 64bit float |
$teststr = pack("d", 1.2345); |
$number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F); |
if ($number == $teststr) { |
$byte_order = 0; // Little Endian |
} |
elseif ($number == strrev($teststr)){ |
$byte_order = 1; // Big Endian |
} |
else { |
// Give up. I'll fix this in a later version. |
$this->raiseError("Required floating point format not supported ". |
"on this platform."); |
} |
} |
$this->_byte_order = $byte_order; |
} |
/** |
* General storage function |
* |
* @param string $data binary data to prepend |
* @access private |
*/ |
function _prepend($data) |
{ |
if (strlen($data) > $this->_limit) { |
$data = $this->_addContinue($data); |
} |
$this->_data = $data.$this->_data; |
$this->_datasize += strlen($data); |
} |
/** |
* General storage function |
* |
* @param string $data binary data to append |
* @access private |
*/ |
function _append($data) |
{ |
if (strlen($data) > $this->_limit) { |
$data = $this->_addContinue($data); |
} |
$this->_data = $this->_data.$data; |
$this->_datasize += strlen($data); |
} |
/** |
* Writes Excel BOF record to indicate the beginning of a stream or |
* sub-stream in the BIFF file. |
* |
* @param integer $type type of BIFF file to write: 0x0005 Workbook, 0x0010 Worksheet. |
* @access private |
*/ |
function _storeBof($type) |
{ |
$record = 0x0809; // Record identifier |
$length = 0x0008; // Number of bytes to follow |
$version = $this->_BIFF_version; |
// According to the SDK $build and $year should be set to zero. |
// However, this throws a warning in Excel 5. So, use these |
// magic numbers. |
$build = 0x096C; |
$year = 0x07C9; |
$header = pack("vv", $record, $length); |
$data = pack("vvvv", $version, $type, $build, $year); |
$this->_prepend($header.$data); |
} |
/** |
* Writes Excel EOF record to indicate the end of a BIFF stream. |
* |
* @access private |
*/ |
function _storeEof() |
{ |
$record = 0x000A; // Record identifier |
$length = 0x0000; // Number of bytes to follow |
$header = pack("vv", $record, $length); |
$this->_append($header); |
} |
/** |
* Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In |
* Excel 97 the limit is 8228 bytes. Records that are longer than these limits |
* must be split up into CONTINUE blocks. |
* |
* This function takes a long BIFF record and inserts CONTINUE records as |
* necessary. |
* |
* @param string $data The original binary data to be written |
* @return string A very convenient string of continue blocks |
* @access private |
*/ |
function _addContinue($data) |
{ |
$limit = $this->_limit; |
$record = 0x003C; // Record identifier |
// The first 2080/8224 bytes remain intact. However, we have to change |
// the length field of the record. |
$tmp = substr($data, 0, 2).pack("v", $limit-4).substr($data, 4, $limit - 4); |
$header = pack("vv", $record, $limit); // Headers for continue records |
// Retrieve chunks of 2080/8224 bytes +4 for the header. |
for($i = $limit; $i < strlen($data) - $limit; $i += $limit) |
{ |
$tmp .= $header; |
$tmp .= substr($data, $i, $limit); |
} |
// Retrieve the last chunk of data |
$header = pack("vv", $record, strlen($data) - $i); |
$tmp .= $header; |
$tmp .= substr($data,$i,strlen($data) - $i); |
return($tmp); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Spreadsheet/Excel/Writer/Format.php |
---|
New file |
0,0 → 1,940 |
<?php |
/* |
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com> |
* |
* The majority of this is _NOT_ my code. I simply ported it from the |
* PERL Spreadsheet::WriteExcel module. |
* |
* The author of the Spreadsheet::WriteExcel module is John McNamara |
* <jmcnamara@cpan.org> |
* |
* I _DO_ maintain this code, and John McNamara has nothing to do with the |
* porting of this code to PHP. Any questions directly related to this |
* class library should be directed to me. |
* |
* License Information: |
* |
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets |
* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
* License as published by the Free Software Foundation; either |
* version 2.1 of the License, or (at your option) any later version. |
* |
* This library is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Lesser General Public License for more details. |
* |
* You should have received a copy of the GNU Lesser General Public |
* License along with this library; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
//require_once('PEAR.php'); |
/** |
* Class for generating Excel XF records (formats) |
* |
* @author Xavier Noguer <xnoguer@rezebra.com> |
* @category FileFormats |
* @package Spreadsheet_Excel_Writer |
*/ |
class Spreadsheet_Excel_Writer_Format extends PEAR |
{ |
/** |
* The index given by the workbook when creating a new format. |
* @var integer |
*/ |
var $_xf_index; |
/** |
* Index to the FONT record. |
* @var integer |
*/ |
var $font_index; |
/** |
* The font name (ASCII). |
* @var string |
*/ |
var $_font_name; |
/** |
* Height of font (1/20 of a point) |
* @var integer |
*/ |
var $_size; |
/** |
* Bold style |
* @var integer |
*/ |
var $_bold; |
/** |
* Bit specifiying if the font is italic. |
* @var integer |
*/ |
var $_italic; |
/** |
* Index to the cell's color |
* @var integer |
*/ |
var $_color; |
/** |
* The text underline property |
* @var integer |
*/ |
var $_underline; |
/** |
* Bit specifiying if the font has strikeout. |
* @var integer |
*/ |
var $_font_strikeout; |
/** |
* Bit specifiying if the font has outline. |
* @var integer |
*/ |
var $_font_outline; |
/** |
* Bit specifiying if the font has shadow. |
* @var integer |
*/ |
var $_font_shadow; |
/** |
* 2 bytes specifiying the script type for the font. |
* @var integer |
*/ |
var $_font_script; |
/** |
* Byte specifiying the font family. |
* @var integer |
*/ |
var $_font_family; |
/** |
* Byte specifiying the font charset. |
* @var integer |
*/ |
var $_font_charset; |
/** |
* An index (2 bytes) to a FORMAT record (number format). |
* @var integer |
*/ |
var $_num_format; |
/** |
* Bit specifying if formulas are hidden. |
* @var integer |
*/ |
var $_hidden; |
/** |
* Bit specifying if the cell is locked. |
* @var integer |
*/ |
var $_locked; |
/** |
* The three bits specifying the text horizontal alignment. |
* @var integer |
*/ |
var $_text_h_align; |
/** |
* Bit specifying if the text is wrapped at the right border. |
* @var integer |
*/ |
var $_text_wrap; |
/** |
* The three bits specifying the text vertical alignment. |
* @var integer |
*/ |
var $_text_v_align; |
/** |
* 1 bit, apparently not used. |
* @var integer |
*/ |
var $_text_justlast; |
/** |
* The two bits specifying the text rotation. |
* @var integer |
*/ |
var $_rotation; |
/** |
* The cell's foreground color. |
* @var integer |
*/ |
var $_fg_color; |
/** |
* The cell's background color. |
* @var integer |
*/ |
var $_bg_color; |
/** |
* The cell's background fill pattern. |
* @var integer |
*/ |
var $_pattern; |
/** |
* Style of the bottom border of the cell |
* @var integer |
*/ |
var $_bottom; |
/** |
* Color of the bottom border of the cell. |
* @var integer |
*/ |
var $_bottom_color; |
/** |
* Style of the top border of the cell |
* @var integer |
*/ |
var $_top; |
/** |
* Color of the top border of the cell. |
* @var integer |
*/ |
var $_top_color; |
/** |
* Style of the left border of the cell |
* @var integer |
*/ |
var $_left; |
/** |
* Color of the left border of the cell. |
* @var integer |
*/ |
var $_left_color; |
/** |
* Style of the right border of the cell |
* @var integer |
*/ |
var $_right; |
/** |
* Color of the right border of the cell. |
* @var integer |
*/ |
var $_right_color; |
/** |
* Constructor |
* |
* @access public |
* @param integer $index the XF index for the format. |
* @param array $properties array with properties to be set on initialization. |
*/ |
function Spreadsheet_Excel_Writer_Format($index = 0,$properties = array()) |
{ |
$this->_xf_index = $index; |
$this->font_index = 0; |
$this->_font_name = 'Arial'; |
$this->_size = 10; |
$this->_bold = 0x0190; |
$this->_italic = 0; |
$this->_color = 0x7FFF; |
$this->_underline = 0; |
$this->_font_strikeout = 0; |
$this->_font_outline = 0; |
$this->_font_shadow = 0; |
$this->_font_script = 0; |
$this->_font_family = 0; |
$this->_font_charset = 0; |
$this->_num_format = 0; |
$this->_hidden = 0; |
$this->_locked = 1; |
$this->_text_h_align = 0; |
$this->_text_wrap = 0; |
$this->_text_v_align = 2; |
$this->_text_justlast = 0; |
$this->_rotation = 0; |
$this->_fg_color = 0x40; |
$this->_bg_color = 0x41; |
$this->_pattern = 0; |
$this->_bottom = 0; |
$this->_top = 0; |
$this->_left = 0; |
$this->_right = 0; |
$this->_bottom_color = 0x40; |
$this->_top_color = 0x40; |
$this->_left_color = 0x40; |
$this->_right_color = 0x40; |
// Set properties passed to Spreadsheet_Excel_Writer_Workbook::addFormat() |
foreach($properties as $property => $value) |
{ |
if(method_exists($this,'set'.ucwords($property))) |
{ |
$method_name = 'set'.ucwords($property); |
$this->$method_name($value); |
} |
} |
} |
/** |
* Generate an Excel BIFF XF record (style or cell). |
* |
* @param string $style The type of the XF record ('style' or 'cell'). |
* @return string The XF record |
*/ |
function getXf($style) |
{ |
// Set the type of the XF record and some of the attributes. |
if ($style == "style") { |
$style = 0xFFF5; |
} |
else { |
$style = $this->_locked; |
$style |= $this->_hidden << 1; |
} |
// Flags to indicate if attributes have been set. |
$atr_num = ($this->_num_format != 0)?1:0; |
$atr_fnt = ($this->font_index != 0)?1:0; |
$atr_alc = ($this->_text_wrap)?1:0; |
$atr_bdr = ($this->_bottom || |
$this->_top || |
$this->_left || |
$this->_right)?1:0; |
$atr_pat = (($this->_fg_color != 0x40) || |
($this->_bg_color != 0x41) || |
$this->_pattern)?1:0; |
$atr_prot = 0; |
// Zero the default border colour if the border has not been set. |
if ($this->_bottom == 0) { |
$this->_bottom_color = 0; |
} |
if ($this->_top == 0) { |
$this->_top_color = 0; |
} |
if ($this->_right == 0) { |
$this->_right_color = 0; |
} |
if ($this->_left == 0) { |
$this->_left_color = 0; |
} |
$record = 0x00E0; // Record identifier |
$length = 0x0010; // Number of bytes to follow |
$ifnt = $this->font_index; // Index to FONT record |
$ifmt = $this->_num_format; // Index to FORMAT record |
$align = $this->_text_h_align; // Alignment |
$align |= $this->_text_wrap << 3; |
$align |= $this->_text_v_align << 4; |
$align |= $this->_text_justlast << 7; |
$align |= $this->_rotation << 8; |
$align |= $atr_num << 10; |
$align |= $atr_fnt << 11; |
$align |= $atr_alc << 12; |
$align |= $atr_bdr << 13; |
$align |= $atr_pat << 14; |
$align |= $atr_prot << 15; |
$icv = $this->_fg_color; // fg and bg pattern colors |
$icv |= $this->_bg_color << 7; |
$fill = $this->_pattern; // Fill and border line style |
$fill |= $this->_bottom << 6; |
$fill |= $this->_bottom_color << 9; |
$border1 = $this->_top; // Border line style and color |
$border1 |= $this->_left << 3; |
$border1 |= $this->_right << 6; |
$border1 |= $this->_top_color << 9; |
$border2 = $this->_left_color; // Border color |
$border2 |= $this->_right_color << 7; |
$header = pack("vv", $record, $length); |
$data = pack("vvvvvvvv", $ifnt, $ifmt, $style, $align, |
$icv, $fill, |
$border1, $border2); |
return($header.$data); |
} |
/** |
* Generate an Excel BIFF FONT record. |
* |
* @return string The FONT record |
*/ |
function getFont() |
{ |
$dyHeight = $this->_size * 20; // Height of font (1/20 of a point) |
$icv = $this->_color; // Index to color palette |
$bls = $this->_bold; // Bold style |
$sss = $this->_font_script; // Superscript/subscript |
$uls = $this->_underline; // Underline |
$bFamily = $this->_font_family; // Font family |
$bCharSet = $this->_font_charset; // Character set |
$rgch = $this->_font_name; // Font name |
$cch = strlen($rgch); // Length of font name |
$record = 0x31; // Record identifier |
$length = 0x0F + $cch; // Record length |
$reserved = 0x00; // Reserved |
$grbit = 0x00; // Font attributes |
if ($this->_italic) { |
$grbit |= 0x02; |
} |
if ($this->_font_strikeout) { |
$grbit |= 0x08; |
} |
if ($this->_font_outline) { |
$grbit |= 0x10; |
} |
if ($this->_font_shadow) { |
$grbit |= 0x20; |
} |
$header = pack("vv", $record, $length); |
$data = pack("vvvvvCCCCC", $dyHeight, $grbit, $icv, $bls, |
$sss, $uls, $bFamily, |
$bCharSet, $reserved, $cch); |
return($header . $data. $this->_font_name); |
} |
/** |
* Returns a unique hash key for a font. |
* Used by Spreadsheet_Excel_Writer_Workbook::_storeAllFonts() |
* |
* The elements that form the key are arranged to increase the probability of |
* generating a unique key. Elements that hold a large range of numbers |
* (eg. _color) are placed between two binary elements such as _italic |
* |
* @return string A key for this font |
*/ |
function getFontKey() |
{ |
$key = "$this->_font_name$this->_size"; |
$key .= "$this->_font_script$this->_underline"; |
$key .= "$this->_font_strikeout$this->_bold$this->_font_outline"; |
$key .= "$this->_font_family$this->_font_charset"; |
$key .= "$this->_font_shadow$this->_color$this->_italic"; |
$key = str_replace(" ","_",$key); |
return ($key); |
} |
/** |
* Returns the index used by Spreadsheet_Excel_Writer_Worksheet::_XF() |
* |
* @return integer The index for the XF record |
*/ |
function getXfIndex() |
{ |
return($this->_xf_index); |
} |
/** |
* Used in conjunction with the set_xxx_color methods to convert a color |
* string into a number. Color range is 0..63 but we will restrict it |
* to 8..63 to comply with Gnumeric. Colors 0..7 are repeated in 8..15. |
* |
* @access private |
* @param string $name_color name of the color (i.e.: 'blue', 'red', etc..). Optional. |
* @return integer The color index |
*/ |
function _getColor($name_color = '') |
{ |
$colors = array( |
'aqua' => 0x0F, |
'cyan' => 0x0F, |
'black' => 0x08, |
'blue' => 0x0C, |
'brown' => 0x10, |
'magenta' => 0x0E, |
'fuchsia' => 0x0E, |
'gray' => 0x17, |
'grey' => 0x17, |
'green' => 0x11, |
'lime' => 0x0B, |
'navy' => 0x12, |
'orange' => 0x35, |
'purple' => 0x14, |
'red' => 0x0A, |
'silver' => 0x16, |
'white' => 0x09, |
'yellow' => 0x0D |
); |
// Return the default color, 0x7FFF, if undef, |
if($name_color == '') { |
return(0x7FFF); |
} |
// or the color string converted to an integer, |
if(isset($colors[$name_color])) { |
return($colors[$name_color]); |
} |
// or the default color if string is unrecognised, |
if(preg_match("/\D/",$name_color)) { |
return(0x7FFF); |
} |
// or an index < 8 mapped into the correct range, |
if($name_color < 8) { |
return($name_color + 8); |
} |
// or the default color if arg is outside range, |
if($name_color > 63) { |
return(0x7FFF); |
} |
// or an integer in the valid range |
return($name_color); |
} |
/** |
* Set cell alignment. |
* |
* @access public |
* @param string $location alignment for the cell ('left', 'right', etc...). |
*/ |
function setAlign($location) |
{ |
if (preg_match("/\d/",$location)) { |
return; // Ignore numbers |
} |
$location = strtolower($location); |
if ($location == 'left') { |
$this->_text_h_align = 1; |
} |
if ($location == 'centre') { |
$this->_text_h_align = 2; |
} |
if ($location == 'center') { |
$this->_text_h_align = 2; |
} |
if ($location == 'right') { |
$this->_text_h_align = 3; |
} |
if ($location == 'fill') { |
$this->_text_h_align = 4; |
} |
if ($location == 'justify') { |
$this->_text_h_align = 5; |
} |
if ($location == 'merge') { |
$this->_text_h_align = 6; |
} |
if ($location == 'equal_space') { // For T.K. |
$this->_text_h_align = 7; |
} |
if ($location == 'top') { |
$this->_text_v_align = 0; |
} |
if ($location == 'vcentre') { |
$this->_text_v_align = 1; |
} |
if ($location == 'vcenter') { |
$this->_text_v_align = 1; |
} |
if ($location == 'bottom') { |
$this->_text_v_align = 2; |
} |
if ($location == 'vjustify') { |
$this->_text_v_align = 3; |
} |
if ($location == 'vequal_space') { // For T.K. |
$this->_text_v_align = 4; |
} |
} |
/** |
* This is an alias for the unintuitive setAlign('merge') |
* |
* @access public |
*/ |
function setMerge() |
{ |
$this->setAlign('merge'); |
} |
/** |
* Sets the boldness of the text. |
* Bold has a range 100..1000. |
* 0 (400) is normal. 1 (700) is bold. |
* |
* @access public |
* @param integer $weight Weight for the text, 0 maps to 400 (normal text), |
1 maps to 700 (bold text). Valid range is: 100-1000. |
It's Optional, default is 1 (bold). |
*/ |
function setBold($weight = 1) |
{ |
if($weight == 1) { |
$weight = 0x2BC; // Bold text |
} |
if($weight == 0) { |
$weight = 0x190; // Normal text |
} |
if($weight < 0x064) { |
$weight = 0x190; // Lower bound |
} |
if($weight > 0x3E8) { |
$weight = 0x190; // Upper bound |
} |
$this->_bold = $weight; |
} |
/************************************ |
* FUNCTIONS FOR SETTING CELLS BORDERS |
*/ |
/** |
* Sets the width for the bottom border of the cell |
* |
* @access public |
* @param integer $style style of the cell border. 1 => thin, 2 => thick. |
*/ |
function setBottom($style) |
{ |
$this->_bottom = $style; |
} |
/** |
* Sets the width for the top border of the cell |
* |
* @access public |
* @param integer $style style of the cell top border. 1 => thin, 2 => thick. |
*/ |
function setTop($style) |
{ |
$this->_top = $style; |
} |
/** |
* Sets the width for the left border of the cell |
* |
* @access public |
* @param integer $style style of the cell left border. 1 => thin, 2 => thick. |
*/ |
function setLeft($style) |
{ |
$this->_left = $style; |
} |
/** |
* Sets the width for the right border of the cell |
* |
* @access public |
* @param integer $style style of the cell right border. 1 => thin, 2 => thick. |
*/ |
function setRight($style) |
{ |
$this->_right = $style; |
} |
/** |
* Set cells borders to the same style |
* |
* @access public |
* @param integer $style style to apply for all cell borders. 1 => thin, 2 => thick. |
*/ |
function setBorder($style) |
{ |
$this->setBottom($style); |
$this->setTop($style); |
$this->setLeft($style); |
$this->setRight($style); |
} |
/******************************************* |
* FUNCTIONS FOR SETTING CELLS BORDERS COLORS |
*/ |
/** |
* Sets all the cell's borders to the same color |
* |
* @access public |
* @param mixed $color The color we are setting. Either a string (like 'blue'), |
* or an integer (range is [8...63]). |
*/ |
function setBorderColor($color) |
{ |
$this->setBottomColor($color); |
$this->setTopColor($color); |
$this->setLeftColor($color); |
$this->setRightColor($color); |
} |
/** |
* Sets the cell's bottom border color |
* |
* @access public |
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). |
*/ |
function setBottomColor($color) |
{ |
$value = $this->_getColor($color); |
$this->_bottom_color = $value; |
} |
/** |
* Sets the cell's top border color |
* |
* @access public |
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). |
*/ |
function setTopColor($color) |
{ |
$value = $this->_getColor($color); |
$this->_top_color = $value; |
} |
/** |
* Sets the cell's left border color |
* |
* @access public |
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). |
*/ |
function setLeftColor($color) |
{ |
$value = $this->_getColor($color); |
$this->_left_color = $value; |
} |
/** |
* Sets the cell's right border color |
* |
* @access public |
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). |
*/ |
function setRightColor($color) |
{ |
$value = $this->_getColor($color); |
$this->_right_color = $value; |
} |
/** |
* Sets the cell's foreground color |
* |
* @access public |
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). |
*/ |
function setFgColor($color) |
{ |
$value = $this->_getColor($color); |
$this->_fg_color = $value; |
} |
/** |
* Sets the cell's background color |
* |
* @access public |
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). |
*/ |
function setBgColor($color) |
{ |
$value = $this->_getColor($color); |
$this->_bg_color = $value; |
} |
/** |
* Sets the cell's color |
* |
* @access public |
* @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). |
*/ |
function setColor($color) |
{ |
$value = $this->_getColor($color); |
$this->_color = $value; |
} |
/** |
* Sets the fill pattern attribute of a cell |
* |
* @access public |
* @param integer $arg Optional. Defaults to 1. Meaningful values are: 0-18, |
* 0 meaning no background. |
*/ |
function setPattern($arg = 1) |
{ |
$this->_pattern = $arg; |
} |
/** |
* Sets the underline of the text |
* |
* @access public |
* @param integer $underline The value for underline. Possible values are: |
* 1 => underline, 2 => double underline. |
*/ |
function setUnderline($underline) |
{ |
$this->_underline = $underline; |
} |
/** |
* Sets the font style as italic |
* |
* @access public |
*/ |
function setItalic() |
{ |
$this->_italic = 1; |
} |
/** |
* Sets the font size |
* |
* @access public |
* @param integer $size The font size (in pixels I think). |
*/ |
function setSize($size) |
{ |
$this->_size = $size; |
} |
/** |
* Sets text wrapping |
* |
* @access public |
*/ |
function setTextWrap() |
{ |
$this->_text_wrap = 1; |
} |
/** |
* Sets the orientation of the text |
* |
* @access public |
* @param integer $angle The rotation angle for the text (clockwise). Possible |
values are: 0, 90, 270 and -1 for stacking top-to-bottom. |
*/ |
function setTextRotation($angle) |
{ |
switch ($angle) |
{ |
case 0: |
$this->_rotation = 0; |
break; |
case 90: |
$this->_rotation = 3; |
break; |
case 270: |
$this->_rotation = 2; |
break; |
case -1: |
$this->_rotation = 1; |
break; |
default : |
$this->raiseError("Invalid value for angle.". |
" Possible values are: 0, 90, 270 and -1 ". |
"for stacking top-to-bottom."); |
$this->_rotation = 0; |
break; |
} |
} |
/** |
* Sets the numeric format. |
* It can be date, time, currency, etc... |
* |
* @access public |
* @param integer $num_format The numeric format. |
*/ |
function setNumFormat($num_format) |
{ |
$this->_num_format = $num_format; |
} |
/** |
* Sets font as strikeout. |
* |
* @access public |
*/ |
function setStrikeOut() |
{ |
$this->_font_strikeout = 1; |
} |
/** |
* Sets outlining for a font. |
* |
* @access public |
*/ |
function setOutLine() |
{ |
$this->_font_outline = 1; |
} |
/** |
* Sets font as shadow. |
* |
* @access public |
*/ |
function setShadow() |
{ |
$this->_font_shadow = 1; |
} |
/** |
* Sets the script type of the text |
* |
* @access public |
* @param integer $script The value for script type. Possible values are: |
* 1 => superscript, 2 => subscript. |
*/ |
function setScript($script) |
{ |
$this->_font_script = $script; |
} |
/** |
* Unlocks a cell. Useful for unprotecting particular cells of a protected sheet. |
* |
* @access public |
*/ |
function setUnLocked() |
{ |
$this->_locked = 0; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Spreadsheet/Excel/Writer/Worksheet.php |
---|
New file |
0,0 → 1,3095 |
<?php |
/* |
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com> |
* |
* The majority of this is _NOT_ my code. I simply ported it from the |
* PERL Spreadsheet::WriteExcel module. |
* |
* The author of the Spreadsheet::WriteExcel module is John McNamara |
* <jmcnamara@cpan.org> |
* |
* I _DO_ maintain this code, and John McNamara has nothing to do with the |
* porting of this code to PHP. Any questions directly related to this |
* class library should be directed to me. |
* |
* License Information: |
* |
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets |
* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
* License as published by the Free Software Foundation; either |
* version 2.1 of the License, or (at your option) any later version. |
* |
* This library is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Lesser General Public License for more details. |
* |
* You should have received a copy of the GNU Lesser General Public |
* License along with this library; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
require_once('Parser.php'); |
require_once('BIFFwriter.php'); |
/** |
* Class for generating Excel Spreadsheets |
* |
* @author Xavier Noguer <xnoguer@rezebra.com> |
* @category FileFormats |
* @package Spreadsheet_Excel_Writer |
*/ |
class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwriter |
{ |
/** |
* Name of the Worksheet |
* @var string |
*/ |
var $name; |
/** |
* Index for the Worksheet |
* @var integer |
*/ |
var $index; |
/** |
* Reference to the (default) Format object for URLs |
* @var object Format |
*/ |
var $_url_format; |
/** |
* Reference to the parser used for parsing formulas |
* @var object Format |
*/ |
var $_parser; |
/** |
* Filehandle to the temporary file for storing data |
* @var resource |
*/ |
var $_filehandle; |
/** |
* Boolean indicating if we are using a temporary file for storing data |
* @var bool |
*/ |
var $_using_tmpfile; |
/** |
* Maximum number of rows for an Excel spreadsheet (BIFF5) |
* @var integer |
*/ |
var $_xls_rowmax; |
/** |
* Maximum number of columns for an Excel spreadsheet (BIFF5) |
* @var integer |
*/ |
var $_xls_colmax; |
/** |
* Maximum number of characters for a string (LABEL record in BIFF5) |
* @var integer |
*/ |
var $_xls_strmax; |
/** |
* First row for the DIMENSIONS record |
* @var integer |
* @see storeDimensions() |
*/ |
var $_dim_rowmin; |
/** |
* Last row for the DIMENSIONS record |
* @var integer |
* @see storeDimensions() |
*/ |
var $_dim_rowmax; |
/** |
* First column for the DIMENSIONS record |
* @var integer |
* @see storeDimensions() |
*/ |
var $_dim_colmin; |
/** |
* Last column for the DIMENSIONS record |
* @var integer |
* @see storeDimensions() |
*/ |
var $_dim_colmax; |
/** |
* Array containing format information for columns |
* @var array |
*/ |
var $_colinfo; |
/** |
* Array containing the selected area for the worksheet |
* @var array |
*/ |
var $_selection; |
/** |
* Array containing the panes for the worksheet |
* @var array |
*/ |
var $_panes; |
/** |
* The active pane for the worksheet |
* @var integer |
*/ |
var $_active_pane; |
/** |
* Bit specifying if panes are frozen |
* @var integer |
*/ |
var $_frozen; |
/** |
* Bit specifying if the worksheet is selected |
* @var integer |
*/ |
var $selected; |
/** |
* The paper size (for printing) (DOCUMENT!!!) |
* @var integer |
*/ |
var $_paper_size; |
/** |
* Bit specifying paper orientation (for printing). 0 => landscape, 1 => portrait |
* @var integer |
*/ |
var $_orientation; |
/** |
* The page header caption |
* @var string |
*/ |
var $_header; |
/** |
* The page footer caption |
* @var string |
*/ |
var $_footer; |
/** |
* The horizontal centering value for the page |
* @var integer |
*/ |
var $_hcenter; |
/** |
* The vertical centering value for the page |
* @var integer |
*/ |
var $_vcenter; |
/** |
* The margin for the header |
* @var float |
*/ |
var $_margin_head; |
/** |
* The margin for the footer |
* @var float |
*/ |
var $_margin_foot; |
/** |
* The left margin for the worksheet in inches |
* @var float |
*/ |
var $_margin_left; |
/** |
* The right margin for the worksheet in inches |
* @var float |
*/ |
var $_margin_right; |
/** |
* The top margin for the worksheet in inches |
* @var float |
*/ |
var $_margin_top; |
/** |
* The bottom margin for the worksheet in inches |
* @var float |
*/ |
var $_margin_bottom; |
/** |
* First row to reapeat on each printed page |
* @var integer |
*/ |
var $title_rowmin; |
/** |
* Last row to reapeat on each printed page |
* @var integer |
*/ |
var $title_rowmax; |
/** |
* First column to reapeat on each printed page |
* @var integer |
*/ |
var $title_colmin; |
/** |
* First row of the area to print |
* @var integer |
*/ |
var $print_rowmin; |
/** |
* Last row to of the area to print |
* @var integer |
*/ |
var $print_rowmax; |
/** |
* First column of the area to print |
* @var integer |
*/ |
var $print_colmin; |
/** |
* Last column of the area to print |
* @var integer |
*/ |
var $print_colmax; |
/** |
* Constructor |
* |
* @param string $name The name of the new worksheet |
* @param integer $index The index of the new worksheet |
* @param mixed &$activesheet The current activesheet of the workbook we belong to |
* @param mixed &$firstsheet The first worksheet in the workbook we belong to |
* @param mixed &$url_format The default format for hyperlinks |
* @param mixed &$parser The formula parser created for the Workbook |
*/ |
function Spreadsheet_Excel_Writer_Worksheet($name, $index, &$activesheet, |
&$firstsheet, &$url_format, |
&$parser) |
{ |
// It needs to call its parent's constructor explicitly |
$this->Spreadsheet_Excel_Writer_BIFFwriter(); |
$rowmax = 65536; // 16384 in Excel 5 |
$colmax = 256; |
$this->name = $name; |
$this->index = $index; |
$this->activesheet = &$activesheet; |
$this->firstsheet = &$firstsheet; |
$this->_url_format = &$url_format; |
$this->_parser = &$parser; |
//$this->ext_sheets = array(); |
$this->_filehandle = ""; |
$this->_using_tmpfile = true; |
//$this->fileclosed = 0; |
//$this->offset = 0; |
$this->_xls_rowmax = $rowmax; |
$this->_xls_colmax = $colmax; |
$this->_xls_strmax = 255; |
$this->_dim_rowmin = $rowmax + 1; |
$this->_dim_rowmax = 0; |
$this->_dim_colmin = $colmax + 1; |
$this->_dim_colmax = 0; |
$this->_colinfo = array(); |
$this->_selection = array(0,0,0,0); |
$this->_panes = array(); |
$this->_active_pane = 3; |
$this->_frozen = 0; |
$this->selected = 0; |
$this->_paper_size = 0x0; |
$this->_orientation = 0x1; |
$this->_header = ''; |
$this->_footer = ''; |
$this->_hcenter = 0; |
$this->_vcenter = 0; |
$this->_margin_head = 0.50; |
$this->_margin_foot = 0.50; |
$this->_margin_left = 0.75; |
$this->_margin_right = 0.75; |
$this->_margin_top = 1.00; |
$this->_margin_bottom = 1.00; |
$this->title_rowmin = NULL; |
$this->title_rowmax = NULL; |
$this->title_colmin = NULL; |
$this->title_colmax = NULL; |
$this->print_rowmin = NULL; |
$this->print_rowmax = NULL; |
$this->print_colmin = NULL; |
$this->print_colmax = NULL; |
$this->_print_gridlines = 1; |
$this->_print_headers = 0; |
$this->_fit_page = 0; |
$this->_fit_width = 0; |
$this->_fit_height = 0; |
$this->_hbreaks = array(); |
$this->_vbreaks = array(); |
$this->_protect = 0; |
$this->_password = NULL; |
$this->col_sizes = array(); |
$this->row_sizes = array(); |
$this->_zoom = 100; |
$this->_print_scale = 100; |
$this->_initialize(); |
} |
/** |
* Open a tmp file to store the majority of the Worksheet data. If this fails, |
* for example due to write permissions, store the data in memory. This can be |
* slow for large files. |
* |
* @access private |
*/ |
function _initialize() |
{ |
// Open tmp file for storing Worksheet data |
$fh = tmpfile(); |
if ( $fh) { |
// Store filehandle |
$this->_filehandle = $fh; |
} |
else { |
// If tmpfile() fails store data in memory |
$this->_using_tmpfile = false; |
} |
} |
/** |
* Add data to the beginning of the workbook (note the reverse order) |
* and to the end of the workbook. |
* |
* @access public |
* @see Spreadsheet_Excel_Writer_Workbook::storeWorkbook() |
* @param array $sheetnames The array of sheetnames from the Workbook this |
* worksheet belongs to |
*/ |
function close($sheetnames) |
{ |
$num_sheets = count($sheetnames); |
/*********************************************** |
* Prepend in reverse order!! |
*/ |
// Prepend the sheet dimensions |
$this->storeDimensions(); |
// Prepend the sheet password |
$this->_storePassword(); |
// Prepend the sheet protection |
$this->_storeProtect(); |
// Prepend the page setup |
$this->_storeSetup(); |
// Prepend the bottom margin |
$this->_storeMarginBottom(); |
// Prepend the top margin |
$this->_storeMarginTop(); |
// Prepend the right margin |
$this->_storeMarginRight(); |
// Prepend the left margin |
$this->_storeMarginLeft(); |
// Prepend the page vertical centering |
$this->_storeVcenter(); |
// Prepend the page horizontal centering |
$this->_storeHcenter(); |
// Prepend the page footer |
$this->_storeFooter(); |
// Prepend the page header |
$this->_storeHeader(); |
// Prepend the vertical page breaks |
$this->_storeVbreak(); |
// Prepend the horizontal page breaks |
$this->_storeHbreak(); |
// Prepend WSBOOL |
$this->_storeWsbool(); |
// Prepend GRIDSET |
$this->_storeGridset(); |
// Prepend PRINTGRIDLINES |
$this->_storePrintGridlines(); |
// Prepend PRINTHEADERS |
$this->_storePrintHeaders(); |
// Prepend EXTERNSHEET references |
for ($i = $num_sheets; $i > 0; $i--) |
{ |
$sheetname = $sheetnames[$i-1]; |
$this->_storeExternsheet($sheetname); |
} |
// Prepend the EXTERNCOUNT of external references. |
$this->_storeExterncount($num_sheets); |
// Prepend the COLINFO records if they exist |
if (!empty($this->_colinfo)) |
{ |
for($i=0; $i < count($this->_colinfo); $i++) { |
$this->_storeColinfo($this->_colinfo[$i]); |
} |
$this->_storeDefcol(); |
} |
// Prepend the BOF record |
$this->_storeBof(0x0010); |
/* |
* End of prepend. Read upwards from here. |
***********************************************/ |
// Append |
$this->_storeWindow2(); |
$this->_storeZoom(); |
if (!empty($this->_panes)) { |
$this->_storePanes($this->_panes); |
} |
$this->_storeSelection($this->_selection); |
$this->_storeEof(); |
} |
/** |
* Retrieve the worksheet name. |
* This is usefull when creating worksheets without a name. |
* |
* @access public |
* @return string The worksheet's name |
*/ |
function getName() |
{ |
return $this->name; |
} |
/** |
* Retrieves data from memory in one chunk, or from disk in $buffer |
* sized chunks. |
* |
* @return string The data |
*/ |
function getData() |
{ |
$buffer = 4096; |
// Return data stored in memory |
if (isset($this->_data)) |
{ |
$tmp = $this->_data; |
unset($this->_data); |
$fh = $this->_filehandle; |
if ($this->_using_tmpfile) { |
fseek($fh, 0); |
} |
return($tmp); |
} |
// Return data stored on disk |
if ($this->_using_tmpfile) |
{ |
if ($tmp = fread($this->_filehandle, $buffer)) { |
return($tmp); |
} |
} |
// No data to return |
return(''); |
} |
/** |
* Set this worksheet as a selected worksheet, |
* i.e. the worksheet has its tab highlighted. |
* |
* @access public |
*/ |
function select() |
{ |
$this->selected = 1; |
} |
/** |
* Set this worksheet as the active worksheet, |
* i.e. the worksheet that is displayed when the workbook is opened. |
* Also set it as selected. |
* |
* @access public |
*/ |
function activate() |
{ |
$this->selected = 1; |
$this->activesheet = $this->index; |
} |
/** |
* Set this worksheet as the first visible sheet. |
* This is necessary when there are a large number of worksheets and the |
* activated worksheet is not visible on the screen. |
* |
* @access public |
*/ |
function setFirstSheet() |
{ |
$this->firstsheet = $this->index; |
} |
/** |
* Set the worksheet protection flag |
* to prevent accidental modification and to |
* hide formulas if the locked and hidden format properties have been set. |
* |
* @access public |
* @param string $password The password to use for protecting the sheet. |
*/ |
function protect($password) |
{ |
$this->_protect = 1; |
$this->_password = $this->_encodePassword($password); |
} |
/** |
* Set the width of a single column or a range of columns. |
* |
* @access public |
* @param integer $firstcol first column on the range |
* @param integer $lastcol last column on the range |
* @param integer $width width to set |
* @param mixed $format The optional XF format to apply to the columns |
* @param integer $hidden The optional hidden atribute |
*/ |
function setColumn($firstcol, $lastcol, $width, $format = 0, $hidden = 0) |
{ |
$this->_colinfo[] = array($firstcol, $lastcol, $width, &$format, $hidden); |
// Set width to zero if column is hidden |
$width = ($hidden) ? 0 : $width; |
for($col = $firstcol; $col <= $lastcol; $col++) { |
$this->col_sizes[$col] = $width; |
} |
} |
/** |
* Set which cell or cells are selected in a worksheet |
* |
* @access public |
* @param integer $first_row first row in the selected quadrant |
* @param integer $first_column first column in the selected quadrant |
* @param integer $last_row last row in the selected quadrant |
* @param integer $last_column last column in the selected quadrant |
*/ |
function setSelection($first_row,$first_column,$last_row,$last_column) |
{ |
$this->_selection = array($first_row,$first_column,$last_row,$last_column); |
} |
/** |
* Set panes and mark them as frozen. |
* |
* @access public |
* @param array $panes This is the only parameter received and is composed of the following: |
* 0 => Vertical split position, |
* 1 => Horizontal split position |
* 2 => Top row visible |
* 3 => Leftmost column visible |
* 4 => Active pane |
*/ |
function freezePanes($panes) |
{ |
$this->_frozen = 1; |
$this->_panes = $panes; |
} |
/** |
* Set panes and mark them as unfrozen. |
* |
* @access public |
* @param array $panes This is the only parameter received and is composed of the following: |
* 0 => Vertical split position, |
* 1 => Horizontal split position |
* 2 => Top row visible |
* 3 => Leftmost column visible |
* 4 => Active pane |
*/ |
function thawPanes($panes) |
{ |
$this->_frozen = 0; |
$this->_panes = $panes; |
} |
/** |
* Set the page orientation as portrait. |
* |
* @access public |
*/ |
function setPortrait() |
{ |
$this->_orientation = 1; |
} |
/** |
* Set the page orientation as landscape. |
* |
* @access public |
*/ |
function setLandscape() |
{ |
$this->_orientation = 0; |
} |
/** |
* Set the paper type. Ex. 1 = US Letter, 9 = A4 |
* |
* @access public |
* @param integer $size The type of paper size to use |
*/ |
function setPaper($size = 0) |
{ |
$this->_paper_size = $size; |
} |
/** |
* Set the page header caption and optional margin. |
* |
* @access public |
* @param string $string The header text |
* @param float $margin optional head margin in inches. |
*/ |
function setHeader($string,$margin = 0.50) |
{ |
if (strlen($string) >= 255) { |
//carp 'Header string must be less than 255 characters'; |
return; |
} |
$this->_header = $string; |
$this->_margin_head = $margin; |
} |
/** |
* Set the page footer caption and optional margin. |
* |
* @access public |
* @param string $string The footer text |
* @param float $margin optional foot margin in inches. |
*/ |
function setFooter($string,$margin = 0.50) |
{ |
if (strlen($string) >= 255) { |
//carp 'Footer string must be less than 255 characters'; |
return; |
} |
$this->_footer = $string; |
$this->_margin_foot = $margin; |
} |
/** |
* Center the page horinzontally. |
* |
* @access public |
* @param integer $center the optional value for centering. Defaults to 1 (center). |
*/ |
function centerHorizontally($center = 1) |
{ |
$this->_hcenter = $center; |
} |
/** |
* Center the page vertically. |
* |
* @access public |
* @param integer $center the optional value for centering. Defaults to 1 (center). |
*/ |
function centerVertically($center = 1) |
{ |
$this->_vcenter = $center; |
} |
/** |
* Set all the page margins to the same value in inches. |
* |
* @access public |
* @param float $margin The margin to set in inches |
*/ |
function setMargins($margin) |
{ |
$this->setMarginLeft($margin); |
$this->setMarginRight($margin); |
$this->setMarginTop($margin); |
$this->setMarginBottom($margin); |
} |
/** |
* Set the left and right margins to the same value in inches. |
* |
* @access public |
* @param float $margin The margin to set in inches |
*/ |
function setMargins_LR($margin) |
{ |
$this->setMarginLeft($margin); |
$this->setMarginRight($margin); |
} |
/** |
* Set the top and bottom margins to the same value in inches. |
* |
* @access public |
* @param float $margin The margin to set in inches |
*/ |
function setMargins_TB($margin) |
{ |
$this->setMarginTop($margin); |
$this->setMarginBottom($margin); |
} |
/** |
* Set the left margin in inches. |
* |
* @access public |
* @param float $margin The margin to set in inches |
*/ |
function setMarginLeft($margin = 0.75) |
{ |
$this->_margin_left = $margin; |
} |
/** |
* Set the right margin in inches. |
* |
* @access public |
* @param float $margin The margin to set in inches |
*/ |
function setMarginRight($margin = 0.75) |
{ |
$this->_margin_right = $margin; |
} |
/** |
* Set the top margin in inches. |
* |
* @access public |
* @param float $margin The margin to set in inches |
*/ |
function setMarginTop($margin = 1.00) |
{ |
$this->_margin_top = $margin; |
} |
/** |
* Set the bottom margin in inches. |
* |
* @access public |
* @param float $margin The margin to set in inches |
*/ |
function setMarginBottom($margin = 1.00) |
{ |
$this->_margin_bottom = $margin; |
} |
/** |
* Set the rows to repeat at the top of each printed page. |
* |
* @access public |
* @param integer $first_row First row to repeat |
* @param integer $last_row Last row to repeat. Optional. |
*/ |
function repeatRows($first_row, $last_row = NULL) |
{ |
$this->title_rowmin = $first_row; |
if (isset($last_row)) { //Second row is optional |
$this->title_rowmax = $last_row; |
} |
else { |
$this->title_rowmax = $first_row; |
} |
} |
/** |
* Set the columns to repeat at the left hand side of each printed page. |
* |
* @access public |
* @param integer $first_col First column to repeat |
* @param integer $last_col Last column to repeat. Optional. |
*/ |
function repeatColumns($first_col, $last_col = NULL) |
{ |
$this->title_colmin = $first_col; |
if (isset($last_col)) { // Second col is optional |
$this->title_colmax = $last_col; |
} |
else { |
$this->title_colmax = $first_col; |
} |
} |
/** |
* Set the area of each worksheet that will be printed. |
* |
* @access public |
* @param integer $first_row First row of the area to print |
* @param integer $first_col First column of the area to print |
* @param integer $last_row Last row of the area to print |
* @param integer $last_col Last column of the area to print |
*/ |
function printArea($first_row, $first_col, $last_row, $last_col) |
{ |
$this->print_rowmin = $first_row; |
$this->print_colmin = $first_col; |
$this->print_rowmax = $last_row; |
$this->print_colmax = $last_col; |
} |
/** |
* Set the option to hide gridlines on the printed page. |
* |
* @access public |
*/ |
function hideGridlines() |
{ |
$this->_print_gridlines = 0; |
} |
/** |
* Set the option to print the row and column headers on the printed page. |
* |
* @access public |
* @param integer $print Whether to print the headers or not. Defaults to 1 (print). |
*/ |
function printRowColHeaders($print = 1) |
{ |
$this->_print_headers = $print; |
} |
/** |
* Set the vertical and horizontal number of pages that will define the maximum area printed. |
* It doesn't seem to work with OpenOffice. |
* |
* @access public |
* @param integer $width Maximun width of printed area in pages |
* @param integer $height Maximun heigth of printed area in pages |
* @see setPrintScale() |
*/ |
function fitToPages($width, $height) |
{ |
$this->_fit_page = 1; |
$this->_fit_width = $width; |
$this->_fit_height = $height; |
} |
/** |
* Store the horizontal page breaks on a worksheet (for printing). |
* The breaks represent the row after which the break is inserted. |
* |
* @access public |
* @param array $breaks Array containing the horizontal page breaks |
*/ |
function setHPagebreaks($breaks) |
{ |
foreach($breaks as $break) { |
array_push($this->_hbreaks,$break); |
} |
} |
/** |
* Store the vertical page breaks on a worksheet (for printing). |
* The breaks represent the column after which the break is inserted. |
* |
* @access public |
* @param array $breaks Array containing the vertical page breaks |
*/ |
function setVPagebreaks($breaks) |
{ |
foreach($breaks as $break) { |
array_push($this->_vbreaks,$break); |
} |
} |
/** |
* Set the worksheet zoom factor. |
* |
* @access public |
* @param integer $scale The zoom factor |
*/ |
function setZoom($scale = 100) |
{ |
// Confine the scale to Excel's range |
if ($scale < 10 or $scale > 400) |
{ |
$this->raiseError("Zoom factor $scale outside range: 10 <= zoom <= 400"); |
$scale = 100; |
} |
$this->_zoom = floor($scale); |
} |
/** |
* Set the scale factor for the printed page. |
* It turns off the "fit to page" option |
* |
* @access public |
* @param integer $scale The optional scale factor. Defaults to 100 |
*/ |
function setPrintScale($scale = 100) |
{ |
// Confine the scale to Excel's range |
if ($scale < 10 or $scale > 400) |
{ |
$this->raiseError("Print scale $scale outside range: 10 <= zoom <= 400"); |
$scale = 100; |
} |
// Turn off "fit to page" option |
$this->_fit_page = 0; |
$this->_print_scale = floor($scale); |
} |
/** |
* Map to the appropriate write method acording to the token recieved. |
* |
* @access public |
* @param integer $row The row of the cell we are writing to |
* @param integer $col The column of the cell we are writing to |
* @param mixed $token What we are writing |
* @param mixed $format The optional format to apply to the cell |
*/ |
function write($row, $col, $token, $format = 0) |
{ |
// Check for a cell reference in A1 notation and substitute row and column |
/*if ($_[0] =~ /^\D/) { |
@_ = $this->_substituteCellref(@_); |
}*/ |
// Match number |
if (preg_match("/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/",$token)) { |
return $this->writeNumber($row,$col,$token,$format); |
} |
// Match http or ftp URL |
elseif (preg_match("/^[fh]tt?p:\/\//",$token)) { |
return $this->writeUrl($row, $col, $token, $format); |
} |
// Match mailto: |
elseif (preg_match("/^mailto:/",$token)) { |
return $this->writeUrl($row, $col, $token, $format); |
} |
// Match internal or external sheet link |
elseif (preg_match("/^(?:in|ex)ternal:/",$token)) { |
return $this->writeUrl($row, $col, $token, $format); |
} |
// Match formula |
elseif (preg_match("/^=/",$token)) { |
return $this->writeFormula($row, $col, $token, $format); |
} |
// Match formula |
elseif (preg_match("/^@/",$token)) { |
return $this->writeFormula($row, $col, $token, $format); |
} |
// Match blank |
elseif ($token == '') { |
return $this->writeBlank($row,$col,$format); |
} |
// Default: match string |
else { |
return $this->writeString($row,$col,$token,$format); |
} |
} |
/** |
* Write an array of values as a row |
* |
* @access public |
* @param |
* @return |
*/ |
function writeRow($row, $col, $val, $format=0) |
{ |
if (is_array($val)) { |
foreach($val as $v) { |
if (is_array($v)) { |
$this->writeCol($row, $col, $v, $format); |
} else { |
$this->write($row, $col, $v, $format); |
} |
$col++; |
} |
} else { |
$retval = new PEAR_Error('$val needs to be an array'); |
} |
return($retval); |
} |
/** |
* Write an array of values as a column |
* |
* @access public |
* @param |
* @return |
*/ |
function writeCol($row, $col, $val, $format=0) |
{ |
if (is_array($val)) { |
foreach($val as $v) { |
$this->write($row, $col, $v, $format); |
$row++; |
} |
} else { |
$retval = new PEAR_Error('$val needs to be an array'); |
} |
return($retval); |
} |
/** |
* Returns an index to the XF record in the workbook |
* |
* @access private |
* @param mixed &$format The optional XF format |
* @return integer The XF record index |
*/ |
function _XF(&$format) |
{ |
if ($format != 0) { |
return($format->getXfIndex()); |
} |
else { |
return(0x0F); |
} |
} |
/****************************************************************************** |
******************************************************************************* |
* |
* Internal methods |
*/ |
/** |
* Store Worksheet data in memory using the parent's class append() or to a |
* temporary file, the default. |
* |
* @access private |
* @param string $data The binary data to append |
*/ |
function _append($data) |
{ |
if ($this->_using_tmpfile) |
{ |
// Add CONTINUE records if necessary |
if (strlen($data) > $this->_limit) { |
$data = $this->_addContinue($data); |
} |
fwrite($this->_filehandle,$data); |
$this->_datasize += strlen($data); |
} |
else { |
parent::_append($data); |
} |
} |
/** |
* Substitute an Excel cell reference in A1 notation for zero based row and |
* column values in an argument list. |
* |
* Ex: ("A4", "Hello") is converted to (3, 0, "Hello"). |
* |
* @access private |
* @param string $cell The cell reference. Or range of cells. |
* @return array |
*/ |
function _substituteCellref($cell) |
{ |
$cell = strtoupper($cell); |
// Convert a column range: 'A:A' or 'B:G' |
if (preg_match("/([A-I]?[A-Z]):([A-I]?[A-Z])/",$cell,$match)) { |
list($no_use, $col1) = $this->_cellToRowcol($match[1] .'1'); // Add a dummy row |
list($no_use, $col2) = $this->_cellToRowcol($match[2] .'1'); // Add a dummy row |
return(array($col1, $col2)); |
} |
// Convert a cell range: 'A1:B7' |
if (preg_match("/\$?([A-I]?[A-Z]\$?\d+):\$?([A-I]?[A-Z]\$?\d+)/",$cell,$match)) { |
list($row1, $col1) = $this->_cellToRowcol($match[1]); |
list($row2, $col2) = $this->_cellToRowcol($match[2]); |
return(array($row1, $col1, $row2, $col2)); |
} |
// Convert a cell reference: 'A1' or 'AD2000' |
if (preg_match("/\$?([A-I]?[A-Z]\$?\d+)/",$cell)) { |
list($row1, $col1) = $this->_cellToRowcol($match[1]); |
return(array($row1, $col1)); |
} |
// TODO use real error codes |
$this->raiseError("Unknown cell reference $cell", 0, PEAR_ERROR_DIE); |
} |
/** |
* Convert an Excel cell reference in A1 notation to a zero based row and column |
* reference; converts C1 to (0, 2). |
* |
* @access private |
* @param string $cell The cell reference. |
* @return array containing (row, column) |
*/ |
function _cellToRowcol($cell) |
{ |
preg_match("/\$?([A-I]?[A-Z])\$?(\d+)/",$cell,$match); |
$col = $match[1]; |
$row = $match[2]; |
// Convert base26 column string to number |
$chars = explode('', $col); |
$expn = 0; |
$col = 0; |
while ($chars) { |
$char = array_pop($chars); // LS char first |
$col += (ord($char) -ord('A') +1) * pow(26,$expn); |
$expn++; |
} |
// Convert 1-index to zero-index |
$row--; |
$col--; |
return(array($row, $col)); |
} |
/** |
* Based on the algorithm provided by Daniel Rentz of OpenOffice. |
* |
* @access private |
* @param string $plaintext The password to be encoded in plaintext. |
* @return string The encoded password |
*/ |
function _encodePassword($plaintext) |
{ |
$password = 0x0000; |
$i = 1; // char position |
// split the plain text password in its component characters |
$chars = preg_split('//', $plaintext, -1, PREG_SPLIT_NO_EMPTY); |
foreach($chars as $char) |
{ |
$value = ord($char) << $i; // shifted ASCII value |
$rotated_bits = $value >> 15; // rotated bits beyond bit 15 |
$value &= 0x7fff; // first 15 bits |
$password ^= ($value | $rotated_bits); |
$i++; |
} |
$password ^= strlen($plaintext); |
$password ^= 0xCE4B; |
return($password); |
} |
/****************************************************************************** |
******************************************************************************* |
* |
* BIFF RECORDS |
*/ |
/** |
* Write a double to the specified row and column (zero indexed). |
* An integer can be written as a double. Excel will display an |
* integer. $format is optional. |
* |
* Returns 0 : normal termination |
* -2 : row or column out of range |
* |
* @access public |
* @param integer $row Zero indexed row |
* @param integer $col Zero indexed column |
* @param float $num The number to write |
* @param mixed $format The optional XF format |
* @return integer |
*/ |
function writeNumber($row, $col, $num, $format = 0) |
{ |
$record = 0x0203; // Record identifier |
$length = 0x000E; // Number of bytes to follow |
$xf = $this->_XF($format); // The cell format |
// Check that row and col are valid and store max and min values |
if ($row >= $this->_xls_rowmax) |
{ |
return(-2); |
} |
if ($col >= $this->_xls_colmax) |
{ |
return(-2); |
} |
if ($row < $this->_dim_rowmin) |
{ |
$this->_dim_rowmin = $row; |
} |
if ($row > $this->_dim_rowmax) |
{ |
$this->_dim_rowmax = $row; |
} |
if ($col < $this->_dim_colmin) |
{ |
$this->_dim_colmin = $col; |
} |
if ($col > $this->_dim_colmax) |
{ |
$this->_dim_colmax = $col; |
} |
$header = pack("vv", $record, $length); |
$data = pack("vvv", $row, $col, $xf); |
$xl_double = pack("d", $num); |
if ($this->_byte_order) // if it's Big Endian |
{ |
$xl_double = strrev($xl_double); |
} |
$this->_append($header.$data.$xl_double); |
return(0); |
} |
/** |
* Write a string to the specified row and column (zero indexed). |
* NOTE: there is an Excel 5 defined limit of 255 characters. |
* $format is optional. |
* Returns 0 : normal termination |
* -2 : row or column out of range |
* -3 : long string truncated to 255 chars |
* |
* @access public |
* @param integer $row Zero indexed row |
* @param integer $col Zero indexed column |
* @param string $str The string to write |
* @param mixed $format The XF format for the cell |
* @return integer |
*/ |
function writeString($row, $col, $str, $format = 0) |
{ |
$strlen = strlen($str); |
$record = 0x0204; // Record identifier |
$length = 0x0008 + $strlen; // Bytes to follow |
$xf = $this->_XF($format); // The cell format |
$str_error = 0; |
// Check that row and col are valid and store max and min values |
if ($row >= $this->_xls_rowmax) |
{ |
return(-2); |
} |
if ($col >= $this->_xls_colmax) |
{ |
return(-2); |
} |
if ($row < $this->_dim_rowmin) |
{ |
$this->_dim_rowmin = $row; |
} |
if ($row > $this->_dim_rowmax) |
{ |
$this->_dim_rowmax = $row; |
} |
if ($col < $this->_dim_colmin) |
{ |
$this->_dim_colmin = $col; |
} |
if ($col > $this->_dim_colmax) |
{ |
$this->_dim_colmax = $col; |
} |
if ($strlen > $this->_xls_strmax) // LABEL must be < 255 chars |
{ |
$str = substr($str, 0, $this->_xls_strmax); |
$length = 0x0008 + $this->_xls_strmax; |
$strlen = $this->_xls_strmax; |
$str_error = -3; |
} |
$header = pack("vv", $record, $length); |
$data = pack("vvvv", $row, $col, $xf, $strlen); |
$this->_append($header.$data.$str); |
return($str_error); |
} |
/** |
* Writes a note associated with the cell given by the row and column. |
* NOTE records don't have a length limit. |
* |
* @access public |
* @param integer $row Zero indexed row |
* @param integer $col Zero indexed column |
* @param string $note The note to write |
*/ |
function writeNote($row, $col, $note) |
{ |
$note_length = strlen($note); |
$record = 0x001C; // Record identifier |
$max_length = 2048; // Maximun length for a NOTE record |
//$length = 0x0006 + $note_length; // Bytes to follow |
// Check that row and col are valid and store max and min values |
if ($row >= $this->_xls_rowmax) |
{ |
return(-2); |
} |
if ($col >= $this->_xls_colmax) |
{ |
return(-2); |
} |
if ($row < $this->_dim_rowmin) |
{ |
$this->_dim_rowmin = $row; |
} |
if ($row > $this->_dim_rowmax) |
{ |
$this->_dim_rowmax = $row; |
} |
if ($col < $this->_dim_colmin) |
{ |
$this->_dim_colmin = $col; |
} |
if ($col > $this->_dim_colmax) |
{ |
$this->_dim_colmax = $col; |
} |
// Length for this record is no more than 2048 + 6 |
$length = 0x0006 + min($note_length, 2048); |
$header = pack("vv", $record, $length); |
$data = pack("vvv", $row, $col, $note_length); |
$this->_append($header.$data.substr($note, 0, 2048)); |
for($i = $max_length; $i < $note_length; $i += $max_length) |
{ |
$chunk = substr($note, $i, $max_length); |
$length = 0x0006 + strlen($chunk); |
$header = pack("vv", $record, $length); |
$data = pack("vvv", -1, 0, strlen($chunk)); |
$this->_append($header.$data.$chunk); |
} |
return(0); |
} |
/** |
* Write a blank cell to the specified row and column (zero indexed). |
* A blank cell is used to specify formatting without adding a string |
* or a number. |
* |
* A blank cell without a format serves no purpose. Therefore, we don't write |
* a BLANK record unless a format is specified. |
* |
* Returns 0 : normal termination (including no format) |
* -1 : insufficient number of arguments |
* -2 : row or column out of range |
* |
* @access public |
* @param integer $row Zero indexed row |
* @param integer $col Zero indexed column |
* @param mixed $format The XF format |
*/ |
function writeBlank($row, $col, $format) |
{ |
// Don't write a blank cell unless it has a format |
if ($format == 0) |
{ |
return(0); |
} |
$record = 0x0201; // Record identifier |
$length = 0x0006; // Number of bytes to follow |
$xf = $this->_XF($format); // The cell format |
// Check that row and col are valid and store max and min values |
if ($row >= $this->_xls_rowmax) |
{ |
return(-2); |
} |
if ($col >= $this->_xls_colmax) |
{ |
return(-2); |
} |
if ($row < $this->_dim_rowmin) |
{ |
$this->_dim_rowmin = $row; |
} |
if ($row > $this->_dim_rowmax) |
{ |
$this->_dim_rowmax = $row; |
} |
if ($col < $this->_dim_colmin) |
{ |
$this->_dim_colmin = $col; |
} |
if ($col > $this->_dim_colmax) |
{ |
$this->_dim_colmax = $col; |
} |
$header = pack("vv", $record, $length); |
$data = pack("vvv", $row, $col, $xf); |
$this->_append($header.$data); |
return 0; |
} |
/** |
* Write a formula to the specified row and column (zero indexed). |
* The textual representation of the formula is passed to the parser in |
* Parser.php which returns a packed binary string. |
* |
* Returns 0 : normal termination |
* -1 : formula errors (bad formula) |
* -2 : row or column out of range |
* |
* @access public |
* @param integer $row Zero indexed row |
* @param integer $col Zero indexed column |
* @param string $formula The formula text string |
* @param mixed $format The optional XF format |
* @return integer |
*/ |
function writeFormula($row, $col, $formula, $format = 0) |
{ |
$record = 0x0006; // Record identifier |
// Excel normally stores the last calculated value of the formula in $num. |
// Clearly we are not in a position to calculate this a priori. Instead |
// we set $num to zero and set the option flags in $grbit to ensure |
// automatic calculation of the formula when the file is opened. |
// |
$xf = $this->_XF($format); // The cell format |
$num = 0x00; // Current value of formula |
$grbit = 0x03; // Option flags |
$chn = 0x0000; // Must be zero |
// Check that row and col are valid and store max and min values |
if ($row >= $this->_xls_rowmax) |
{ |
return(-2); |
} |
if ($col >= $this->_xls_colmax) |
{ |
return(-2); |
} |
if ($row < $this->_dim_rowmin) |
{ |
$this->_dim_rowmin = $row; |
} |
if ($row > $this->_dim_rowmax) |
{ |
$this->_dim_rowmax = $row; |
} |
if ($col < $this->_dim_colmin) |
{ |
$this->_dim_colmin = $col; |
} |
if ($col > $this->_dim_colmax) |
{ |
$this->_dim_colmax = $col; |
} |
// Strip the '=' or '@' sign at the beginning of the formula string |
if (preg_match("/^=/",$formula)) { |
$formula = preg_replace("/(^=)/","",$formula); |
} |
elseif (preg_match("/^@/",$formula)) { |
$formula = preg_replace("/(^@)/","",$formula); |
} |
else |
{ |
// Error handling |
$this->writeString($row, $col, 'Unrecognised character for formula'); |
return -1; |
} |
// Parse the formula using the parser in Parser.php |
$error = $this->_parser->parse($formula); |
if ($this->isError($error)) |
{ |
$this->writeString($row, $col, $error->getMessage()); |
return -1; |
} |
$formula = $this->_parser->toReversePolish(); |
if ($this->isError($formula)) |
{ |
$this->writeString($row, $col, $formula->getMessage()); |
return -1; |
} |
$formlen = strlen($formula); // Length of the binary string |
$length = 0x16 + $formlen; // Length of the record data |
$header = pack("vv", $record, $length); |
$data = pack("vvvdvVv", $row, $col, $xf, $num, |
$grbit, $chn, $formlen); |
$this->_append($header.$data.$formula); |
return 0; |
} |
/** |
* Write a hyperlink. |
* This is comprised of two elements: the visible label and |
* the invisible link. The visible label is the same as the link unless an |
* alternative string is specified. The label is written using the |
* writeString() method. Therefore the 255 characters string limit applies. |
* $string and $format are optional. |
* |
* The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external |
* directory url. |
* |
* Returns 0 : normal termination |
* -2 : row or column out of range |
* -3 : long string truncated to 255 chars |
* |
* @access public |
* @param integer $row Row |
* @param integer $col Column |
* @param string $url URL string |
* @param string $string Alternative label |
* @param mixed $format The cell format |
* @return integer |
*/ |
function writeUrl($row, $col, $url, $string = '', $format = 0) |
{ |
// Add start row and col to arg list |
return($this->_writeUrl_range($row, $col, $row, $col, $url, $string, $format)); |
} |
/** |
* This is the more general form of writeUrl(). It allows a hyperlink to be |
* written to a range of cells. This function also decides the type of hyperlink |
* to be written. These are either, Web (http, ftp, mailto), Internal |
* (Sheet1!A1) or external ('c:\temp\foo.xls#Sheet1!A1'). |
* |
* @access private |
* @see writeUrl() |
* @param integer $row1 Start row |
* @param integer $col1 Start column |
* @param integer $row2 End row |
* @param integer $col2 End column |
* @param string $url URL string |
* @param string $string Alternative label |
* @param mixed $format The cell format |
* @return integer |
*/ |
function _writeUrl_range($row1, $col1, $row2, $col2, $url, $string = '', $format = 0) |
{ |
// Check for internal/external sheet links or default to web link |
if (preg_match('[^internal:]', $url)) { |
return($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url, $string, $format)); |
} |
if (preg_match('[^external:]', $url)) { |
return($this->_writeUrlExternal($row1, $col1, $row2, $col2, $url, $string, $format)); |
} |
return($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url, $string, $format)); |
} |
/** |
* Used to write http, ftp and mailto hyperlinks. |
* The link type ($options) is 0x03 is the same as absolute dir ref without |
* sheet. However it is differentiated by the $unknown2 data stream. |
* |
* @access private |
* @see writeUrl() |
* @param integer $row1 Start row |
* @param integer $col1 Start column |
* @param integer $row2 End row |
* @param integer $col2 End column |
* @param string $url URL string |
* @param string $str Alternative label |
* @param mixed $format The cell format |
* @return integer |
*/ |
function _writeUrlWeb($row1, $col1, $row2, $col2, $url, $str, $format = 0) |
{ |
$record = 0x01B8; // Record identifier |
$length = 0x00000; // Bytes to follow |
if ($format == 0) { |
$format = $this->_url_format; |
} |
// Write the visible label using the writeString() method. |
if ($str == '') { |
$str = $url; |
} |
$str_error = $this->writeString($row1, $col1, $str, $format); |
if (($str_error == -2) or ($str_error == -3)) { |
return $str_error; |
} |
// Pack the undocumented parts of the hyperlink stream |
$unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); |
$unknown2 = pack("H*", "E0C9EA79F9BACE118C8200AA004BA90B"); |
// Pack the option flags |
$options = pack("V", 0x03); |
// Convert URL to a null terminated wchar string |
$url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY)); |
$url = $url . "\0\0\0"; |
// Pack the length of the URL |
$url_len = pack("V", strlen($url)); |
// Calculate the data length |
$length = 0x34 + strlen($url); |
// Pack the header data |
$header = pack("vv", $record, $length); |
$data = pack("vvvv", $row1, $row2, $col1, $col2); |
// Write the packed data |
$this->_append( $header. $data. |
$unknown1. $options. |
$unknown2. $url_len. $url); |
return($str_error); |
} |
/** |
* Used to write internal reference hyperlinks such as "Sheet1!A1". |
* |
* @access private |
* @see writeUrl() |
* @param integer $row1 Start row |
* @param integer $col1 Start column |
* @param integer $row2 End row |
* @param integer $col2 End column |
* @param string $url URL string |
* @param string $str Alternative label |
* @param mixed $format The cell format |
* @return integer |
*/ |
function _writeUrlInternal($row1, $col1, $row2, $col2, $url, $str, $format = 0) |
{ |
$record = 0x01B8; // Record identifier |
$length = 0x00000; // Bytes to follow |
if ($format == 0) { |
$format = $this->_url_format; |
} |
// Strip URL type |
$url = preg_replace('s[^internal:]', '', $url); |
// Write the visible label |
if ($str == '') { |
$str = $url; |
} |
$str_error = $this->writeString($row1, $col1, $str, $format); |
if (($str_error == -2) or ($str_error == -3)) { |
return $str_error; |
} |
// Pack the undocumented parts of the hyperlink stream |
$unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); |
// Pack the option flags |
$options = pack("V", 0x08); |
// Convert the URL type and to a null terminated wchar string |
$url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY)); |
$url = $url . "\0\0\0"; |
// Pack the length of the URL as chars (not wchars) |
$url_len = pack("V", floor(strlen($url)/2)); |
// Calculate the data length |
$length = 0x24 + strlen($url); |
// Pack the header data |
$header = pack("vv", $record, $length); |
$data = pack("vvvv", $row1, $row2, $col1, $col2); |
// Write the packed data |
$this->_append($header. $data. |
$unknown1. $options. |
$url_len. $url); |
return($str_error); |
} |
/** |
* Write links to external directory names such as 'c:\foo.xls', |
* c:\foo.xls#Sheet1!A1', '../../foo.xls'. and '../../foo.xls#Sheet1!A1'. |
* |
* Note: Excel writes some relative links with the $dir_long string. We ignore |
* these cases for the sake of simpler code. |
* |
* @access private |
* @see writeUrl() |
* @param integer $row1 Start row |
* @param integer $col1 Start column |
* @param integer $row2 End row |
* @param integer $col2 End column |
* @param string $url URL string |
* @param string $str Alternative label |
* @param mixed $format The cell format |
* @return integer |
*/ |
function _writeUrlExternal($row1, $col1, $row2, $col2, $url, $str, $format = 0) |
{ |
// Network drives are different. We will handle them separately |
// MS/Novell network drives and shares start with \\ |
if (preg_match('[^external:\\\\]', $url)) { |
return; //($this->_writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format)); |
} |
$record = 0x01B8; // Record identifier |
$length = 0x00000; // Bytes to follow |
if ($format == 0) { |
$format = $this->_url_format; |
} |
// Strip URL type and change Unix dir separator to Dos style (if needed) |
// |
$url = preg_replace('[^external:]', '', $url); |
$url = preg_replace('[/]', "\\", $url); |
// Write the visible label |
if ($str == '') { |
$str = preg_replace('[\#]', ' - ', $url); |
} |
$str_error = $this->writeString($row1, $col1, $str, $format); |
if (($str_error == -2) or ($str_error == -3)) { |
return $str_error; |
} |
// Determine if the link is relative or absolute: |
// relative if link contains no dir separator, "somefile.xls" |
// relative if link starts with up-dir, "..\..\somefile.xls" |
// otherwise, absolute |
$absolute = 0x02; // Bit mask |
if (!preg_match('[\\]', $url)) { |
$absolute = 0x00; |
} |
if (preg_match('[^\.\.\\]', $url)) { |
$absolute = 0x00; |
} |
// Determine if the link contains a sheet reference and change some of the |
// parameters accordingly. |
// Split the dir name and sheet name (if it exists) |
list($dir_long , $sheet) = explode('/\#/', $url); |
$link_type = 0x01 | $absolute; |
if (isset($sheet)) { |
$link_type |= 0x08; |
$sheet_len = pack("V", strlen($sheet) + 0x01); |
$sheet = join("\0", explode('', $sheet)); |
$sheet .= "\0\0\0"; |
} |
else { |
$sheet_len = ''; |
$sheet = ''; |
} |
// Pack the link type |
$link_type = pack("V", $link_type); |
// Calculate the up-level dir count e.g.. (..\..\..\ == 3) |
$up_count = preg_match_all("/\.\.\\/", $dir_long, $useless); |
$up_count = pack("v", $up_count); |
// Store the short dos dir name (null terminated) |
$dir_short = preg_replace('/\.\.\\/', '', $dir_long) . "\0"; |
// Store the long dir name as a wchar string (non-null terminated) |
$dir_long = join("\0", explode('', $dir_long)); |
$dir_long = $dir_long . "\0"; |
// Pack the lengths of the dir strings |
$dir_short_len = pack("V", strlen($dir_short) ); |
$dir_long_len = pack("V", strlen($dir_long) ); |
$stream_len = pack("V", strlen($dir_long) + 0x06); |
// Pack the undocumented parts of the hyperlink stream |
$unknown1 = pack("H*",'D0C9EA79F9BACE118C8200AA004BA90B02000000' ); |
$unknown2 = pack("H*",'0303000000000000C000000000000046' ); |
$unknown3 = pack("H*",'FFFFADDE000000000000000000000000000000000000000'); |
$unknown4 = pack("v", 0x03 ); |
// Pack the main data stream |
$data = pack("vvvv", $row1, $row2, $col1, $col2) . |
$unknown1 . |
$link_type . |
$unknown2 . |
$up_count . |
$dir_short_len. |
$dir_short . |
$unknown3 . |
$stream_len . |
$dir_long_len . |
$unknown4 . |
$dir_long . |
$sheet_len . |
$sheet ; |
// Pack the header data |
$length = strlen($data); |
$header = pack("vv", $record, $length); |
// Write the packed data |
$this->_append($header. $data); |
return($str_error); |
} |
/** |
* This method is used to set the height and format for a row. |
* |
* @access public |
* @param integer $row The row to set |
* @param integer $height Height we are giving to the row. |
* Use NULL to set XF without setting height |
* @param mixed $format XF format we are giving to the row |
*/ |
function setRow($row, $height, $format = 0) |
{ |
$record = 0x0208; // Record identifier |
$length = 0x0010; // Number of bytes to follow |
$colMic = 0x0000; // First defined column |
$colMac = 0x0000; // Last defined column |
$irwMac = 0x0000; // Used by Excel to optimise loading |
$reserved = 0x0000; // Reserved |
$grbit = 0x01C0; // Option flags. (monkey) see $1 do |
$ixfe = $this->_XF($format); // XF index |
// Use setRow($row, NULL, $XF) to set XF format without setting height |
if ($height != NULL) { |
$miyRw = $height * 20; // row height |
} |
else { |
$miyRw = 0xff; // default row height is 256 |
} |
$header = pack("vv", $record, $length); |
$data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, |
$irwMac,$reserved, $grbit, $ixfe); |
$this->_append($header.$data); |
} |
/** |
* Writes Excel DIMENSIONS to define the area in which there is data. |
* |
* @access private |
*/ |
function storeDimensions() |
{ |
$record = 0x0000; // Record identifier |
$length = 0x000A; // Number of bytes to follow |
$row_min = $this->_dim_rowmin; // First row |
$row_max = $this->_dim_rowmax; // Last row plus 1 |
$col_min = $this->_dim_colmin; // First column |
$col_max = $this->_dim_colmax; // Last column plus 1 |
$reserved = 0x0000; // Reserved by Excel |
$header = pack("vv", $record, $length); |
$data = pack("vvvvv", $row_min, $row_max, |
$col_min, $col_max, $reserved); |
$this->_prepend($header.$data); |
} |
/** |
* Write BIFF record Window2. |
* |
* @access private |
*/ |
function _storeWindow2() |
{ |
$record = 0x023E; // Record identifier |
$length = 0x000A; // Number of bytes to follow |
$grbit = 0x00B6; // Option flags |
$rwTop = 0x0000; // Top row visible in window |
$colLeft = 0x0000; // Leftmost column visible in window |
$rgbHdr = 0x00000000; // Row/column heading and gridline color |
// The options flags that comprise $grbit |
$fDspFmla = 0; // 0 - bit |
$fDspGrid = 1; // 1 |
$fDspRwCol = 1; // 2 |
$fFrozen = $this->_frozen; // 3 |
$fDspZeros = 1; // 4 |
$fDefaultHdr = 1; // 5 |
$fArabic = 0; // 6 |
$fDspGuts = 1; // 7 |
$fFrozenNoSplit = 0; // 0 - bit |
$fSelected = $this->selected; // 1 |
$fPaged = 1; // 2 |
$grbit = $fDspFmla; |
$grbit |= $fDspGrid << 1; |
$grbit |= $fDspRwCol << 2; |
$grbit |= $fFrozen << 3; |
$grbit |= $fDspZeros << 4; |
$grbit |= $fDefaultHdr << 5; |
$grbit |= $fArabic << 6; |
$grbit |= $fDspGuts << 7; |
$grbit |= $fFrozenNoSplit << 8; |
$grbit |= $fSelected << 9; |
$grbit |= $fPaged << 10; |
$header = pack("vv", $record, $length); |
$data = pack("vvvV", $grbit, $rwTop, $colLeft, $rgbHdr); |
$this->_append($header.$data); |
} |
/** |
* Write BIFF record DEFCOLWIDTH if COLINFO records are in use. |
* |
* @access private |
*/ |
function _storeDefcol() |
{ |
$record = 0x0055; // Record identifier |
$length = 0x0002; // Number of bytes to follow |
$colwidth = 0x0008; // Default column width |
$header = pack("vv", $record, $length); |
$data = pack("v", $colwidth); |
$this->_prepend($header.$data); |
} |
/** |
* Write BIFF record COLINFO to define column widths |
* |
* Note: The SDK says the record length is 0x0B but Excel writes a 0x0C |
* length record. |
* |
* @access private |
* @param array $col_array This is the only parameter received and is composed of the following: |
* 0 => First formatted column, |
* 1 => Last formatted column, |
* 2 => Col width (8.43 is Excel default), |
* 3 => The optional XF format of the column, |
* 4 => Option flags. |
*/ |
function _storeColinfo($col_array) |
{ |
if (isset($col_array[0])) { |
$colFirst = $col_array[0]; |
} |
if (isset($col_array[1])) { |
$colLast = $col_array[1]; |
} |
if (isset($col_array[2])) { |
$coldx = $col_array[2]; |
} |
else { |
$coldx = 8.43; |
} |
if (isset($col_array[3])) { |
$format = $col_array[3]; |
} |
else { |
$format = 0; |
} |
if (isset($col_array[4])) { |
$grbit = $col_array[4]; |
} |
else { |
$grbit = 0; |
} |
$record = 0x007D; // Record identifier |
$length = 0x000B; // Number of bytes to follow |
$coldx += 0.72; // Fudge. Excel subtracts 0.72 !? |
$coldx *= 256; // Convert to units of 1/256 of a char |
$ixfe = $this->_XF($format); |
$reserved = 0x00; // Reserved |
$header = pack("vv", $record, $length); |
$data = pack("vvvvvC", $colFirst, $colLast, $coldx, |
$ixfe, $grbit, $reserved); |
$this->_prepend($header.$data); |
} |
/** |
* Write BIFF record SELECTION. |
* |
* @access private |
* @param array $array array containing ($rwFirst,$colFirst,$rwLast,$colLast) |
* @see setSelection() |
*/ |
function _storeSelection($array) |
{ |
list($rwFirst,$colFirst,$rwLast,$colLast) = $array; |
$record = 0x001D; // Record identifier |
$length = 0x000F; // Number of bytes to follow |
$pnn = $this->_active_pane; // Pane position |
$rwAct = $rwFirst; // Active row |
$colAct = $colFirst; // Active column |
$irefAct = 0; // Active cell ref |
$cref = 1; // Number of refs |
if (!isset($rwLast)) { |
$rwLast = $rwFirst; // Last row in reference |
} |
if (!isset($colLast)) { |
$colLast = $colFirst; // Last col in reference |
} |
// Swap last row/col for first row/col as necessary |
if ($rwFirst > $rwLast) |
{ |
list($rwFirst, $rwLast) = array($rwLast, $rwFirst); |
} |
if ($colFirst > $colLast) |
{ |
list($colFirst, $colLast) = array($colLast, $colFirst); |
} |
$header = pack("vv", $record, $length); |
$data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct, |
$irefAct, $cref, |
$rwFirst, $rwLast, |
$colFirst, $colLast); |
$this->_append($header.$data); |
} |
/** |
* Write BIFF record EXTERNCOUNT to indicate the number of external sheet |
* references in a worksheet. |
* |
* Excel only stores references to external sheets that are used in formulas. |
* For simplicity we store references to all the sheets in the workbook |
* regardless of whether they are used or not. This reduces the overall |
* complexity and eliminates the need for a two way dialogue between the formula |
* parser the worksheet objects. |
* |
* @access private |
* @param integer $count The number of external sheet references in this worksheet |
*/ |
function _storeExterncount($count) |
{ |
$record = 0x0016; // Record identifier |
$length = 0x0002; // Number of bytes to follow |
$header = pack("vv", $record, $length); |
$data = pack("v", $count); |
$this->_prepend($header.$data); |
} |
/** |
* Writes the Excel BIFF EXTERNSHEET record. These references are used by |
* formulas. A formula references a sheet name via an index. Since we store a |
* reference to all of the external worksheets the EXTERNSHEET index is the same |
* as the worksheet index. |
* |
* @access private |
* @param string $sheetname The name of a external worksheet |
*/ |
function _storeExternsheet($sheetname) |
{ |
$record = 0x0017; // Record identifier |
// References to the current sheet are encoded differently to references to |
// external sheets. |
// |
if ($this->name == $sheetname) { |
$sheetname = ''; |
$length = 0x02; // The following 2 bytes |
$cch = 1; // The following byte |
$rgch = 0x02; // Self reference |
} |
else { |
$length = 0x02 + strlen($sheetname); |
$cch = strlen($sheetname); |
$rgch = 0x03; // Reference to a sheet in the current workbook |
} |
$header = pack("vv", $record, $length); |
$data = pack("CC", $cch, $rgch); |
$this->_prepend($header.$data.$sheetname); |
} |
/** |
* Writes the Excel BIFF PANE record. |
* The panes can either be frozen or thawed (unfrozen). |
* Frozen panes are specified in terms of an integer number of rows and columns. |
* Thawed panes are specified in terms of Excel's units for rows and columns. |
* |
* @access private |
* @param array $panes This is the only parameter received and is composed of the following: |
* 0 => Vertical split position, |
* 1 => Horizontal split position |
* 2 => Top row visible |
* 3 => Leftmost column visible |
* 4 => Active pane |
*/ |
function _storePanes($panes) |
{ |
$y = $panes[0]; |
$x = $panes[1]; |
$rwTop = $panes[2]; |
$colLeft = $panes[3]; |
if (count($panes) > 4) { // if Active pane was received |
$pnnAct = $panes[4]; |
} |
else { |
$pnnAct = NULL; |
} |
$record = 0x0041; // Record identifier |
$length = 0x000A; // Number of bytes to follow |
// Code specific to frozen or thawed panes. |
if ($this->_frozen) |
{ |
// Set default values for $rwTop and $colLeft |
if (!isset($rwTop)) { |
$rwTop = $y; |
} |
if (!isset($colLeft)) { |
$colLeft = $x; |
} |
} |
else |
{ |
// Set default values for $rwTop and $colLeft |
if (!isset($rwTop)) { |
$rwTop = 0; |
} |
if (!isset($colLeft)) { |
$colLeft = 0; |
} |
// Convert Excel's row and column units to the internal units. |
// The default row height is 12.75 |
// The default column width is 8.43 |
// The following slope and intersection values were interpolated. |
// |
$y = 20*$y + 255; |
$x = 113.879*$x + 390; |
} |
// Determine which pane should be active. There is also the undocumented |
// option to override this should it be necessary: may be removed later. |
// |
if (!isset($pnnAct)) |
{ |
if ($x != 0 and $y != 0) |
$pnnAct = 0; // Bottom right |
if ($x != 0 and $y == 0) |
$pnnAct = 1; // Top right |
if ($x == 0 and $y != 0) |
$pnnAct = 2; // Bottom left |
if ($x == 0 and $y == 0) |
$pnnAct = 3; // Top left |
} |
$this->_active_pane = $pnnAct; // Used in _storeSelection |
$header = pack("vv", $record, $length); |
$data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); |
$this->_append($header.$data); |
} |
/** |
* Store the page setup SETUP BIFF record. |
* |
* @access private |
*/ |
function _storeSetup() |
{ |
$record = 0x00A1; // Record identifier |
$length = 0x0022; // Number of bytes to follow |
$iPaperSize = $this->_paper_size; // Paper size |
$iScale = $this->_print_scale; // Print scaling factor |
$iPageStart = 0x01; // Starting page number |
$iFitWidth = $this->_fit_width; // Fit to number of pages wide |
$iFitHeight = $this->_fit_height; // Fit to number of pages high |
$grbit = 0x00; // Option flags |
$iRes = 0x0258; // Print resolution |
$iVRes = 0x0258; // Vertical print resolution |
$numHdr = $this->_margin_head; // Header Margin |
$numFtr = $this->_margin_foot; // Footer Margin |
$iCopies = 0x01; // Number of copies |
$fLeftToRight = 0x0; // Print over then down |
$fLandscape = $this->_orientation; // Page orientation |
$fNoPls = 0x0; // Setup not read from printer |
$fNoColor = 0x0; // Print black and white |
$fDraft = 0x0; // Print draft quality |
$fNotes = 0x0; // Print notes |
$fNoOrient = 0x0; // Orientation not set |
$fUsePage = 0x0; // Use custom starting page |
$grbit = $fLeftToRight; |
$grbit |= $fLandscape << 1; |
$grbit |= $fNoPls << 2; |
$grbit |= $fNoColor << 3; |
$grbit |= $fDraft << 4; |
$grbit |= $fNotes << 5; |
$grbit |= $fNoOrient << 6; |
$grbit |= $fUsePage << 7; |
$numHdr = pack("d", $numHdr); |
$numFtr = pack("d", $numFtr); |
if ($this->_byte_order) // if it's Big Endian |
{ |
$numHdr = strrev($numHdr); |
$numFtr = strrev($numFtr); |
} |
$header = pack("vv", $record, $length); |
$data1 = pack("vvvvvvvv", $iPaperSize, |
$iScale, |
$iPageStart, |
$iFitWidth, |
$iFitHeight, |
$grbit, |
$iRes, |
$iVRes); |
$data2 = $numHdr.$numFtr; |
$data3 = pack("v", $iCopies); |
$this->_prepend($header.$data1.$data2.$data3); |
} |
/** |
* Store the header caption BIFF record. |
* |
* @access private |
*/ |
function _storeHeader() |
{ |
$record = 0x0014; // Record identifier |
$str = $this->_header; // header string |
$cch = strlen($str); // Length of header string |
$length = 1 + $cch; // Bytes to follow |
$header = pack("vv", $record, $length); |
$data = pack("C", $cch); |
$this->_append($header.$data.$str); |
} |
/** |
* Store the footer caption BIFF record. |
* |
* @access private |
*/ |
function _storeFooter() |
{ |
$record = 0x0015; // Record identifier |
$str = $this->_footer; // Footer string |
$cch = strlen($str); // Length of footer string |
$length = 1 + $cch; // Bytes to follow |
$header = pack("vv", $record, $length); |
$data = pack("C", $cch); |
$this->_append($header.$data.$str); |
} |
/** |
* Store the horizontal centering HCENTER BIFF record. |
* |
* @access private |
*/ |
function _storeHcenter() |
{ |
$record = 0x0083; // Record identifier |
$length = 0x0002; // Bytes to follow |
$fHCenter = $this->_hcenter; // Horizontal centering |
$header = pack("vv", $record, $length); |
$data = pack("v", $fHCenter); |
$this->_append($header.$data); |
} |
/** |
* Store the vertical centering VCENTER BIFF record. |
* |
* @access private |
*/ |
function _storeVcenter() |
{ |
$record = 0x0084; // Record identifier |
$length = 0x0002; // Bytes to follow |
$fVCenter = $this->_vcenter; // Horizontal centering |
$header = pack("vv", $record, $length); |
$data = pack("v", $fVCenter); |
$this->_append($header.$data); |
} |
/** |
* Store the LEFTMARGIN BIFF record. |
* |
* @access private |
*/ |
function _storeMarginLeft() |
{ |
$record = 0x0026; // Record identifier |
$length = 0x0008; // Bytes to follow |
$margin = $this->_margin_left; // Margin in inches |
$header = pack("vv", $record, $length); |
$data = pack("d", $margin); |
if ($this->_byte_order) // if it's Big Endian |
{ |
$data = strrev($data); |
} |
$this->_append($header.$data); |
} |
/** |
* Store the RIGHTMARGIN BIFF record. |
* |
* @access private |
*/ |
function _storeMarginRight() |
{ |
$record = 0x0027; // Record identifier |
$length = 0x0008; // Bytes to follow |
$margin = $this->_margin_right; // Margin in inches |
$header = pack("vv", $record, $length); |
$data = pack("d", $margin); |
if ($this->_byte_order) // if it's Big Endian |
{ |
$data = strrev($data); |
} |
$this->_append($header.$data); |
} |
/** |
* Store the TOPMARGIN BIFF record. |
* |
* @access private |
*/ |
function _storeMarginTop() |
{ |
$record = 0x0028; // Record identifier |
$length = 0x0008; // Bytes to follow |
$margin = $this->_margin_top; // Margin in inches |
$header = pack("vv", $record, $length); |
$data = pack("d", $margin); |
if ($this->_byte_order) // if it's Big Endian |
{ |
$data = strrev($data); |
} |
$this->_append($header.$data); |
} |
/** |
* Store the BOTTOMMARGIN BIFF record. |
* |
* @access private |
*/ |
function _storeMarginBottom() |
{ |
$record = 0x0029; // Record identifier |
$length = 0x0008; // Bytes to follow |
$margin = $this->_margin_bottom; // Margin in inches |
$header = pack("vv", $record, $length); |
$data = pack("d", $margin); |
if ($this->_byte_order) // if it's Big Endian |
{ |
$data = strrev($data); |
} |
$this->_append($header.$data); |
} |
/** |
* Merges the area given by its arguments. |
* This is an Excel97/2000 method. It is required to perform more complicated |
* merging than the normal setAlign('merge'). |
* |
* @access public |
* @param integer $first_row First row of the area to merge |
* @param integer $first_col First column of the area to merge |
* @param integer $last_row Last row of the area to merge |
* @param integer $last_col Last column of the area to merge |
*/ |
function mergeCells($first_row, $first_col, $last_row, $last_col) |
{ |
$record = 0x00E5; // Record identifier |
$length = 0x000A; // Bytes to follow |
$cref = 1; // Number of refs |
// Swap last row/col for first row/col as necessary |
if ($first_row > $last_row) { |
list($first_row, $last_row) = array($last_row, $first_row); |
} |
if ($first_col > $last_col) { |
list($first_col, $last_col) = array($last_col, $first_col); |
} |
$header = pack("vv", $record, $length); |
$data = pack("vvvvv", $cref, $first_row, $last_row, |
$first_col, $last_col); |
$this->_append($header.$data); |
} |
/** |
* Write the PRINTHEADERS BIFF record. |
* |
* @access private |
*/ |
function _storePrintHeaders() |
{ |
$record = 0x002a; // Record identifier |
$length = 0x0002; // Bytes to follow |
$fPrintRwCol = $this->_print_headers; // Boolean flag |
$header = pack("vv", $record, $length); |
$data = pack("v", $fPrintRwCol); |
$this->_prepend($header.$data); |
} |
/** |
* Write the PRINTGRIDLINES BIFF record. Must be used in conjunction with the |
* GRIDSET record. |
* |
* @access private |
*/ |
function _storePrintGridlines() |
{ |
$record = 0x002b; // Record identifier |
$length = 0x0002; // Bytes to follow |
$fPrintGrid = $this->_print_gridlines; // Boolean flag |
$header = pack("vv", $record, $length); |
$data = pack("v", $fPrintGrid); |
$this->_prepend($header.$data); |
} |
/** |
* Write the GRIDSET BIFF record. Must be used in conjunction with the |
* PRINTGRIDLINES record. |
* |
* @access private |
*/ |
function _storeGridset() |
{ |
$record = 0x0082; // Record identifier |
$length = 0x0002; // Bytes to follow |
$fGridSet = !($this->_print_gridlines); // Boolean flag |
$header = pack("vv", $record, $length); |
$data = pack("v", $fGridSet); |
$this->_prepend($header.$data); |
} |
/** |
* Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction |
* with the SETUP record. |
* |
* @access private |
*/ |
function _storeWsbool() |
{ |
$record = 0x0081; // Record identifier |
$length = 0x0002; // Bytes to follow |
// The only option that is of interest is the flag for fit to page. So we |
// set all the options in one go. |
// |
if ($this->_fit_page) { |
$grbit = 0x05c1; |
} |
else { |
$grbit = 0x04c1; |
} |
$header = pack("vv", $record, $length); |
$data = pack("v", $grbit); |
$this->_prepend($header.$data); |
} |
/** |
* Write the HORIZONTALPAGEBREAKS BIFF record. |
* |
* @access private |
*/ |
function _storeHbreak() |
{ |
// Return if the user hasn't specified pagebreaks |
if (empty($this->_hbreaks)) { |
return; |
} |
// Sort and filter array of page breaks |
$breaks = $this->_hbreaks; |
sort($breaks,SORT_NUMERIC); |
if ($breaks[0] == 0) { // don't use first break if it's 0 |
array_shift($breaks); |
} |
$record = 0x001b; // Record identifier |
$cbrk = count($breaks); // Number of page breaks |
$length = ($cbrk + 1) * 2; // Bytes to follow |
$header = pack("vv", $record, $length); |
$data = pack("v", $cbrk); |
// Append each page break |
foreach($breaks as $break) { |
$data .= pack("v", $break); |
} |
$this->_prepend($header.$data); |
} |
/** |
* Write the VERTICALPAGEBREAKS BIFF record. |
* |
* @access private |
*/ |
function _storeVbreak() |
{ |
// Return if the user hasn't specified pagebreaks |
if (empty($this->_vbreaks)) { |
return; |
} |
// 1000 vertical pagebreaks appears to be an internal Excel 5 limit. |
// It is slightly higher in Excel 97/200, approx. 1026 |
$breaks = array_slice($this->_vbreaks,0,1000); |
// Sort and filter array of page breaks |
sort($breaks,SORT_NUMERIC); |
if ($breaks[0] == 0) { // don't use first break if it's 0 |
array_shift($breaks); |
} |
$record = 0x001a; // Record identifier |
$cbrk = count($breaks); // Number of page breaks |
$length = ($cbrk + 1) * 2; // Bytes to follow |
$header = pack("vv", $record, $length); |
$data = pack("v", $cbrk); |
// Append each page break |
foreach ($breaks as $break) { |
$data .= pack("v", $break); |
} |
$this->_prepend($header.$data); |
} |
/** |
* Set the Biff PROTECT record to indicate that the worksheet is protected. |
* |
* @access private |
*/ |
function _storeProtect() |
{ |
// Exit unless sheet protection has been specified |
if ($this->_protect == 0) { |
return; |
} |
$record = 0x0012; // Record identifier |
$length = 0x0002; // Bytes to follow |
$fLock = $this->_protect; // Worksheet is protected |
$header = pack("vv", $record, $length); |
$data = pack("v", $fLock); |
$this->_prepend($header.$data); |
} |
/** |
* Write the worksheet PASSWORD record. |
* |
* @access private |
*/ |
function _storePassword() |
{ |
// Exit unless sheet protection and password have been specified |
if (($this->_protect == 0) or (!isset($this->_password))) { |
return; |
} |
$record = 0x0013; // Record identifier |
$length = 0x0002; // Bytes to follow |
$wPassword = $this->_password; // Encoded password |
$header = pack("vv", $record, $length); |
$data = pack("v", $wPassword); |
$this->_prepend($header.$data); |
} |
/** |
* Insert a 24bit bitmap image in a worksheet. |
* |
* @access public |
* @param integer $row The row we are going to insert the bitmap into |
* @param integer $col The column we are going to insert the bitmap into |
* @param string $bitmap The bitmap filename |
* @param integer $x The horizontal position (offset) of the image inside the cell. |
* @param integer $y The vertical position (offset) of the image inside the cell. |
* @param integer $scale_x The horizontal scale |
* @param integer $scale_y The vertical scale |
*/ |
function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) |
{ |
$bitmap_array = $this->_processBitmap($bitmap); |
if ($this->isError($bitmap_array)) |
{ |
$this->writeString($row, $col, $bitmap_array->getMessage()); |
return; |
} |
list($width, $height, $size, $data) = $bitmap_array; //$this->_processBitmap($bitmap); |
// Scale the frame of the image. |
$width *= $scale_x; |
$height *= $scale_y; |
// Calculate the vertices of the image and write the OBJ record |
$this->_positionImage($col, $row, $x, $y, $width, $height); |
// Write the IMDATA record to store the bitmap data |
$record = 0x007f; |
$length = 8 + $size; |
$cf = 0x09; |
$env = 0x01; |
$lcb = $size; |
$header = pack("vvvvV", $record, $length, $cf, $env, $lcb); |
$this->_append($header.$data); |
} |
/** |
* Calculate the vertices that define the position of the image as required by |
* the OBJ record. |
* |
* +------------+------------+ |
* | A | B | |
* +-----+------------+------------+ |
* | |(x1,y1) | | |
* | 1 |(A1)._______|______ | |
* | | | | | |
* | | | | | |
* +-----+----| BITMAP |-----+ |
* | | | | | |
* | 2 | |______________. | |
* | | | (B2)| |
* | | | (x2,y2)| |
* +---- +------------+------------+ |
* |
* Example of a bitmap that covers some of the area from cell A1 to cell B2. |
* |
* Based on the width and height of the bitmap we need to calculate 8 vars: |
* $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. |
* The width and height of the cells are also variable and have to be taken into |
* account. |
* The values of $col_start and $row_start are passed in from the calling |
* function. The values of $col_end and $row_end are calculated by subtracting |
* the width and height of the bitmap from the width and height of the |
* underlying cells. |
* The vertices are expressed as a percentage of the underlying cell width as |
* follows (rhs values are in pixels): |
* |
* x1 = X / W *1024 |
* y1 = Y / H *256 |
* x2 = (X-1) / W *1024 |
* y2 = (Y-1) / H *256 |
* |
* Where: X is distance from the left side of the underlying cell |
* Y is distance from the top of the underlying cell |
* W is the width of the cell |
* H is the height of the cell |
* |
* @access private |
* @note the SDK incorrectly states that the height should be expressed as a |
* percentage of 1024. |
* @param integer $col_start Col containing upper left corner of object |
* @param integer $row_start Row containing top left corner of object |
* @param integer $x1 Distance to left side of object |
* @param integer $y1 Distance to top of object |
* @param integer $width Width of image frame |
* @param integer $height Height of image frame |
*/ |
function _positionImage($col_start, $row_start, $x1, $y1, $width, $height) |
{ |
// Initialise end cell to the same as the start cell |
$col_end = $col_start; // Col containing lower right corner of object |
$row_end = $row_start; // Row containing bottom right corner of object |
// Zero the specified offset if greater than the cell dimensions |
if ($x1 >= $this->_sizeCol($col_start)) |
{ |
$x1 = 0; |
} |
if ($y1 >= $this->_sizeRow($row_start)) |
{ |
$y1 = 0; |
} |
$width = $width + $x1 -1; |
$height = $height + $y1 -1; |
// Subtract the underlying cell widths to find the end cell of the image |
while ($width >= $this->_sizeCol($col_end)) { |
$width -= $this->_sizeCol($col_end); |
$col_end++; |
} |
// Subtract the underlying cell heights to find the end cell of the image |
while ($height >= $this->_sizeRow($row_end)) { |
$height -= $this->_sizeRow($row_end); |
$row_end++; |
} |
// Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell |
// with zero eight or width. |
// |
if ($this->_sizeCol($col_start) == 0) |
return; |
if ($this->_sizeCol($col_end) == 0) |
return; |
if ($this->_sizeRow($row_start) == 0) |
return; |
if ($this->_sizeRow($row_end) == 0) |
return; |
// Convert the pixel values to the percentage value expected by Excel |
$x1 = $x1 / $this->_sizeCol($col_start) * 1024; |
$y1 = $y1 / $this->_sizeRow($row_start) * 256; |
$x2 = $width / $this->_sizeCol($col_end) * 1024; // Distance to right side of object |
$y2 = $height / $this->_sizeRow($row_end) * 256; // Distance to bottom of object |
$this->_storeObjPicture( $col_start, $x1, |
$row_start, $y1, |
$col_end, $x2, |
$row_end, $y2 |
); |
} |
/** |
* Convert the width of a cell from user's units to pixels. By interpolation |
* the relationship is: y = 7x +5. If the width hasn't been set by the user we |
* use the default value. If the col is hidden we use a value of zero. |
* |
* @access private |
* @param integer $col The column |
* @return integer The width in pixels |
*/ |
function _sizeCol($col) |
{ |
// Look up the cell value to see if it has been changed |
if (isset($this->col_sizes[$col])) { |
if ($this->col_sizes[$col] == 0) { |
return(0); |
} |
else { |
return(floor(7 * $this->col_sizes[$col] + 5)); |
} |
} |
else { |
return(64); |
} |
} |
/** |
* Convert the height of a cell from user's units to pixels. By interpolation |
* the relationship is: y = 4/3x. If the height hasn't been set by the user we |
* use the default value. If the row is hidden we use a value of zero. (Not |
* possible to hide row yet). |
* |
* @access private |
* @param integer $row The row |
* @return integer The width in pixels |
*/ |
function _sizeRow($row) |
{ |
// Look up the cell value to see if it has been changed |
if (isset($this->row_sizes[$row])) { |
if ($this->row_sizes[$row] == 0) { |
return(0); |
} |
else { |
return(floor(4/3 * $this->row_sizes[$row])); |
} |
} |
else { |
return(17); |
} |
} |
/** |
* Store the OBJ record that precedes an IMDATA record. This could be generalise |
* to support other Excel objects. |
* |
* @access private |
* @param integer $colL Column containing upper left corner of object |
* @param integer $dxL Distance from left side of cell |
* @param integer $rwT Row containing top left corner of object |
* @param integer $dyT Distance from top of cell |
* @param integer $colR Column containing lower right corner of object |
* @param integer $dxR Distance from right of cell |
* @param integer $rwB Row containing bottom right corner of object |
* @param integer $dyB Distance from bottom of cell |
*/ |
function _storeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB) |
{ |
$record = 0x005d; // Record identifier |
$length = 0x003c; // Bytes to follow |
$cObj = 0x0001; // Count of objects in file (set to 1) |
$OT = 0x0008; // Object type. 8 = Picture |
$id = 0x0001; // Object ID |
$grbit = 0x0614; // Option flags |
$cbMacro = 0x0000; // Length of FMLA structure |
$Reserved1 = 0x0000; // Reserved |
$Reserved2 = 0x0000; // Reserved |
$icvBack = 0x09; // Background colour |
$icvFore = 0x09; // Foreground colour |
$fls = 0x00; // Fill pattern |
$fAuto = 0x00; // Automatic fill |
$icv = 0x08; // Line colour |
$lns = 0xff; // Line style |
$lnw = 0x01; // Line weight |
$fAutoB = 0x00; // Automatic border |
$frs = 0x0000; // Frame style |
$cf = 0x0009; // Image format, 9 = bitmap |
$Reserved3 = 0x0000; // Reserved |
$cbPictFmla = 0x0000; // Length of FMLA structure |
$Reserved4 = 0x0000; // Reserved |
$grbit2 = 0x0001; // Option flags |
$Reserved5 = 0x0000; // Reserved |
$header = pack("vv", $record, $length); |
$data = pack("V", $cObj); |
$data .= pack("v", $OT); |
$data .= pack("v", $id); |
$data .= pack("v", $grbit); |
$data .= pack("v", $colL); |
$data .= pack("v", $dxL); |
$data .= pack("v", $rwT); |
$data .= pack("v", $dyT); |
$data .= pack("v", $colR); |
$data .= pack("v", $dxR); |
$data .= pack("v", $rwB); |
$data .= pack("v", $dyB); |
$data .= pack("v", $cbMacro); |
$data .= pack("V", $Reserved1); |
$data .= pack("v", $Reserved2); |
$data .= pack("C", $icvBack); |
$data .= pack("C", $icvFore); |
$data .= pack("C", $fls); |
$data .= pack("C", $fAuto); |
$data .= pack("C", $icv); |
$data .= pack("C", $lns); |
$data .= pack("C", $lnw); |
$data .= pack("C", $fAutoB); |
$data .= pack("v", $frs); |
$data .= pack("V", $cf); |
$data .= pack("v", $Reserved3); |
$data .= pack("v", $cbPictFmla); |
$data .= pack("v", $Reserved4); |
$data .= pack("v", $grbit2); |
$data .= pack("V", $Reserved5); |
$this->_append($header.$data); |
} |
/** |
* Convert a 24 bit bitmap into the modified internal format used by Windows. |
* This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the |
* MSDN library. |
* |
* @access private |
* @param string $bitmap The bitmap to process |
* @return array Array with data and properties of the bitmap |
*/ |
function _processBitmap($bitmap) |
{ |
// Open file. |
$bmp_fd = @fopen($bitmap,"rb"); |
if (!$bmp_fd) { |
return($this->raiseError("Couldn't import $bitmap")); |
} |
// Slurp the file into a string. |
$data = fread($bmp_fd, filesize($bitmap)); |
// Check that the file is big enough to be a bitmap. |
if (strlen($data) <= 0x36) { |
return($this->raiseError("$bitmap doesn't contain enough data.\n")); |
} |
// The first 2 bytes are used to identify the bitmap. |
$identity = unpack("A2", $data); |
if ($identity[''] != "BM") { |
return($this->raiseError("$bitmap doesn't appear to be a valid bitmap image.\n")); |
} |
// Remove bitmap data: ID. |
$data = substr($data, 2); |
// Read and remove the bitmap size. This is more reliable than reading |
// the data size at offset 0x22. |
// |
$size_array = unpack("V", substr($data, 0, 4)); |
$size = $size_array['']; |
$data = substr($data, 4); |
$size -= 0x36; // Subtract size of bitmap header. |
$size += 0x0C; // Add size of BIFF header. |
// Remove bitmap data: reserved, offset, header length. |
$data = substr($data, 12); |
// Read and remove the bitmap width and height. Verify the sizes. |
$width_and_height = unpack("V2", substr($data, 0, 8)); |
$width = $width_and_height[1]; |
$height = $width_and_height[2]; |
$data = substr($data, 8); |
if ($width > 0xFFFF) { |
return($this->raiseError("$bitmap: largest image width supported is 65k.\n")); |
} |
if ($height > 0xFFFF) { |
return($this->raiseError("$bitmap: largest image height supported is 65k.\n")); |
} |
// Read and remove the bitmap planes and bpp data. Verify them. |
$planes_and_bitcount = unpack("v2", substr($data, 0, 4)); |
$data = substr($data, 4); |
if ($planes_and_bitcount[2] != 24) { // Bitcount |
return($this->raiseError("$bitmap isn't a 24bit true color bitmap.\n")); |
} |
if ($planes_and_bitcount[1] != 1) { |
return($this->raiseError("$bitmap: only 1 plane nupported in bitmap image.\n")); |
} |
// Read and remove the bitmap compression. Verify compression. |
$compression = unpack("V", substr($data, 0, 4)); |
$data = substr($data, 4); |
//$compression = 0; |
if ($compression[""] != 0) { |
return($this->raiseError("$bitmap: compression not supported in bitmap image.\n")); |
} |
// Remove bitmap data: data size, hres, vres, colours, imp. colours. |
$data = substr($data, 20); |
// Add the BITMAPCOREHEADER data |
$header = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); |
$data = $header . $data; |
return (array($width, $height, $size, $data)); |
} |
/** |
* Store the window zoom factor. This should be a reduced fraction but for |
* simplicity we will store all fractions with a numerator of 100. |
* |
* @access private |
*/ |
function _storeZoom() |
{ |
// If scale is 100 we don't need to write a record |
if ($this->_zoom == 100) { |
return; |
} |
$record = 0x00A0; // Record identifier |
$length = 0x0004; // Bytes to follow |
$header = pack("vv", $record, $length); |
$data = pack("vv", $this->_zoom, 100); |
$this->_append($header.$data); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Spreadsheet/Excel/Writer/.directory |
---|
New file |
0,0 → 1,5 |
[Dolphin] |
Timestamp=2010,10,19,15,2,8 |
[Settings] |
ShowDotFiles=true |
/branches/v1.6-croc/jrest/lib/Spreadsheet/Excel/Writer/OLEwriter.php |
---|
New file |
0,0 → 1,428 |
<?php |
/* |
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com> |
* |
* The majority of this is _NOT_ my code. I simply ported it from the |
* PERL Spreadsheet::WriteExcel module. |
* |
* The author of the Spreadsheet::WriteExcel module is John McNamara |
* <jmcnamara@cpan.org> |
* |
* I _DO_ maintain this code, and John McNamara has nothing to do with the |
* porting of this code to PHP. Any questions directly related to this |
* class library should be directed to me. |
* |
* License Information: |
* |
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets |
* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
* License as published by the Free Software Foundation; either |
* version 2.1 of the License, or (at your option) any later version. |
* |
* This library is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Lesser General Public License for more details. |
* |
* You should have received a copy of the GNU Lesser General Public |
* License along with this library; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
//require_once('PEAR.php'); |
/** |
* Class for creating OLE streams for Excel Spreadsheets |
* |
* @author Xavier Noguer <xnoguer@rezebra.com> |
* @category FileFormats |
* @package Spreadsheet_Excel_Writer |
*/ |
class Spreadsheet_Excel_Writer_OLEwriter extends PEAR |
{ |
/** |
* Filename for the OLE stream |
* @var string |
* @see _initialize() |
*/ |
var $_OLEfilename; |
/** |
* Filehandle for the OLE stream |
* @var resource |
*/ |
var $_filehandle; |
/** |
* Name of the temporal file in case OLE stream goes to stdout |
* @var string |
*/ |
var $_tmp_filename; |
/** |
* Variable for preventing closing two times |
* @var integer |
*/ |
var $_fileclosed; |
/** |
* Size of the data to be written to the OLE stream |
* @var integer |
*/ |
var $_biffsize; |
/** |
* Real data size to be written to the OLE stream |
* @var integer |
*/ |
var $_booksize; |
/** |
* Number of big blocks in the OLE stream |
* @var integer |
*/ |
var $_big_blocks; |
/** |
* Number of list blocks in the OLE stream |
* @var integer |
*/ |
var $_list_blocks; |
/** |
* Number of big blocks in the OLE stream |
* @var integer |
*/ |
var $_root_start; |
/** |
* Constructor for the OLEwriter class |
* |
* @param string $OLEfilename the name of the file for the OLE stream |
*/ |
function Spreadsheet_Excel_Writer_OLEwriter($OLEfilename) |
{ |
$this->_OLEfilename = $OLEfilename; |
$this->_filehandle = ""; |
$this->_tmp_filename = ""; |
$this->_fileclosed = 0; |
$this->_biff_only = 0; |
//$this->_size_allowed = 0; |
$this->_biffsize = 0; |
$this->_booksize = 0; |
$this->_big_blocks = 0; |
$this->_list_blocks = 0; |
$this->_root_start = 0; |
//$this->_block_count = 4; |
$this->_initialize(); |
} |
/** |
* Check for a valid filename and store the filehandle. |
* Filehandle "-" writes to STDOUT |
* |
* @access private |
*/ |
function _initialize() |
{ |
$OLEfile = $this->_OLEfilename; |
if(($OLEfile == '-') or ($OLEfile == '')) |
{ |
$this->_tmp_filename = tempnam("/tmp", "OLEwriter"); |
$fh = fopen($this->_tmp_filename,"wb"); |
if ($fh == false) { |
$this->raiseError("Can't create temporary file."); |
} |
} |
else |
{ |
// Create a new file, open for writing (in binmode) |
$fh = fopen($OLEfile,"wb"); |
if ($fh == false) { |
$this->raiseError("Can't open $OLEfile. It may be in use or protected."); |
} |
} |
// Store filehandle |
$this->_filehandle = $fh; |
} |
/** |
* Set the size of the data to be written to the OLE stream. |
* The maximun size comes from this: |
* $big_blocks = (109 depot block x (128 -1 marker word) |
* - (1 x end words)) = 13842 |
* $maxsize = $big_blocks * 512 bytes = 7087104 |
* |
* @access public |
* @see Spreadsheet_Excel_Writer_Workbook::store_OLE_file() |
* @param integer $biffsize The size of the data to be written to the OLE stream |
* @return integer 1 for success |
*/ |
function setSize($biffsize) |
{ |
$maxsize = 7087104; // TODO: extend max size |
if ($biffsize > $maxsize) { |
$this->raiseError("Maximum file size, $maxsize, exceeded."); |
} |
$this->_biffsize = $biffsize; |
// Set the min file size to 4k to avoid having to use small blocks |
if ($biffsize > 4096) { |
$this->_booksize = $biffsize; |
} |
else { |
$this->_booksize = 4096; |
} |
//$this->_size_allowed = 1; |
return(1); |
} |
/** |
* Calculate various sizes needed for the OLE stream |
* |
* @access private |
*/ |
function _calculateSizes() |
{ |
$datasize = $this->_booksize; |
if ($datasize % 512 == 0) { |
$this->_big_blocks = $datasize/512; |
} |
else { |
$this->_big_blocks = floor($datasize/512) + 1; |
} |
// There are 127 list blocks and 1 marker blocks for each big block |
// depot + 1 end of chain block |
$this->_list_blocks = floor(($this->_big_blocks)/127) + 1; |
$this->_root_start = $this->_big_blocks; |
} |
/** |
* Write root entry, big block list and close the filehandle. |
* This routine is used to explicitly close the open filehandle without |
* having to wait for DESTROY. |
* |
* @access public |
* @see Spreadsheet_Excel_Writer_Workbook::store_OLE_file() |
*/ |
function close() |
{ |
//return if not $this->{_size_allowed}; |
$this->_writePadding(); |
$this->_writePropertyStorage(); |
$this->_writeBigBlockDepot(); |
// Close the filehandle |
fclose($this->_filehandle); |
if(($this->_OLEfilename == '-') or ($this->_OLEfilename == '')) |
{ |
$fh = fopen($this->_tmp_filename, "rb"); |
if ($fh == false) { |
$this->raiseError("Can't read temporary file."); |
} |
fpassthru($fh); |
@unlink($this->_tmp_filename); |
} |
$this->_fileclosed = 1; |
} |
/** |
* Write BIFF data to OLE file. |
* |
* @param string $data string of bytes to be written |
*/ |
function write($data) |
{ |
fwrite($this->_filehandle,$data,strlen($data)); |
} |
/** |
* Write OLE header block. |
*/ |
function writeHeader() |
{ |
$this->_calculateSizes(); |
$root_start = $this->_root_start; |
$num_lists = $this->_list_blocks; |
$id = pack("nnnn", 0xD0CF, 0x11E0, 0xA1B1, 0x1AE1); |
$unknown1 = pack("VVVV", 0x00, 0x00, 0x00, 0x00); |
$unknown2 = pack("vv", 0x3E, 0x03); |
$unknown3 = pack("v", -2); |
$unknown4 = pack("v", 0x09); |
$unknown5 = pack("VVV", 0x06, 0x00, 0x00); |
$num_bbd_blocks = pack("V", $num_lists); |
$root_startblock = pack("V", $root_start); |
$unknown6 = pack("VV", 0x00, 0x1000); |
$sbd_startblock = pack("V", -2); |
$unknown7 = pack("VVV", 0x00, -2 ,0x00); |
$unused = pack("V", -1); |
fwrite($this->_filehandle,$id); |
fwrite($this->_filehandle,$unknown1); |
fwrite($this->_filehandle,$unknown2); |
fwrite($this->_filehandle,$unknown3); |
fwrite($this->_filehandle,$unknown4); |
fwrite($this->_filehandle,$unknown5); |
fwrite($this->_filehandle,$num_bbd_blocks); |
fwrite($this->_filehandle,$root_startblock); |
fwrite($this->_filehandle,$unknown6); |
fwrite($this->_filehandle,$sbd_startblock); |
fwrite($this->_filehandle,$unknown7); |
for($i=1; $i <= $num_lists; $i++) |
{ |
$root_start++; |
fwrite($this->_filehandle,pack("V",$root_start)); |
} |
for($i = $num_lists; $i <=108; $i++) |
{ |
fwrite($this->_filehandle,$unused); |
} |
} |
/** |
* Write big block depot. |
* |
* @access private |
*/ |
function _writeBigBlockDepot() |
{ |
$num_blocks = $this->_big_blocks; |
$num_lists = $this->_list_blocks; |
$total_blocks = $num_lists *128; |
$used_blocks = $num_blocks + $num_lists +2; |
$marker = pack("V", -3); |
$end_of_chain = pack("V", -2); |
$unused = pack("V", -1); |
for($i=1; $i < $num_blocks; $i++) |
{ |
fwrite($this->_filehandle,pack("V",$i)); |
} |
fwrite($this->_filehandle,$end_of_chain); |
fwrite($this->_filehandle,$end_of_chain); |
for($i=0; $i < $num_lists; $i++) |
{ |
fwrite($this->_filehandle,$marker); |
} |
for($i=$used_blocks; $i <= $total_blocks; $i++) |
{ |
fwrite($this->_filehandle,$unused); |
} |
} |
/** |
* Write property storage. TODO: add summary sheets |
* |
* @access private |
*/ |
function _writePropertyStorage() |
{ |
//$rootsize = -2; |
/*************** name type dir start size */ |
$this->_writePps("Root Entry", 0x05, 1, -2, 0x00); |
$this->_writePps("Book", 0x02, -1, 0x00, $this->_booksize); |
$this->_writePps('', 0x00, -1, 0x00, 0x0000); |
$this->_writePps('', 0x00, -1, 0x00, 0x0000); |
} |
/** |
* Write property sheet in property storage |
* |
* @param string $name name of the property storage. |
* @param integer $type type of the property storage. |
* @param integer $dir dir of the property storage. |
* @param integer $start start of the property storage. |
* @param integer $size size of the property storage. |
* @access private |
*/ |
function _writePps($name,$type,$dir,$start,$size) |
{ |
$length = 0; |
$rawname = ''; |
if ($name != '') |
{ |
$name = $name . "\0"; |
for($i=0;$i<strlen($name);$i++) |
{ |
// Simulate a Unicode string |
$rawname .= pack("H*",dechex(ord($name{$i}))).pack("C",0); |
} |
$length = strlen($name) * 2; |
} |
$zero = pack("C", 0); |
$pps_sizeofname = pack("v", $length); // 0x40 |
$pps_type = pack("v", $type); // 0x42 |
$pps_prev = pack("V", -1); // 0x44 |
$pps_next = pack("V", -1); // 0x48 |
$pps_dir = pack("V", $dir); // 0x4c |
$unknown1 = pack("V", 0); |
$pps_ts1s = pack("V", 0); // 0x64 |
$pps_ts1d = pack("V", 0); // 0x68 |
$pps_ts2s = pack("V", 0); // 0x6c |
$pps_ts2d = pack("V", 0); // 0x70 |
$pps_sb = pack("V", $start); // 0x74 |
$pps_size = pack("V", $size); // 0x78 |
fwrite($this->_filehandle,$rawname); |
for($i=0; $i < (64 -$length); $i++) { |
fwrite($this->_filehandle,$zero); |
} |
fwrite($this->_filehandle,$pps_sizeofname); |
fwrite($this->_filehandle,$pps_type); |
fwrite($this->_filehandle,$pps_prev); |
fwrite($this->_filehandle,$pps_next); |
fwrite($this->_filehandle,$pps_dir); |
for($i=0; $i < 5; $i++) { |
fwrite($this->_filehandle,$unknown1); |
} |
fwrite($this->_filehandle,$pps_ts1s); |
fwrite($this->_filehandle,$pps_ts1d); |
fwrite($this->_filehandle,$pps_ts2d); |
fwrite($this->_filehandle,$pps_ts2d); |
fwrite($this->_filehandle,$pps_sb); |
fwrite($this->_filehandle,$pps_size); |
fwrite($this->_filehandle,$unknown1); |
} |
/** |
* Pad the end of the file |
* |
* @access private |
*/ |
function _writePadding() |
{ |
$biffsize = $this->_biffsize; |
if ($biffsize < 4096) { |
$min_size = 4096; |
} |
else { |
$min_size = 512; |
} |
if ($biffsize % $min_size != 0) |
{ |
$padding = $min_size - ($biffsize % $min_size); |
for($i=0; $i < $padding; $i++) { |
fwrite($this->_filehandle,"\0"); |
} |
} |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Spreadsheet/Excel/Writer/Parser.php |
---|
New file |
0,0 → 1,1551 |
<?php |
/** |
* Class for parsing Excel formulas |
* |
* License Information: |
* |
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets |
* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
* License as published by the Free Software Foundation; either |
* version 2.1 of the License, or (at your option) any later version. |
* |
* This library is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Lesser General Public License for more details. |
* |
* You should have received a copy of the GNU Lesser General Public |
* License along with this library; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
/** |
* @const SPREADSHEET_EXCEL_WRITER_ADD token identifier for character "+" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_ADD',"+"); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_SUB token identifier for character "-" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_SUB',"-"); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_MUL token identifier for character "*" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_MUL',"*"); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_DIV token identifier for character "/" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_DIV',"/"); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_OPEN token identifier for character "(" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_OPEN',"("); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_CLOSE token identifier for character ")" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_CLOSE',")"); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_COMA token identifier for character "," |
*/ |
define('SPREADSHEET_EXCEL_WRITER_COMA',","); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_GT token identifier for character ">" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_GT',">"); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_LT token identifier for character "<" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_LT',"<"); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_LE token identifier for character "<=" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_LE',"<="); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_GE token identifier for character ">=" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_GE',">="); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_EQ token identifier for character "=" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_EQ',"="); |
/** |
* @const SPREADSHEET_EXCEL_WRITER_NE token identifier for character "<>" |
*/ |
define('SPREADSHEET_EXCEL_WRITER_NE',"<>"); |
//require_once('PEAR.php'); |
/** |
* Class for parsing Excel formulas |
* |
* @author Xavier Noguer <xnoguer@rezebra.com> |
* @category FileFormats |
* @package Spreadsheet_Excel_Writer |
*/ |
class Spreadsheet_Excel_Writer_Parser extends PEAR |
{ |
/** |
* The index of the character we are currently looking at |
* @var integer |
*/ |
var $_current_char; |
/** |
* The token we are working on. |
* @var string |
*/ |
var $_current_token; |
/** |
* The formula to parse |
* @var string |
*/ |
var $_formula; |
/** |
* The character ahead of the current char |
* @var string |
*/ |
var $_lookahead; |
/** |
* The parse tree to be generated |
* @var string |
*/ |
var $_parse_tree; |
/** |
* The byte order. 1 => big endian, 0 => little endian. |
* @var integer |
*/ |
var $_byte_order; |
/** |
* Number of arguments for the current function |
* @var integer |
*/ |
var $_func_args; |
/** |
* Array of external sheets |
* @var array |
*/ |
var $_ext_sheets; |
/** |
* The class constructor |
* |
* @param integer $byte_order The byte order (Little endian or Big endian) of the architecture |
(optional). 1 => big endian, 0 (default) => little endian. |
*/ |
function Spreadsheet_Excel_Writer_Parser($byte_order = 0) |
{ |
$this->_current_char = 0; |
$this->_current_token = ''; // The token we are working on. |
$this->_formula = ""; // The formula to parse. |
$this->_lookahead = ''; // The character ahead of the current char. |
$this->_parse_tree = ''; // The parse tree to be generated. |
$this->_initializeHashes(); // Initialize the hashes: ptg's and function's ptg's |
$this->_byte_order = $byte_order; // Little Endian or Big Endian |
$this->_func_args = 0; // Number of arguments for the current function |
$this->_ext_sheets = array(); |
} |
/** |
* Initialize the ptg and function hashes. |
* |
* @access private |
*/ |
function _initializeHashes() |
{ |
// The Excel ptg indices |
$this->ptg = array( |
'ptgExp' => 0x01, |
'ptgTbl' => 0x02, |
'ptgAdd' => 0x03, |
'ptgSub' => 0x04, |
'ptgMul' => 0x05, |
'ptgDiv' => 0x06, |
'ptgPower' => 0x07, |
'ptgConcat' => 0x08, |
'ptgLT' => 0x09, |
'ptgLE' => 0x0A, |
'ptgEQ' => 0x0B, |
'ptgGE' => 0x0C, |
'ptgGT' => 0x0D, |
'ptgNE' => 0x0E, |
'ptgIsect' => 0x0F, |
'ptgUnion' => 0x10, |
'ptgRange' => 0x11, |
'ptgUplus' => 0x12, |
'ptgUminus' => 0x13, |
'ptgPercent' => 0x14, |
'ptgParen' => 0x15, |
'ptgMissArg' => 0x16, |
'ptgStr' => 0x17, |
'ptgAttr' => 0x19, |
'ptgSheet' => 0x1A, |
'ptgEndSheet' => 0x1B, |
'ptgErr' => 0x1C, |
'ptgBool' => 0x1D, |
'ptgInt' => 0x1E, |
'ptgNum' => 0x1F, |
'ptgArray' => 0x20, |
'ptgFunc' => 0x21, |
'ptgFuncVar' => 0x22, |
'ptgName' => 0x23, |
'ptgRef' => 0x24, |
'ptgArea' => 0x25, |
'ptgMemArea' => 0x26, |
'ptgMemErr' => 0x27, |
'ptgMemNoMem' => 0x28, |
'ptgMemFunc' => 0x29, |
'ptgRefErr' => 0x2A, |
'ptgAreaErr' => 0x2B, |
'ptgRefN' => 0x2C, |
'ptgAreaN' => 0x2D, |
'ptgMemAreaN' => 0x2E, |
'ptgMemNoMemN' => 0x2F, |
'ptgNameX' => 0x39, |
'ptgRef3d' => 0x3A, |
'ptgArea3d' => 0x3B, |
'ptgRefErr3d' => 0x3C, |
'ptgAreaErr3d' => 0x3D, |
'ptgArrayV' => 0x40, |
'ptgFuncV' => 0x41, |
'ptgFuncVarV' => 0x42, |
'ptgNameV' => 0x43, |
'ptgRefV' => 0x44, |
'ptgAreaV' => 0x45, |
'ptgMemAreaV' => 0x46, |
'ptgMemErrV' => 0x47, |
'ptgMemNoMemV' => 0x48, |
'ptgMemFuncV' => 0x49, |
'ptgRefErrV' => 0x4A, |
'ptgAreaErrV' => 0x4B, |
'ptgRefNV' => 0x4C, |
'ptgAreaNV' => 0x4D, |
'ptgMemAreaNV' => 0x4E, |
'ptgMemNoMemN' => 0x4F, |
'ptgFuncCEV' => 0x58, |
'ptgNameXV' => 0x59, |
'ptgRef3dV' => 0x5A, |
'ptgArea3dV' => 0x5B, |
'ptgRefErr3dV' => 0x5C, |
'ptgAreaErr3d' => 0x5D, |
'ptgArrayA' => 0x60, |
'ptgFuncA' => 0x61, |
'ptgFuncVarA' => 0x62, |
'ptgNameA' => 0x63, |
'ptgRefA' => 0x64, |
'ptgAreaA' => 0x65, |
'ptgMemAreaA' => 0x66, |
'ptgMemErrA' => 0x67, |
'ptgMemNoMemA' => 0x68, |
'ptgMemFuncA' => 0x69, |
'ptgRefErrA' => 0x6A, |
'ptgAreaErrA' => 0x6B, |
'ptgRefNA' => 0x6C, |
'ptgAreaNA' => 0x6D, |
'ptgMemAreaNA' => 0x6E, |
'ptgMemNoMemN' => 0x6F, |
'ptgFuncCEA' => 0x78, |
'ptgNameXA' => 0x79, |
'ptgRef3dA' => 0x7A, |
'ptgArea3dA' => 0x7B, |
'ptgRefErr3dA' => 0x7C, |
'ptgAreaErr3d' => 0x7D |
); |
// Thanks to Michael Meeks and Gnumeric for the initial arg values. |
// |
// The following hash was generated by "function_locale.pl" in the distro. |
// Refer to function_locale.pl for non-English function names. |
// |
// The array elements are as follow: |
// ptg: The Excel function ptg code. |
// args: The number of arguments that the function takes: |
// >=0 is a fixed number of arguments. |
// -1 is a variable number of arguments. |
// class: The reference, value or array class of the function args. |
// vol: The function is volatile. |
// |
$this->_functions = array( |
// function ptg args class vol |
'COUNT' => array( 0, -1, 0, 0 ), |
'IF' => array( 1, -1, 1, 0 ), |
'ISNA' => array( 2, 1, 1, 0 ), |
'ISERROR' => array( 3, 1, 1, 0 ), |
'SUM' => array( 4, -1, 0, 0 ), |
'AVERAGE' => array( 5, -1, 0, 0 ), |
'MIN' => array( 6, -1, 0, 0 ), |
'MAX' => array( 7, -1, 0, 0 ), |
'ROW' => array( 8, -1, 0, 0 ), |
'COLUMN' => array( 9, -1, 0, 0 ), |
'NA' => array( 10, 0, 0, 0 ), |
'NPV' => array( 11, -1, 1, 0 ), |
'STDEV' => array( 12, -1, 0, 0 ), |
'DOLLAR' => array( 13, -1, 1, 0 ), |
'FIXED' => array( 14, -1, 1, 0 ), |
'SIN' => array( 15, 1, 1, 0 ), |
'COS' => array( 16, 1, 1, 0 ), |
'TAN' => array( 17, 1, 1, 0 ), |
'ATAN' => array( 18, 1, 1, 0 ), |
'PI' => array( 19, 0, 1, 0 ), |
'SQRT' => array( 20, 1, 1, 0 ), |
'EXP' => array( 21, 1, 1, 0 ), |
'LN' => array( 22, 1, 1, 0 ), |
'LOG10' => array( 23, 1, 1, 0 ), |
'ABS' => array( 24, 1, 1, 0 ), |
'INT' => array( 25, 1, 1, 0 ), |
'SIGN' => array( 26, 1, 1, 0 ), |
'ROUND' => array( 27, 2, 1, 0 ), |
'LOOKUP' => array( 28, -1, 0, 0 ), |
'INDEX' => array( 29, -1, 0, 1 ), |
'REPT' => array( 30, 2, 1, 0 ), |
'MID' => array( 31, 3, 1, 0 ), |
'LEN' => array( 32, 1, 1, 0 ), |
'VALUE' => array( 33, 1, 1, 0 ), |
'TRUE' => array( 34, 0, 1, 0 ), |
'FALSE' => array( 35, 0, 1, 0 ), |
'AND' => array( 36, -1, 0, 0 ), |
'OR' => array( 37, -1, 0, 0 ), |
'NOT' => array( 38, 1, 1, 0 ), |
'MOD' => array( 39, 2, 1, 0 ), |
'DCOUNT' => array( 40, 3, 0, 0 ), |
'DSUM' => array( 41, 3, 0, 0 ), |
'DAVERAGE' => array( 42, 3, 0, 0 ), |
'DMIN' => array( 43, 3, 0, 0 ), |
'DMAX' => array( 44, 3, 0, 0 ), |
'DSTDEV' => array( 45, 3, 0, 0 ), |
'VAR' => array( 46, -1, 0, 0 ), |
'DVAR' => array( 47, 3, 0, 0 ), |
'TEXT' => array( 48, 2, 1, 0 ), |
'LINEST' => array( 49, -1, 0, 0 ), |
'TREND' => array( 50, -1, 0, 0 ), |
'LOGEST' => array( 51, -1, 0, 0 ), |
'GROWTH' => array( 52, -1, 0, 0 ), |
'PV' => array( 56, -1, 1, 0 ), |
'FV' => array( 57, -1, 1, 0 ), |
'NPER' => array( 58, -1, 1, 0 ), |
'PMT' => array( 59, -1, 1, 0 ), |
'RATE' => array( 60, -1, 1, 0 ), |
'MIRR' => array( 61, 3, 0, 0 ), |
'IRR' => array( 62, -1, 0, 0 ), |
'RAND' => array( 63, 0, 1, 1 ), |
'MATCH' => array( 64, -1, 0, 0 ), |
'DATE' => array( 65, 3, 1, 0 ), |
'TIME' => array( 66, 3, 1, 0 ), |
'DAY' => array( 67, 1, 1, 0 ), |
'MONTH' => array( 68, 1, 1, 0 ), |
'YEAR' => array( 69, 1, 1, 0 ), |
'WEEKDAY' => array( 70, -1, 1, 0 ), |
'HOUR' => array( 71, 1, 1, 0 ), |
'MINUTE' => array( 72, 1, 1, 0 ), |
'SECOND' => array( 73, 1, 1, 0 ), |
'NOW' => array( 74, 0, 1, 1 ), |
'AREAS' => array( 75, 1, 0, 1 ), |
'ROWS' => array( 76, 1, 0, 1 ), |
'COLUMNS' => array( 77, 1, 0, 1 ), |
'OFFSET' => array( 78, -1, 0, 1 ), |
'SEARCH' => array( 82, -1, 1, 0 ), |
'TRANSPOSE' => array( 83, 1, 1, 0 ), |
'TYPE' => array( 86, 1, 1, 0 ), |
'ATAN2' => array( 97, 2, 1, 0 ), |
'ASIN' => array( 98, 1, 1, 0 ), |
'ACOS' => array( 99, 1, 1, 0 ), |
'CHOOSE' => array( 100, -1, 1, 0 ), |
'HLOOKUP' => array( 101, -1, 0, 0 ), |
'VLOOKUP' => array( 102, -1, 0, 0 ), |
'ISREF' => array( 105, 1, 0, 0 ), |
'LOG' => array( 109, -1, 1, 0 ), |
'CHAR' => array( 111, 1, 1, 0 ), |
'LOWER' => array( 112, 1, 1, 0 ), |
'UPPER' => array( 113, 1, 1, 0 ), |
'PROPER' => array( 114, 1, 1, 0 ), |
'LEFT' => array( 115, -1, 1, 0 ), |
'RIGHT' => array( 116, -1, 1, 0 ), |
'EXACT' => array( 117, 2, 1, 0 ), |
'TRIM' => array( 118, 1, 1, 0 ), |
'REPLACE' => array( 119, 4, 1, 0 ), |
'SUBSTITUTE' => array( 120, -1, 1, 0 ), |
'CODE' => array( 121, 1, 1, 0 ), |
'FIND' => array( 124, -1, 1, 0 ), |
'CELL' => array( 125, -1, 0, 1 ), |
'ISERR' => array( 126, 1, 1, 0 ), |
'ISTEXT' => array( 127, 1, 1, 0 ), |
'ISNUMBER' => array( 128, 1, 1, 0 ), |
'ISBLANK' => array( 129, 1, 1, 0 ), |
'T' => array( 130, 1, 0, 0 ), |
'N' => array( 131, 1, 0, 0 ), |
'DATEVALUE' => array( 140, 1, 1, 0 ), |
'TIMEVALUE' => array( 141, 1, 1, 0 ), |
'SLN' => array( 142, 3, 1, 0 ), |
'SYD' => array( 143, 4, 1, 0 ), |
'DDB' => array( 144, -1, 1, 0 ), |
'INDIRECT' => array( 148, -1, 1, 1 ), |
'CALL' => array( 150, -1, 1, 0 ), |
'CLEAN' => array( 162, 1, 1, 0 ), |
'MDETERM' => array( 163, 1, 2, 0 ), |
'MINVERSE' => array( 164, 1, 2, 0 ), |
'MMULT' => array( 165, 2, 2, 0 ), |
'IPMT' => array( 167, -1, 1, 0 ), |
'PPMT' => array( 168, -1, 1, 0 ), |
'COUNTA' => array( 169, -1, 0, 0 ), |
'PRODUCT' => array( 183, -1, 0, 0 ), |
'FACT' => array( 184, 1, 1, 0 ), |
'DPRODUCT' => array( 189, 3, 0, 0 ), |
'ISNONTEXT' => array( 190, 1, 1, 0 ), |
'STDEVP' => array( 193, -1, 0, 0 ), |
'VARP' => array( 194, -1, 0, 0 ), |
'DSTDEVP' => array( 195, 3, 0, 0 ), |
'DVARP' => array( 196, 3, 0, 0 ), |
'TRUNC' => array( 197, -1, 1, 0 ), |
'ISLOGICAL' => array( 198, 1, 1, 0 ), |
'DCOUNTA' => array( 199, 3, 0, 0 ), |
'ROUNDUP' => array( 212, 2, 1, 0 ), |
'ROUNDDOWN' => array( 213, 2, 1, 0 ), |
'RANK' => array( 216, -1, 0, 0 ), |
'ADDRESS' => array( 219, -1, 1, 0 ), |
'DAYS360' => array( 220, -1, 1, 0 ), |
'TODAY' => array( 221, 0, 1, 1 ), |
'VDB' => array( 222, -1, 1, 0 ), |
'MEDIAN' => array( 227, -1, 0, 0 ), |
'SUMPRODUCT' => array( 228, -1, 2, 0 ), |
'SINH' => array( 229, 1, 1, 0 ), |
'COSH' => array( 230, 1, 1, 0 ), |
'TANH' => array( 231, 1, 1, 0 ), |
'ASINH' => array( 232, 1, 1, 0 ), |
'ACOSH' => array( 233, 1, 1, 0 ), |
'ATANH' => array( 234, 1, 1, 0 ), |
'DGET' => array( 235, 3, 0, 0 ), |
'INFO' => array( 244, 1, 1, 1 ), |
'DB' => array( 247, -1, 1, 0 ), |
'FREQUENCY' => array( 252, 2, 0, 0 ), |
'ERROR.TYPE' => array( 261, 1, 1, 0 ), |
'REGISTER.ID' => array( 267, -1, 1, 0 ), |
'AVEDEV' => array( 269, -1, 0, 0 ), |
'BETADIST' => array( 270, -1, 1, 0 ), |
'GAMMALN' => array( 271, 1, 1, 0 ), |
'BETAINV' => array( 272, -1, 1, 0 ), |
'BINOMDIST' => array( 273, 4, 1, 0 ), |
'CHIDIST' => array( 274, 2, 1, 0 ), |
'CHIINV' => array( 275, 2, 1, 0 ), |
'COMBIN' => array( 276, 2, 1, 0 ), |
'CONFIDENCE' => array( 277, 3, 1, 0 ), |
'CRITBINOM' => array( 278, 3, 1, 0 ), |
'EVEN' => array( 279, 1, 1, 0 ), |
'EXPONDIST' => array( 280, 3, 1, 0 ), |
'FDIST' => array( 281, 3, 1, 0 ), |
'FINV' => array( 282, 3, 1, 0 ), |
'FISHER' => array( 283, 1, 1, 0 ), |
'FISHERINV' => array( 284, 1, 1, 0 ), |
'FLOOR' => array( 285, 2, 1, 0 ), |
'GAMMADIST' => array( 286, 4, 1, 0 ), |
'GAMMAINV' => array( 287, 3, 1, 0 ), |
'CEILING' => array( 288, 2, 1, 0 ), |
'HYPGEOMDIST' => array( 289, 4, 1, 0 ), |
'LOGNORMDIST' => array( 290, 3, 1, 0 ), |
'LOGINV' => array( 291, 3, 1, 0 ), |
'NEGBINOMDIST' => array( 292, 3, 1, 0 ), |
'NORMDIST' => array( 293, 4, 1, 0 ), |
'NORMSDIST' => array( 294, 1, 1, 0 ), |
'NORMINV' => array( 295, 3, 1, 0 ), |
'NORMSINV' => array( 296, 1, 1, 0 ), |
'STANDARDIZE' => array( 297, 3, 1, 0 ), |
'ODD' => array( 298, 1, 1, 0 ), |
'PERMUT' => array( 299, 2, 1, 0 ), |
'POISSON' => array( 300, 3, 1, 0 ), |
'TDIST' => array( 301, 3, 1, 0 ), |
'WEIBULL' => array( 302, 4, 1, 0 ), |
'SUMXMY2' => array( 303, 2, 2, 0 ), |
'SUMX2MY2' => array( 304, 2, 2, 0 ), |
'SUMX2PY2' => array( 305, 2, 2, 0 ), |
'CHITEST' => array( 306, 2, 2, 0 ), |
'CORREL' => array( 307, 2, 2, 0 ), |
'COVAR' => array( 308, 2, 2, 0 ), |
'FORECAST' => array( 309, 3, 2, 0 ), |
'FTEST' => array( 310, 2, 2, 0 ), |
'INTERCEPT' => array( 311, 2, 2, 0 ), |
'PEARSON' => array( 312, 2, 2, 0 ), |
'RSQ' => array( 313, 2, 2, 0 ), |
'STEYX' => array( 314, 2, 2, 0 ), |
'SLOPE' => array( 315, 2, 2, 0 ), |
'TTEST' => array( 316, 4, 2, 0 ), |
'PROB' => array( 317, -1, 2, 0 ), |
'DEVSQ' => array( 318, -1, 0, 0 ), |
'GEOMEAN' => array( 319, -1, 0, 0 ), |
'HARMEAN' => array( 320, -1, 0, 0 ), |
'SUMSQ' => array( 321, -1, 0, 0 ), |
'KURT' => array( 322, -1, 0, 0 ), |
'SKEW' => array( 323, -1, 0, 0 ), |
'ZTEST' => array( 324, -1, 0, 0 ), |
'LARGE' => array( 325, 2, 0, 0 ), |
'SMALL' => array( 326, 2, 0, 0 ), |
'QUARTILE' => array( 327, 2, 0, 0 ), |
'PERCENTILE' => array( 328, 2, 0, 0 ), |
'PERCENTRANK' => array( 329, -1, 0, 0 ), |
'MODE' => array( 330, -1, 2, 0 ), |
'TRIMMEAN' => array( 331, 2, 0, 0 ), |
'TINV' => array( 332, 2, 1, 0 ), |
'CONCATENATE' => array( 336, -1, 1, 0 ), |
'POWER' => array( 337, 2, 1, 0 ), |
'RADIANS' => array( 342, 1, 1, 0 ), |
'DEGREES' => array( 343, 1, 1, 0 ), |
'SUBTOTAL' => array( 344, -1, 0, 0 ), |
'SUMIF' => array( 345, -1, 0, 0 ), |
'COUNTIF' => array( 346, 2, 0, 0 ), |
'COUNTBLANK' => array( 347, 1, 0, 0 ), |
'ROMAN' => array( 354, -1, 1, 0 ) |
); |
} |
/** |
* Convert a token to the proper ptg value. |
* |
* @access private |
* @param mixed $token The token to convert. |
*/ |
function _convert($token) |
{ |
if (preg_match("/^\"[^\"]{0,255}\"$/", $token)) |
{ |
return $this->_convertString($token); |
} |
elseif (is_numeric($token)) |
{ |
return $this->_convertNumber($token); |
} |
// match references like A1 or $A$1 |
elseif(preg_match('/^\$?([A-I]?[A-Z])\$?(\d+)$/',$token)) |
{ |
return($this->_convertRef2d($token)); |
} |
// match external references like Sheet1:Sheet2!A1 |
elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\![A-I]?[A-Z](\d+)$/",$token)) |
{ |
return $this->_convertRef3d($token); |
} |
// match ranges like A1:B2 |
elseif(preg_match("/^(\$)?[A-I]?[A-Z](\$)?(\d+)\:(\$)?[A-I]?[A-Z](\$)?(\d+)$/",$token)) |
{ |
return($this->_convertRange2d($token)); |
} |
// match ranges like A1..B2 |
elseif(preg_match("/^(\$)?[A-I]?[A-Z](\$)?(\d+)\.\.(\$)?[A-I]?[A-Z](\$)?(\d+)$/",$token)) |
{ |
return($this->_convertRange2d($token)); |
} |
// match external ranges like Sheet1:Sheet2!A1:B2 |
elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\!([A-I]?[A-Z])?(\d+)\:([A-I]?[A-Z])?(\d+)$/",$token)) |
{ |
return $this->_convertRange3d($token); |
} |
elseif(isset($this->ptg[$token])) // operators (including parentheses) |
{ |
return(pack("C", $this->ptg[$token])); |
} |
elseif(preg_match("/[A-Z0-9\xc0-\xdc\.]+/",$token)) |
{ |
return($this->_convertFunction($token,$this->_func_args)); |
} |
// if it's an argument, ignore the token (the argument remains) |
elseif($token == 'arg') |
{ |
$this->_func_args++; |
return(''); |
} |
// TODO: use real error codes |
$this->raiseError("Unknown token $token", 0, PEAR_ERROR_DIE); |
} |
/** |
* Convert a number token to ptgInt or ptgNum |
* |
* @access private |
* @param mixed $num an integer or double for conversion to its ptg value |
*/ |
function _convertNumber($num) |
{ |
// Integer in the range 0..2**16-1 |
if ((preg_match("/^\d+$/",$num)) and ($num <= 65535)) { |
return(pack("Cv", $this->ptg['ptgInt'], $num)); |
} |
else // A float |
{ |
if($this->_byte_order) // if it's Big Endian |
{ |
$num = strrev($num); |
} |
return(pack("Cd", $this->ptg['ptgNum'], $num)); |
} |
} |
/** |
* Convert a string token to ptgStr |
* |
* @access private |
* @param string $string A string for conversion to its ptg value |
*/ |
function _convertString($string) |
{ |
// chop away beggining and ending quotes |
$string = substr($string, 1, strlen($string) - 2); |
return pack("CC", $this->ptg['ptgStr'], strlen($string)).$string; |
} |
/** |
* Convert a function to a ptgFunc or ptgFuncVarV depending on the number of |
* args that it takes. |
* |
* @access private |
* @param string $token The name of the function for convertion to ptg value. |
* @param integer $num_args The number of arguments the function recieves. |
*/ |
function _convertFunction($token, $num_args) |
{ |
$this->_func_args = 0; // re initialize the number of arguments |
$args = $this->_functions[$token][1]; |
$volatile = $this->_functions[$token][3]; |
// Fixed number of args eg. TIME($i,$j,$k). |
if ($args >= 0) { |
return(pack("Cv", $this->ptg['ptgFuncV'], $this->_functions[$token][0])); |
} |
// Variable number of args eg. SUM($i,$j,$k, ..). |
if ($args == -1) { |
return(pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0])); |
} |
} |
/** |
* Convert an Excel range such as A1:D4 to a ptgRefV. |
* |
* @access private |
* @param string $range An Excel range in the A1:A2 or A1..A2 format. |
*/ |
function _convertRange2d($range) |
{ |
$class = 2; // as far as I know, this is magick. |
// Split the range into 2 cell refs |
if(preg_match("/^([A-I]?[A-Z])(\d+)\:([A-I]?[A-Z])(\d+)$/",$range)) { |
list($cell1, $cell2) = explode(':', $range); |
} |
elseif(preg_match("/^([A-I]?[A-Z])(\d+)\.\.([A-I]?[A-Z])(\d+)$/",$range)) { |
list($cell1, $cell2) = explode('\.\.', $range); |
} |
else { |
// TODO: use real error codes |
$this->raiseError("Unknown range separator", 0, PEAR_ERROR_DIE); |
} |
// Convert the cell references |
$cell_array1 = $this->_cellToPackedRowcol($cell1); |
if($this->isError($cell_array1)) { |
return($cell_array1); |
} |
list($row1, $col1) = $cell_array1; //$this->_cellToPackedRowcol($cell1); |
$cell_array2 = $this->_cellToPackedRowcol($cell2); |
if($this->isError($cell_array2)) { |
return($cell_array2); |
} |
list($row2, $col2) = $cell_array2; //$this->_cellToPackedRowcol($cell2); |
// The ptg value depends on the class of the ptg. |
if ($class == 0) { |
$ptgArea = pack("C", $this->ptg['ptgArea']); |
} |
elseif ($class == 1) { |
$ptgArea = pack("C", $this->ptg['ptgAreaV']); |
} |
elseif ($class == 2) { |
$ptgArea = pack("C", $this->ptg['ptgAreaA']); |
} |
else { |
// TODO: use real error codes |
$this->raiseError("Unknown class $class", 0, PEAR_ERROR_DIE); |
} |
return($ptgArea . $row1 . $row2 . $col1. $col2); |
} |
/** |
* Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to |
* a ptgArea3dV. |
* |
* @access private |
* @param string $token An Excel range in the Sheet1!A1:A2 format. |
*/ |
function _convertRange3d($token) |
{ |
$class = 2; // as far as I know, this is magick. |
// Split the ref at the ! symbol |
list($ext_ref, $range) = explode('!', $token); |
// Convert the external reference part |
$ext_ref = $this->_packExtRef($ext_ref); |
if ($this->isError($ext_ref)) { |
return $ext_ref; |
} |
// Split the range into 2 cell refs |
list($cell1, $cell2) = explode(':', $range); |
// Convert the cell references |
if (preg_match("/^(\$)?[A-I]?[A-Z](\$)?(\d+)$/", $cell1)) |
{ |
$cell_array1 = $this->_cellToPackedRowcol($cell1); |
if (PEAR::isError($cell_array1)) { |
return $cell_array1; |
} |
list($row1, $col1) = $cell_array1; |
$cell_array2 = $this->_cellToPackedRowcol($cell2); |
if (PEAR::isError($cell_array2)) { |
return $cell_array2; |
} |
list($row2, $col2) = $cell_array2; |
} |
else { // It's a columns range (like 26:27) |
$cells_array = $this->_rangeToPackedRange($cell1.':'.$cell2); |
if (PEAR::isError($cells_array)) { |
return $cells_array; |
} |
list($row1, $col1, $row2, $col2) = $cells_array; |
} |
// The ptg value depends on the class of the ptg. |
if ($class == 0) { |
$ptgArea = pack("C", $this->ptg['ptgArea3d']); |
} |
elseif ($class == 1) { |
$ptgArea = pack("C", $this->ptg['ptgArea3dV']); |
} |
elseif ($class == 2) { |
$ptgArea = pack("C", $this->ptg['ptgArea3dA']); |
} |
else { |
$this->raiseError("Unknown class $class", 0, PEAR_ERROR_DIE); |
} |
return $ptgArea . $ext_ref . $row1 . $row2 . $col1. $col2; |
} |
/** |
* Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV. |
* |
* @access private |
* @param string $cell An Excel cell reference |
* @return string The cell in packed() format with the corresponding ptg |
*/ |
function _convertRef2d($cell) |
{ |
$class = 2; // as far as I know, this is magick. |
// Convert the cell reference |
$cell_array = $this->_cellToPackedRowcol($cell); |
if($this->isError($cell_array)) { |
return($cell_array); |
} |
list($row, $col) = $cell_array; |
// The ptg value depends on the class of the ptg. |
if ($class == 0) { |
$ptgRef = pack("C", $this->ptg['ptgRef']); |
} |
elseif ($class == 1) { |
$ptgRef = pack("C", $this->ptg['ptgRefV']); |
} |
elseif ($class == 2) { |
$ptgRef = pack("C", $this->ptg['ptgRefA']); |
} |
else { |
// TODO: use real error codes |
$this->raiseError("Unknown class $class", 0, PEAR_ERROR_DIE); |
} |
return($ptgRef.$row.$col); |
} |
/** |
* Convert an Excel 3d reference such as "Sheet1!A1" or "Sheet1:Sheet2!A1" to a |
* ptgRef3dV. |
* |
* @access private |
* @param string $cell An Excel cell reference |
* @return string The cell in packed() format with the corresponding ptg |
*/ |
function _convertRef3d($cell) |
{ |
$class = 2; // as far as I know, this is magick. |
// Split the ref at the ! symbol |
list($ext_ref, $cell) = explode('!', $cell); |
// Convert the external reference part |
$ext_ref = $this->_packExtRef($ext_ref); |
if ($this->isError($ext_ref)) { |
return $ext_ref; |
} |
// Convert the cell reference part |
list($row, $col) = $this->_cellToPackedRowcol($cell); |
// The ptg value depends on the class of the ptg. |
if ($class == 0) { |
$ptgRef = pack("C", $this->ptg['ptgRef3d']); |
} |
elseif ($class == 1) { |
$ptgRef = pack("C", $this->ptg['ptgRef3dV']); |
} |
elseif ($class == 2) { |
$ptgRef = pack("C", $this->ptg['ptgRef3dA']); |
} |
else { |
$this->raiseError("Unknown class $class", 0, PEAR_ERROR_DIE); |
} |
return $ptgRef . $ext_ref. $row . $col; |
} |
/** |
* Convert the sheet name part of an external reference, for example "Sheet1" or |
* "Sheet1:Sheet2", to a packed structure. |
* |
* @access private |
* @param string $ext_ref The name of the external reference |
* @return string The reference index in packed() format |
*/ |
function _packExtRef($ext_ref) |
{ |
$ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. |
$ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. |
// Check if there is a sheet range eg., Sheet1:Sheet2. |
if (preg_match("/:/", $ext_ref)) |
{ |
list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); |
$sheet1 = $this->_getSheetIndex($sheet_name1); |
if ($sheet1 == -1) { |
return $this->raiseError("Unknown sheet name $sheet_name1 in formula"); |
} |
$sheet2 = $this->_getSheetIndex($sheet_name2); |
if ($sheet2 == -1) { |
return $this->raiseError("Unknown sheet name $sheet_name2 in formula"); |
} |
// Reverse max and min sheet numbers if necessary |
if ($sheet1 > $sheet2) { |
list($sheet1, $sheet2) = array($sheet2, $sheet1); |
} |
} |
else // Single sheet name only. |
{ |
$sheet1 = $this->_getSheetIndex($ext_ref); |
if ($sheet1 == -1) { |
return $this->raiseError("Unknown sheet name $ext_ref in formula"); |
} |
$sheet2 = $sheet1; |
} |
// References are stored relative to 0xFFFF. |
$offset = -1 - $sheet1; |
return pack('vdvv', $offset, 0x00, $sheet1, $sheet2); |
} |
/** |
* Look up the index that corresponds to an external sheet name. The hash of |
* sheet names is updated by the addworksheet() method of the |
* Spreadsheet_Excel_Writer_Workbook class. |
* |
* @access private |
* @return integer |
*/ |
function _getSheetIndex($sheet_name) |
{ |
if (!isset($this->_ext_sheets[$sheet_name])) { |
return -1; |
} |
else { |
return $this->_ext_sheets[$sheet_name]; |
} |
} |
/** |
* This method is used to update the array of sheet names. It is |
* called by the addWorksheet() method of the Spreadsheet_Excel_Writer_Workbook class. |
* |
* @access private |
* @param string $name The name of the worksheet being added |
* @param integer $index The index of the worksheet being added |
*/ |
function setExtSheet($name, $index) |
{ |
$this->_ext_sheets[$name] = $index; |
} |
/** |
* pack() row and column into the required 3 byte format. |
* |
* @access private |
* @param string $cell The Excel cell reference to be packed |
* @return array Array containing the row and column in packed() format |
*/ |
function _cellToPackedRowcol($cell) |
{ |
list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell); |
if ($col >= 256) { |
return($this->raiseError("Column in: $cell greater than 255")); |
} |
if ($row >= 16384) { |
return($this->raiseError("Row in: $cell greater than 16384 ")); |
} |
// Set the high bits to indicate if row or col are relative. |
$row |= $col_rel << 14; |
$row |= $row_rel << 15; |
$row = pack('v', $row); |
$col = pack('C', $col); |
return(array($row, $col)); |
} |
/** |
* pack() row range into the required 3 byte format. |
* Just using maximun col/rows, which is probably not the correct solution |
* |
* @access private |
* @param string $range The Excel range to be packed |
* @return array Array containing (row1,col1,row2,col2) in packed() format |
*/ |
function _rangeToPackedRange($range) |
{ |
preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match); |
// return absolute rows if there is a $ in the ref |
$row1_rel = empty($match[1]) ? 1 : 0; |
$row1 = $match[2]; |
$row2_rel = empty($match[3]) ? 1 : 0; |
$row2 = $match[4]; |
// Convert 1-index to zero-index |
$row1--; |
$row2--; |
// Trick poor inocent Excel |
$col1 = 0; |
$col2 = 16383; // maximum possible value for Excel 5 (change this!!!) |
//list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell); |
if (($row1 >= 16384) or ($row2 >= 16384)) { |
return new PEAR_Error("Row in: $range greater than 16384 "); |
} |
// Set the high bits to indicate if rows are relative. |
$row1 |= $row1_rel << 14; |
$row2 |= $row2_rel << 15; |
$row1 = pack('v', $row1); |
$row2 = pack('v', $row2); |
$col1 = pack('C', $col1); |
$col2 = pack('C', $col2); |
return array($row1, $col1, $row2, $col2); |
} |
/** |
* Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero |
* indexed row and column number. Also returns two (0,1) values to indicate |
* whether the row or column are relative references. |
* |
* @access private |
* @param string $cell The Excel cell reference in A1 format. |
* @return array |
*/ |
function _cellToRowcol($cell) |
{ |
preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/',$cell,$match); |
// return absolute column if there is a $ in the ref |
$col_rel = empty($match[1]) ? 1 : 0; |
$col_ref = $match[2]; |
$row_rel = empty($match[3]) ? 1 : 0; |
$row = $match[4]; |
// Convert base26 column string to a number. |
$expn = strlen($col_ref) - 1; |
$col = 0; |
for($i=0; $i < strlen($col_ref); $i++) |
{ |
$col += (ord($col_ref{$i}) - ord('A') + 1) * pow(26, $expn); |
$expn--; |
} |
// Convert 1-index to zero-index |
$row--; |
$col--; |
return(array($row, $col, $row_rel, $col_rel)); |
} |
/** |
* Advance to the next valid token. |
* |
* @access private |
*/ |
function _advance() |
{ |
$i = $this->_current_char; |
// eat up white spaces |
if($i < strlen($this->_formula)) |
{ |
while($this->_formula{$i} == " ") { |
$i++; |
} |
if($i < strlen($this->_formula) - 1) { |
$this->_lookahead = $this->_formula{$i+1}; |
} |
$token = ""; |
} |
while($i < strlen($this->_formula)) |
{ |
$token .= $this->_formula{$i}; |
if($this->_match($token) != '') |
{ |
if($i < strlen($this->_formula) - 1) { |
$this->_lookahead = $this->_formula{$i+1}; |
} |
$this->_current_char = $i + 1; |
$this->_current_token = $token; |
return(1); |
} |
if ($i < strlen($this->_formula) - 2) { |
$this->_lookahead = $this->_formula{$i+2}; |
} |
// if we run out of characters _lookahead becomes empty |
else { |
$this->_lookahead = ''; |
} |
$i++; |
} |
//die("Lexical error ".$this->_current_char); |
} |
/** |
* Checks if it's a valid token. |
* |
* @access private |
* @param mixed $token The token to check. |
* @return mixed The checked token or false on failure |
*/ |
function _match($token) |
{ |
switch($token) |
{ |
case SPREADSHEET_EXCEL_WRITER_ADD: |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_SUB: |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_MUL: |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_DIV: |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_OPEN: |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_CLOSE: |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_COMA: |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_GT: |
if ($this->_lookahead == '=') { // it's a GE token |
break; |
} |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_LT: |
// it's a LE or a NE token |
if (($this->_lookahead == '=') or ($this->_lookahead == '>')) { |
break; |
} |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_GE: |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_LE: |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_EQ: |
return($token); |
break; |
case SPREADSHEET_EXCEL_WRITER_NE: |
return($token); |
break; |
default: |
// if it's a reference |
if (preg_match('/^\$?[A-I]?[A-Z]\$?[0-9]+$/',$token) and |
!ereg("[0-9]",$this->_lookahead) and |
($this->_lookahead != ':') and ($this->_lookahead != '.') and |
($this->_lookahead != '!')) |
{ |
return $token; |
} |
// If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1) |
elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\![A-I]?[A-Z][0-9]+$/",$token) and |
!ereg("[0-9]",$this->_lookahead) and |
($this->_lookahead != ':') and ($this->_lookahead != '.')) |
{ |
return $token; |
} |
// if it's a range (A1:A2) |
elseif (preg_match("/^(\$)?[A-I]?[A-Z](\$)?[0-9]+:(\$)?[A-I]?[A-Z](\$)?[0-9]+$/",$token) and |
!ereg("[0-9]",$this->_lookahead)) |
{ |
return $token; |
} |
// if it's a range (A1..A2) |
elseif (preg_match("/^(\$)?[A-I]?[A-Z](\$)?[0-9]+\.\.(\$)?[A-I]?[A-Z](\$)?[0-9]+$/",$token) and |
!ereg("[0-9]",$this->_lookahead)) |
{ |
return $token; |
} |
// If it's an external range |
elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\!([A-I]?[A-Z])?[0-9]+:([A-I]?[A-Z])?[0-9]+$/",$token) and |
!ereg("[0-9]",$this->_lookahead)) |
{ |
return $token; |
} |
// If it's a number (check that it's not a sheet name or range) |
elseif (is_numeric($token) and !is_numeric($token.$this->_lookahead) and |
($this->_lookahead != '!') and (($this->_lookahead != ':'))) |
{ |
return $token; |
} |
// If it's a string (of maximum 255 characters) |
elseif(ereg("^\"[^\"]{0,255}\"$",$token)) |
{ |
return($token); |
} |
// if it's a function call |
elseif(eregi("^[A-Z0-9\xc0-\xdc\.]+$",$token) and ($this->_lookahead == "(")) |
{ |
return($token); |
} |
return ''; |
} |
} |
/** |
* The parsing method. It parses a formula. |
* |
* @access public |
* @param string $formula The formula to parse, without the initial equal sign (=). |
*/ |
function parse($formula) |
{ |
$this->_current_char = 0; |
$this->_formula = $formula; |
$this->_lookahead = $formula{1}; |
$this->_advance(); |
$this->_parse_tree = $this->_condition(); |
if ($this->isError($this->_parse_tree)) { |
return $this->_parse_tree; |
} |
} |
/** |
* It parses a condition. It assumes the following rule: |
* Cond -> Expr [(">" | "<") Expr] |
* |
* @access private |
* @return mixed The parsed ptg'd tree |
*/ |
function _condition() |
{ |
$result = $this->_expression(); |
if($this->isError($result)) { |
return $result; |
} |
if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_LT) |
{ |
$this->_advance(); |
$result2 = $this->_expression(); |
if($this->isError($result2)) { |
return $result2; |
} |
$result = $this->_createTree('ptgLT', $result, $result2); |
} |
elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_GT) |
{ |
$this->_advance(); |
$result2 = $this->_expression(); |
if($this->isError($result2)) { |
return $result2; |
} |
$result = $this->_createTree('ptgGT', $result, $result2); |
} |
elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_LE) |
{ |
$this->_advance(); |
$result2 = $this->_expression(); |
if($this->isError($result2)) { |
return $result2; |
} |
$result = $this->_createTree('ptgLE', $result, $result2); |
} |
elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_GE) |
{ |
$this->_advance(); |
$result2 = $this->_expression(); |
if($this->isError($result2)) { |
return $result2; |
} |
$result = $this->_createTree('ptgGE', $result, $result2); |
} |
elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_EQ) |
{ |
$this->_advance(); |
$result2 = $this->_expression(); |
if($this->isError($result2)) { |
return $result2; |
} |
$result = $this->_createTree('ptgEQ', $result, $result2); |
} |
elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_NE) |
{ |
$this->_advance(); |
$result2 = $this->_expression(); |
if($this->isError($result2)) { |
return $result2; |
} |
$result = $this->_createTree('ptgNE', $result, $result2); |
} |
return $result; |
} |
/** |
* It parses a expression. It assumes the following rule: |
* Expr -> Term [("+" | "-") Term] |
* |
* @access private |
* @return mixed The parsed ptg'd tree |
*/ |
function _expression() |
{ |
// If it's a string return a string node |
if (ereg("^\"[^\"]{0,255}\"$", $this->_current_token)) |
{ |
$result = $this->_createTree($this->_current_token, '', ''); |
$this->_advance(); |
return($result); |
} |
$result = $this->_term(); |
if($this->isError($result)) { |
return($result); |
} |
while (($this->_current_token == SPREADSHEET_EXCEL_WRITER_ADD) or |
($this->_current_token == SPREADSHEET_EXCEL_WRITER_SUB)) |
{ |
if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_ADD) |
{ |
$this->_advance(); |
$result2 = $this->_term(); |
if($this->isError($result2)) { |
return($result2); |
} |
$result = $this->_createTree('ptgAdd', $result, $result2); |
} |
else |
{ |
$this->_advance(); |
$result2 = $this->_term(); |
if($this->isError($result2)) { |
return($result2); |
} |
$result = $this->_createTree('ptgSub', $result, $result2); |
} |
} |
return($result); |
} |
/** |
* This function just introduces a ptgParen element in the tree, so that Excel |
* doesn't get confused when working with a parenthesized formula afterwards. |
* |
* @access private |
* @see _fact() |
* @return mixed The parsed ptg'd tree |
*/ |
function _parenthesizedExpression() |
{ |
$result = $this->_createTree('ptgParen', $this->_expression(), ''); |
return($result); |
} |
/** |
* It parses a term. It assumes the following rule: |
* Term -> Fact [("*" | "/") Fact] |
* |
* @access private |
* @return mixed The parsed ptg'd tree |
*/ |
function _term() |
{ |
$result = $this->_fact(); |
if($this->isError($result)) { |
return($result); |
} |
while (($this->_current_token == SPREADSHEET_EXCEL_WRITER_MUL) or |
($this->_current_token == SPREADSHEET_EXCEL_WRITER_DIV)) |
{ |
if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_MUL) |
{ |
$this->_advance(); |
$result2 = $this->_fact(); |
if($this->isError($result2)) { |
return($result2); |
} |
$result = $this->_createTree('ptgMul', $result, $result2); |
} |
else |
{ |
$this->_advance(); |
$result2 = $this->_fact(); |
if($this->isError($result2)) { |
return($result2); |
} |
$result = $this->_createTree('ptgDiv', $result, $result2); |
} |
} |
return($result); |
} |
/** |
* It parses a factor. It assumes the following rule: |
* Fact -> ( Expr ) |
* | CellRef |
* | CellRange |
* | Number |
* | Function |
* |
* @access private |
* @return mixed The parsed ptg'd tree |
*/ |
function _fact() |
{ |
if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_OPEN) |
{ |
$this->_advance(); // eat the "(" |
$result = $this->_parenthesizedExpression(); |
if ($this->_current_token != SPREADSHEET_EXCEL_WRITER_CLOSE) { |
return($this->raiseError("')' token expected.")); |
} |
$this->_advance(); // eat the ")" |
return $result; |
} |
// if it's a reference |
if (preg_match('/^\$?[A-I]?[A-Z]\$?[0-9]+$/',$this->_current_token)) |
{ |
$result = $this->_createTree($this->_current_token, '', ''); |
$this->_advance(); |
return $result; |
} |
// If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1) |
elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\![A-I]?[A-Z][0-9]+$/",$this->_current_token)) |
{ |
$result = $this->_createTree($this->_current_token, '', ''); |
$this->_advance(); |
return $result; |
} |
// if it's a range |
elseif (preg_match("/^(\$)?[A-I]?[A-Z](\$)?[0-9]+:(\$)?[A-I]?[A-Z](\$)?[0-9]+$/",$this->_current_token) or |
preg_match("/^(\$)?[A-I]?[A-Z](\$)?[0-9]+\.\.(\$)?[A-I]?[A-Z](\$)?[0-9]+$/",$this->_current_token)) |
{ |
$result = $this->_current_token; |
$this->_advance(); |
return $result; |
} |
// If it's an external range (Sheet1!A1:B2) |
elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\!([A-I]?[A-Z])?[0-9]+:([A-I]?[A-Z])?[0-9]+$/",$this->_current_token)) |
{ |
$result = $this->_current_token; |
$this->_advance(); |
return($result); |
} |
elseif (is_numeric($this->_current_token)) |
{ |
$result = $this->_createTree($this->_current_token, '', ''); |
$this->_advance(); |
return($result); |
} |
// if it's a function call |
elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$this->_current_token)) |
{ |
$result = $this->_func(); |
return($result); |
} |
return($this->raiseError("Sintactic error: ".$this->_current_token.", lookahead: ". |
$this->_lookahead.", current char: ".$this->_current_char)); |
} |
/** |
* It parses a function call. It assumes the following rule: |
* Func -> ( Expr [,Expr]* ) |
* |
* @access private |
*/ |
function _func() |
{ |
$num_args = 0; // number of arguments received |
$function = $this->_current_token; |
$this->_advance(); |
$this->_advance(); // eat the "(" |
while($this->_current_token != ')') |
{ |
if($num_args > 0) |
{ |
if($this->_current_token == SPREADSHEET_EXCEL_WRITER_COMA) { |
$this->_advance(); // eat the "," |
} |
else { |
return new PEAR_Error("Sintactic error: coma expected in ". |
"function $function, {$num_args}� arg"); |
} |
$result2 = $this->_condition(); |
if($this->isError($result2)) { |
return($result2); |
} |
$result = $this->_createTree('arg', $result, $result2); |
} |
else // first argument |
{ |
$result2 = $this->_condition(); |
if($this->isError($result2)) { |
return($result2); |
} |
$result = $this->_createTree('arg', '', $result2); |
} |
$num_args++; |
} |
$args = $this->_functions[$function][1]; |
// If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid. |
if (($args >= 0) and ($args != $num_args)) |
{ |
return($this->raiseError("Incorrect number of arguments in function $function() ")); |
} |
$result = $this->_createTree($function, $result, ''); |
$this->_advance(); // eat the ")" |
return($result); |
} |
/** |
* Creates a tree. In fact an array which may have one or two arrays (sub-trees) |
* as elements. |
* |
* @access private |
* @param mixed $value The value of this node. |
* @param mixed $left The left array (sub-tree) or a final node. |
* @param mixed $right The right array (sub-tree) or a final node. |
*/ |
function _createTree($value, $left, $right) |
{ |
return(array('value' => $value, 'left' => $left, 'right' => $right)); |
} |
/** |
* Builds a string containing the tree in reverse polish notation (What you |
* would use in a HP calculator stack). |
* The following tree: |
* |
* + |
* / \ |
* 2 3 |
* |
* produces: "23+" |
* |
* The following tree: |
* |
* + |
* / \ |
* 3 * |
* / \ |
* 6 A1 |
* |
* produces: "36A1*+" |
* |
* In fact all operands, functions, references, etc... are written as ptg's |
* |
* @access public |
* @param array $tree The optional tree to convert. |
* @return string The tree in reverse polish notation |
*/ |
function toReversePolish($tree = array()) |
{ |
$polish = ""; // the string we are going to return |
if (empty($tree)) // If it's the first call use _parse_tree |
{ |
$tree = $this->_parse_tree; |
} |
if (is_array($tree['left'])) |
{ |
$converted_tree = $this->toReversePolish($tree['left']); |
if($this->isError($converted_tree)) { |
return($converted_tree); |
} |
$polish .= $converted_tree; |
} |
elseif($tree['left'] != '') // It's a final node |
{ |
$converted_tree = $this->_convert($tree['left']); |
if($this->isError($converted_tree)) { |
return($converted_tree); |
} |
$polish .= $converted_tree; |
} |
if (is_array($tree['right'])) |
{ |
$converted_tree = $this->toReversePolish($tree['right']); |
if($this->isError($converted_tree)) { |
return($converted_tree); |
} |
$polish .= $converted_tree; |
} |
elseif($tree['right'] != '') // It's a final node |
{ |
$converted_tree = $this->_convert($tree['right']); |
if($this->isError($converted_tree)) { |
return($converted_tree); |
} |
$polish .= $converted_tree; |
} |
$converted_tree = $this->_convert($tree['value']); |
if($this->isError($converted_tree)) { |
return($converted_tree); |
} |
$polish .= $converted_tree; |
return($polish); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/GestionObservation.php |
---|
New file |
0,0 → 1,441 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurelien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* Classe de gestion de l'ajout, modification et suppression des observations |
* |
* in=utf8 |
* out=utf8 |
* |
*/ |
class GestionObservation extends Cel { |
/** |
* Ajoute une observation grâce aux paramètres fournis |
* |
* @param int $utilisateur id utilisateur du proprietaire de l'observation |
* @param array $parametres tableau indexé avec les mêmes noms de champs que la bdd |
* |
* @return true ou false suivant le succès de l'opération |
*/ |
public function ajouterObservation($utilisateur, $parametres) { |
$retour = true; |
$parametres['ordre'] = $this->renvoyerDernierOrdreUtilisePlusUn($utilisateur); |
$requete_insertion_observation = 'INSERT INTO cel_obs '; |
$sous_requete_colonnes = $this->traiterParametresObservationEtConstruireSousRequeteAjout($parametres); |
$requete_insertion_observation = $requete_insertion_observation.$sous_requete_colonnes; |
// important ! ne pas utiliser la fonction executerRequete qui renvoie une erreur si la requete contient des | (pipes) |
// ce qui peut arriver dans les commentaires |
// TODO: corriger la fonction ou bien continuer à utiliser executerRequeteSimple |
$resultat_ajout_observation = $this->executerRequeteSimple($requete_insertion_observation); |
if ($resultat_ajout_observation === false) { |
$retour = false; |
$this->logger("CEL_bugs","Erreur de creation d'une observation : ".$resultat_ajout_observation); |
} |
// TODO: retourner l'id ou le numero d'ordre nouvellement créé ? |
return $retour; |
} |
/** |
* Renvoie le prochain numero d'ordre relatif à un utilisateur (i.e. dernier ordre + 1) |
* |
* @param int $utilisateur id utilisateur |
* |
* @return int le nouveau numero d'ordre relatif à l'utilisateur ou bien 0 s'il n'a jamais créé d'observations |
*/ |
public function renvoyerDernierOrdreUtilisePlusUn($utilisateur) { |
$requete_selection_dernier_ordre = "SELECT max(ordre) AS ordre FROM cel_obs ". |
"WHERE ce_utilisateur = ".$this->proteger($utilisateur); |
$dernier_ordre = $this->executerRequete($requete_selection_dernier_ordre); |
$nouvel_ordre = 0; |
if (is_array($dernier_ordre) && count($dernier_ordre) > 0 && trim($dernier_ordre[0]['ordre']) != '') { |
$nouvel_ordre = $dernier_ordre[0]['ordre'] + 1; |
} |
return $nouvel_ordre; |
} |
/** |
* Modifie une ou plusieurs observations grâce aux paramètres fournis |
* |
* @param int $utilisateur id utilisateur du proprietaire de l'observation |
* @param mixed $ordre ordre(s) observation(s) relatif(s) à l'utilisateur: un seul ordre ou bien "ordre1,ordre2,ordre3" etc... |
* @param array $parametres tableau indexé avec les mêmes noms de champs que la bdd |
* |
* @return true ou false suivant le succès de l'opération |
*/ |
public function modifierObservation($utilisateur, $ordre, $parametres) { |
$retour = true; |
$requete_modification = "UPDATE cel_obs SET " ; |
$sous_requete_modification = $this->traiterParametresObservationEtConstruireSousRequeteMaj($parametres); |
$requete_modification .= $sous_requete_modification; |
$requete_modification .= " WHERE ordre IN (".$ordre.") AND ce_utilisateur = ".$this->proteger($utilisateur); |
// important ! ne pas utiliser la fonction executerRequete qui renvoie une erreur si la requete contient des | (pipes) |
// ce qui peut arriver dans les commentaires |
// TODO: corriger la fonction ou bien continuer à utiliser executerRequeteSimple |
$resultat_modification = $this->executerRequeteSimple($requete_modification); |
if ($resultat_modification === false) { |
$retour = false; |
$this->logger("CEL_bugs","Erreur de mise à jour d'une liste d'observations : ".$requete_modification); |
} |
return $retour; |
} |
/** |
* Modifie une observation publique dont l'id et l'utilisateur sont passé en paramètre |
* |
* @param int $utilisateur id utilisateur du proprietaire de l'observation |
* @param int $id identifiant de l'observation |
* @param array $parametres tableau indexé avec les mêmes noms de champs que la bdd |
* |
* @return true ou false suivant le succès de l'opération |
*/ |
public function modifierObservationPublique($utilisateur, $id, $parametres) { |
$retour = true; |
$requete_modification = "UPDATE cel_obs SET " ; |
$sous_requete_modification = $this->traiterParametresObservationEtConstruireSousRequeteMaj($parametres); |
$requete_modification .= $sous_requete_modification; |
$requete_modification .= " WHERE id_observation = ".$this->proteger($id). |
" AND ce_utilisateur = ".$this->proteger($utilisateur)." ". |
" AND transmission = 1"; |
// important ! ne pas utiliser la fonction executerRequete qui renvoie une erreur si la requete contient des | (pipes) |
// ce qui peut arriver dans les commentaires |
// TODO: corriger la fonction ou bien continuer à utiliser executerRequeteSimple |
$resultat_modification = $this->executerRequeteSimple($requete_modification); |
if ($resultat_modification === false) { |
$retour = false; |
$this->logger("CEL_bugs","Erreur de mise à jour de l\'observation : ".$id); |
} |
return $retour; |
} |
/** |
* Supprime une ou plusieurs observations grâce aux paramètres fournis |
* |
* @param int $utilisateur id utilisateur du proprietaire de l'observation |
* @param mixed $ordre ordre(s) observation(s) relatif(s) à l'utilisateur: un seul ordre ou bien "ordre1,ordre2,ordre3" etc... |
* |
* @return true ou false suivant le succès de l'opération |
*/ |
public function supprimerObservation($utilisateur, $ordre) { |
// TODO changer le systeme pour n'utiliser plus que les id |
$retour = false; |
$tableau_ordre = explode(',', $ordre); |
$tableau_ordre = array_map(array($this, 'proteger'), $tableau_ordre); |
$ordre = implode(',', $tableau_ordre); |
$requete_ids_observations = 'SELECT id_observation as id_obs FROM cel_obs '. |
'WHERE ce_utilisateur = '.$this->proteger($utilisateur).' '. |
'AND ordre IN ('.$ordre.')'; |
$resultat_ids_observations = $this->requeter($requete_ids_observations); |
$ids_obs = array(); |
if(is_array($resultat_ids_observations) && count($resultat_ids_observations) > 0) { |
foreach($resultat_ids_observations as $id_observation) { |
$ids_obs[] = $this->proteger($id_observation['id_obs']); |
} |
$chaine_ids_obs = implode(',', $ids_obs); |
$requete_supression_observations = 'DELETE FROM cel_obs WHERE '. |
'ce_utilisateur = '.$this->proteger($utilisateur).' '. |
'AND id_observation IN ('.$chaine_ids_obs.')'; |
$resultat_suppression_observations = $this->executerRequeteSimple($requete_supression_observations); |
// TODO: Faire la suppression des mots clés |
// et des liaisons obs images dans une ou des fonctions à part |
if ($resultat_suppression_observations === false) { |
$this->logger("CEL_bugs","Erreur de suppression d'une liste d'observations : ".$resultat_suppression_observations); |
} |
else |
{ |
$requete_supression_lien_obs_images = 'DELETE FROM cel_obs_images WHERE '. |
'id_utilisateur = '.$this->proteger($utilisateur).' '. |
'AND id_observation IN ('.$chaine_ids_obs.')'; |
$resultat_suppression_liens = $this->executerRequeteSimple($requete_supression_lien_obs_images); |
if ($resultat_suppression_liens === false) { |
$this->logger("CEL_bugs","Erreur de suppression d'une liste de liaison entre observations et images : ".$requete_supression_lien_obs_images); |
} |
else |
{ |
$retour = true; |
} |
$requete_supression_lien_mots_cles = 'DELETE FROM cel_obs_mots_cles WHERE '. |
'id_observation in ('.$chaine_ids_obs.')'; |
$resultat_suppression_mots_cles = $this->executerRequeteSimple($requete_supression_lien_mots_cles); |
if ($resultat_suppression_mots_cles === false) { |
$this->logger("CEL_bugs","Erreur de suppression d'une liste de mots clés d'observation(s) : ".$resultat_suppression_mots_cles); |
} |
else |
{ |
$retour = true; |
} |
} |
} else { |
$retour = true; |
} |
return $retour; |
} |
/** |
* Fonction utilisée pour importer les observations faites avec des comptes anonymes vers un |
* utilisateur identifié |
* @param string $ancien_id |
* @param string $id_utilisateur |
*/ |
public function migrerObservations($ancien_id, $id_utilisateur) { |
//TODO faire une fonction plus complexe qui déplace, images, observations, mots-clés etc... d'un utilisateur à l'autre |
// qui pourrait servir pour fusionner des comptes |
$nouvel_ordre = $this->renvoyerDernierOrdreUtilisePlusUn($id_utilisateur); |
// Recuperation relevés associés a la session |
$requete_selection_releves_temporaires = 'SELECT ordre FROM cel_obs WHERE ce_utilisateur = '.$this->proteger($ancien_id).' ORDER BY ordre'; |
$resultat_releves_temporaires = $this->executerRequete($requete_selection_releves_temporaires); |
$reussite = true; |
if(is_array($resultat_releves_temporaires)) { |
foreach($resultat_releves_temporaires as $releve_temporaire) { |
$requete_migration_releve = 'UPDATE cel_obs SET '. |
'ce_utilisateur = '.$this->proteger($id_utilisateur).', '. |
'ordre = '.$nouvel_ordre.' '. |
'WHERE ce_utilisateur = '.$ancien_id.' '. |
'AND ordre = '.$releve_temporaire['ordre']; |
$migration_releve = $this->executerRequeteSimple($requete_migration_releve); |
//TODO: meilleure vérification |
if($migration_releve === false) { |
$reussite = false; |
} |
$nouvel_ordre++; |
} |
} |
return $reussite; |
} |
/** |
* Fonction utilisée pour importer les anciennes observations saisie dans les widget dans un compte identifié |
* Dans ce cas là, le widget remplit la case id_utilisateur par le mail indiqué lors de la saisie |
* @param string $mail_utilisateur |
* @param string $id_utilisateur |
*/ |
public function migrerObservationsMailVersId($mail_utilisateur, $infos_utilisateur) { |
// ATTENTION : cette fonction suppose que l'utilisateur n'ai pas déjà d'observations dans le CEL |
// avec l'identifiant $id_utilisateur ce qui est normalement le cas |
$requete_migration_releve = 'UPDATE cel_obs SET '. |
'ce_utilisateur = '.$this->proteger($infos_utilisateur['id_utilisateur']).', '. |
'prenom_utilisateur = '.$this->proteger($infos_utilisateur['prenom']).', '. |
'nom_utilisateur = '.$this->proteger($infos_utilisateur['nom']).', '. |
'courriel_utilisateur = '.$this->proteger($infos_utilisateur['courriel']).' '. |
'WHERE ce_utilisateur = '.$this->proteger($mail_utilisateur).' '; |
$migration_releve = $this->executerRequeteSimple($requete_migration_releve); |
return $migration_releve; |
} |
/** |
* Formate les paramètres fournis en ajoutant des infos complementaires |
* |
* @param array $parametres tableau indexé avec les mêmes noms de champs que la bdd |
* |
* @return $parametres le tableau modifié selon ce qu'il contenait |
*/ |
private function formaterParametresObservation($parametres) { |
$code_referentiel = 'bdtfx'; |
if(!isset($parametres['nom_referentiel'])) { |
$parametres['nom_referentiel'] = 'bdtfx:v1.01'; |
} |
$code_referentiel = substr($parametres['nom_referentiel'], 0, 5); |
if ($this->estUnNomSolitaire($parametres)) { |
$chercheur_infos_complementaires = new RechercheInfosTaxonBeta($this->config, $code_referentiel); |
// Utilisation d'un nom sans numéro nomenclatural, recherche d'une correspondance sur le nom |
$complement = $chercheur_infos_complementaires->rechercherInformationsComplementairesSurNom($parametres['nom_sel']); |
// Si l'on a trouvé un résultat sur la recherche, il s'agit vraisemblablement d'un copié-collé |
// de nom de taxon qui n'a pas été validé par la selection |
if(count($complement) > 0) { |
$parametres['nom_sel_nn'] = $complement[0][0]; |
} |
} |
if ($this->parametreNumNomEstPresent($parametres)) { |
// Utilisation d'un nom faisant parti du referentiel : recherche du nom valide correspondant |
$chercheur_infos_complementaires = new RechercheInfosTaxonBeta($this->config , $code_referentiel); |
$complement = $chercheur_infos_complementaires->rechercherInformationsComplementairesSurNumNom($parametres['nom_sel_nn']); |
$parametres['nom_ret']=$complement['Nom_Retenu']; |
$parametres['nom_ret_nn']=$complement['Num_Nom_Retenu']; |
$parametres['nt']=$complement['Num_Taxon']; |
$parametres['famille']=$complement['Famille']; |
} |
if(isset($parametres['ce_utilisateur'])) { |
$infos_utilisateur = $this->getInfosComplementairesUtilisateur($parametres['ce_utilisateur']); |
$parametres['courriel_utilisateur'] = $infos_utilisateur['courriel']; |
$parametres['nom_utilisateur'] = $infos_utilisateur['nom']; |
$parametres['prenom_utilisateur'] = $infos_utilisateur['prenom']; |
} |
// Pour empecher que des numéros de département de 1 à 9 soient saisis sans 0 |
// TODO: décider quoi faire pour les zones géo plus générales |
if (isset($parametres['ce_zone_geo'])) { |
if($parametres['ce_zone_geo'] == 'null' || trim($parametres['ce_zone_geo']) == "") { |
$parametres['ce_zone_geo'] = ""; |
} else { |
if (strlen($parametres['ce_zone_geo']) == 4) { |
$parametres['ce_zone_geo'] = '0'.$parametres['ce_zone_geo']; |
} |
if (strlen($parametres['ce_zone_geo']) > 0 && strlen($parametres['ce_zone_geo']) <= 2) { |
$parametres['ce_zone_geo'] = $this->obtenirCodeInseeCommunePourNomEtDepartement($parametres['zone_geo'], $parametres['ce_zone_geo']); |
} else { |
$parametres['ce_zone_geo'] = $this->convertirCodeInseeVersCodeZoneGeo($parametres['ce_zone_geo']); |
} |
} |
} |
// TODO : voir si l'on peut utiliser un des fonctions de la classe cel |
if (isset($parametres['date_observation']) && $parametres['date_observation']!="null") { |
if(substr_count($parametres['date_observation'], '/') == 3) { |
list($jour,$mois,$annee)=explode("/",$parametres['date_observation']); |
$parametres['date_observation']=$annee."-".$mois."-".$jour." 0:0:0"; |
} |
} |
return $parametres; |
} |
private function estUnNomSolitaire($parametres) { |
return $this->parametreNumNomPasPresent($parametres) && $parametres['nom_sel'] != ''; |
} |
private function parametreNumNomEstPresent($parametres) { |
return !$this->parametreNumNomPasPresent($parametres); |
} |
private function parametreNumNomPasPresent($parametres) { |
return (!isset($parametres['nom_sel_nn']) || |
$parametres['nom_sel_nn'] == null || |
$parametres['nom_sel_nn'] == '' || |
$parametres['nom_sel_nn'] == 0); |
} |
/** |
* Assemble une sous requete pour un ajout, tout en formatant les paramètres et en recherchant |
* les infos complémentaires |
* |
* @param array $parametres un tableau avec les index correspondant aux champs de la bdd |
* |
* @return string une sous requete utilisable pour l'ajout d'une observation |
*/ |
private function traiterParametresObservationEtConstruireSousRequeteAjout($parametres) { |
$sous_requete = ''; |
$parametres = $this->formaterParametresObservation(&$parametres); |
$champs = ''; |
$valeurs = ''; |
// Nullifiage ... |
// TODO: code dupliqué, en faire une fonction à mettre à la place appropriée |
foreach($parametres as $cle => $valeur) { |
// Pour apparaitre le premier dans les tris ... |
if (trim($valeur) == "" || trim($valeur) == "null") { |
$valeur = "NULL"; |
} else { |
$valeur = $this->proteger($valeur); |
} |
$champs .= $cle.', '; |
$valeurs .= $valeur.', '; |
} |
$champs = '('.$champs.'mots_cles_texte, transmission, date_creation, date_modification, date_transmission)'; |
$valeurs = '('.$valeurs.'"", 0, now(), now(), "0000-00-00 00:00:00")'; |
$sous_requete .= $champs.' VALUES '.$valeurs; |
return $sous_requete; |
} |
/** |
* Assemble une sous requete pour une mise à jour, tout en formatant les paramètres et en recherchant |
* les infos complémentaires |
* |
* @param array $parametres un tableau avec les index correspondant aux champs de la bdd |
* |
* @return string une sous requete utilisable pour la modification d'une observation |
* selon la syntaxe UPDATE table SET colonne1 = valeur1, colonne2 = valeur2 WHERE condition |
*/ |
private function traiterParametresObservationEtConstruireSousRequeteMAJ($parametres) { |
$sous_requete = ''; |
$parametres = $this->formaterParametresObservation(&$parametres); |
// Nullifiage ... |
// TODO: code dupliqué, en faire une fonction à mettre à la place appropriée |
foreach($parametres as $cle => $valeur) { |
// Pour apparaitre le premier dans les tris ... |
if (trim($valeur) == "" || trim($valeur) == "null") { |
$valeur = "NULL"; |
} else { |
$valeur = $this->proteger($valeur); |
} |
$sous_requete .= $cle." = ".$valeur.", "; |
} |
$sous_requete .= ' date_modification = now() '; |
return $sous_requete; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/DB.php |
---|
New file |
0,0 → 1,1114 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ |
// +----------------------------------------------------------------------+ |
// | 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: Stig Bakken <ssb@php.net> | |
// | Tomas V.V.Cox <cox@idecnet.com> | |
// | Maintainer: Daniel Convissor <danielc@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id$ |
// |
// Database independent query interface. |
require_once 'PEAR.php'; |
// {{{ constants |
// {{{ error codes |
/* |
* The method mapErrorCode in each DB_dbtype implementation maps |
* native error codes to one of these. |
* |
* If you add an error code here, make sure you also add a textual |
* version of it in DB::errorMessage(). |
*/ |
define('DB_OK', 1); |
define('DB_ERROR', -1); |
define('DB_ERROR_SYNTAX', -2); |
define('DB_ERROR_CONSTRAINT', -3); |
define('DB_ERROR_NOT_FOUND', -4); |
define('DB_ERROR_ALREADY_EXISTS', -5); |
define('DB_ERROR_UNSUPPORTED', -6); |
define('DB_ERROR_MISMATCH', -7); |
define('DB_ERROR_INVALID', -8); |
define('DB_ERROR_NOT_CAPABLE', -9); |
define('DB_ERROR_TRUNCATED', -10); |
define('DB_ERROR_INVALID_NUMBER', -11); |
define('DB_ERROR_INVALID_DATE', -12); |
define('DB_ERROR_DIVZERO', -13); |
define('DB_ERROR_NODBSELECTED', -14); |
define('DB_ERROR_CANNOT_CREATE', -15); |
define('DB_ERROR_CANNOT_DELETE', -16); |
define('DB_ERROR_CANNOT_DROP', -17); |
define('DB_ERROR_NOSUCHTABLE', -18); |
define('DB_ERROR_NOSUCHFIELD', -19); |
define('DB_ERROR_NEED_MORE_DATA', -20); |
define('DB_ERROR_NOT_LOCKED', -21); |
define('DB_ERROR_VALUE_COUNT_ON_ROW', -22); |
define('DB_ERROR_INVALID_DSN', -23); |
define('DB_ERROR_CONNECT_FAILED', -24); |
define('DB_ERROR_EXTENSION_NOT_FOUND',-25); |
define('DB_ERROR_ACCESS_VIOLATION', -26); |
define('DB_ERROR_NOSUCHDB', -27); |
define('DB_ERROR_CONSTRAINT_NOT_NULL',-29); |
// }}} |
// {{{ prepared statement-related |
/* |
* These constants are used when storing information about prepared |
* statements (using the "prepare" method in DB_dbtype). |
* |
* The prepare/execute model in DB is mostly borrowed from the ODBC |
* extension, in a query the "?" character means a scalar parameter. |
* There are two extensions though, a "&" character means an opaque |
* parameter. An opaque parameter is simply a file name, the real |
* data are in that file (useful for putting uploaded files into your |
* database and such). The "!" char means a parameter that must be |
* left as it is. |
* They modify the quote behavoir: |
* DB_PARAM_SCALAR (?) => 'original string quoted' |
* DB_PARAM_OPAQUE (&) => 'string from file quoted' |
* DB_PARAM_MISC (!) => original string |
*/ |
define('DB_PARAM_SCALAR', 1); |
define('DB_PARAM_OPAQUE', 2); |
define('DB_PARAM_MISC', 3); |
// }}} |
// {{{ binary data-related |
/* |
* These constants define different ways of returning binary data |
* from queries. Again, this model has been borrowed from the ODBC |
* extension. |
* |
* DB_BINMODE_PASSTHRU sends the data directly through to the browser |
* when data is fetched from the database. |
* DB_BINMODE_RETURN lets you return data as usual. |
* DB_BINMODE_CONVERT returns data as well, only it is converted to |
* hex format, for example the string "123" would become "313233". |
*/ |
define('DB_BINMODE_PASSTHRU', 1); |
define('DB_BINMODE_RETURN', 2); |
define('DB_BINMODE_CONVERT', 3); |
// }}} |
// {{{ fetch modes |
/** |
* This is a special constant that tells DB the user hasn't specified |
* any particular get mode, so the default should be used. |
*/ |
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: normally the first level of arrays |
* is the row number, and the second level indexed by column number or name. |
* DB_FETCHMODE_FLIPPED switches this order, so the first level of arrays |
* is the column name, and the second level the row number. |
*/ |
define('DB_FETCHMODE_FLIPPED', 4); |
/* 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 |
/** |
* these are constants for the tableInfo-function |
* they are bitwised or'ed. so if there are more constants to be defined |
* in the future, adjust DB_TABLEINFO_FULL accordingly |
*/ |
define('DB_TABLEINFO_ORDER', 1); |
define('DB_TABLEINFO_ORDERTABLE', 2); |
define('DB_TABLEINFO_FULL', 3); |
/* |
* Used by autoPrepare() |
*/ |
define('DB_AUTOQUERY_INSERT', 1); |
define('DB_AUTOQUERY_UPDATE', 2); |
// }}} |
// {{{ portability modes |
/** |
* Portability: turn off all portability features. |
* @see DB_common::setOption() |
*/ |
define('DB_PORTABILITY_NONE', 0); |
/** |
* Portability: convert names of tables and fields to lower case |
* when using the get*(), fetch*() and tableInfo() methods. |
* @see DB_common::setOption() |
*/ |
define('DB_PORTABILITY_LOWERCASE', 1); |
/** |
* Portability: right trim the data output by get*() and fetch*(). |
* @see DB_common::setOption() |
*/ |
define('DB_PORTABILITY_RTRIM', 2); |
/** |
* Portability: force reporting the number of rows deleted. |
* @see DB_common::setOption() |
*/ |
define('DB_PORTABILITY_DELETE_COUNT', 4); |
/** |
* Portability: enable hack that makes numRows() work in Oracle. |
* @see DB_common::setOption() |
*/ |
define('DB_PORTABILITY_NUMROWS', 8); |
/** |
* Portability: 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. |
* |
* @see DB_common::setOption() |
*/ |
define('DB_PORTABILITY_ERRORS', 16); |
/** |
* Portability: convert null values to empty strings in data output by |
* get*() and fetch*(). |
* @see DB_common::setOption() |
*/ |
define('DB_PORTABILITY_NULL_TO_EMPTY', 32); |
/** |
* Portability: turn on all portability features. |
* @see DB_common::setOption() |
*/ |
define('DB_PORTABILITY_ALL', 63); |
// }}} |
// }}} |
// {{{ class DB |
/** |
* 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): |
* |
* 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. |
* |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V.Cox <cox@idecnet.com> |
* @since PHP 4.0 |
* @version $Id$ |
* @category Database |
*/ |
class DB |
{ |
// {{{ &factory() |
/** |
* Create a new DB object for the specified database type. |
* |
* Allows creation of a DB_<driver> object from which the object's |
* methods can be utilized without actually connecting to a database. |
* |
* @param string $type database type, for example "mysql" |
* @param array $options associative array of option names and values |
* |
* @return object a new DB object. On error, an error object. |
* |
* @see DB_common::setOption() |
* @access public |
*/ |
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", |
'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 and connect to the specified database. |
* |
* Example 1. |
* <code> <?php |
* require_once 'DB.php'; |
* |
* $dsn = 'mysql://user:password@host/database' |
* $options = array( |
* 'debug' => 2, |
* 'portability' => DB_PORTABILITY_ALL, |
* ); |
* |
* $dbh =& DB::connect($dsn, $options); |
* if (DB::isError($dbh)) { |
* die($dbh->getMessage()); |
* } |
* ?></code> |
* |
* @param mixed $dsn string "data source name" or an array in the |
* format returned by DB::parseDSN() |
* |
* @param array $options an associative array of option names and |
* their values |
* |
* @return object a newly created DB connection object, or a DB |
* error object on error |
* |
* @see DB::parseDSN(), DB_common::setOption(), DB::isError() |
* @access public |
*/ |
function &connect($dsn, $options = array()) |
{ |
$dsninfo = DB::parseDSN($dsn); |
$type = $dsninfo['phptype']; |
if (!is_array($options)) { |
/* |
* For backwards compatibility. $options used to be boolean, |
* indicating whether the connection should be persistent. |
*/ |
$options = array('persistent' => $options); |
} |
if (isset($options['debug']) && $options['debug'] >= 2) { |
// expose php errors with sufficient debug level |
include_once "DB/${type}.php"; |
} else { |
@include_once "DB/${type}.php"; |
} |
$classname = "DB_${type}"; |
if (!class_exists($classname)) { |
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, |
"Unable to include the DB/{$type}.php file for `$dsn'", |
'DB_Error', true); |
return $tmp; |
} |
@$obj =& new $classname; |
foreach ($options as $option => $value) { |
$test = $obj->setOption($option, $value); |
if (DB::isError($test)) { |
return $test; |
} |
} |
$err = $obj->connect($dsninfo, $obj->getOption('persistent')); |
if (DB::isError($err)) { |
$err->addUserInfo($dsn); |
return $err; |
} |
return $obj; |
} |
// }}} |
// {{{ apiVersion() |
/** |
* Return the DB API version |
* |
* @return int the DB API version number |
* |
* @access public |
*/ |
function apiVersion() |
{ |
return 2; |
} |
// }}} |
// {{{ isError() |
/** |
* Tell whether a result code from a DB method is an error |
* |
* @param int $value result code |
* |
* @return bool whether $value is an error |
* |
* @access public |
*/ |
function isError($value) |
{ |
return is_a($value, 'DB_Error'); |
} |
// }}} |
// {{{ isConnection() |
/** |
* Tell whether a value is a DB connection |
* |
* @param mixed $value value to test |
* |
* @return bool whether $value is a DB connection |
* |
* @access public |
*/ |
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 query (insert, |
* update or delete) or a data definition query (create, drop, |
* alter, grant, revoke). |
* |
* @access public |
* |
* @param string $query the query |
* |
* @return boolean whether $query is a data manipulation query |
*/ |
function isManip($query) |
{ |
$manips = 'INSERT|UPDATE|DELETE|LOAD DATA|'.'REPLACE|CREATE|DROP|'. |
'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 error code |
* |
* @return string error message, or false if the error code was |
* not recognized |
*/ |
function errorMessage($value) |
{ |
static $errorMessages; |
if (!isset($errorMessages)) { |
$errorMessages = array( |
DB_ERROR => 'unknown error', |
DB_ERROR_ALREADY_EXISTS => 'already exists', |
DB_ERROR_CANNOT_CREATE => 'can not create', |
DB_ERROR_CANNOT_DELETE => 'can not delete', |
DB_ERROR_CANNOT_DROP => 'can not drop', |
DB_ERROR_CONSTRAINT => 'constraint violation', |
DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint', |
DB_ERROR_DIVZERO => 'division by zero', |
DB_ERROR_INVALID => 'invalid', |
DB_ERROR_INVALID_DATE => 'invalid date or time', |
DB_ERROR_INVALID_NUMBER => 'invalid number', |
DB_ERROR_MISMATCH => 'mismatch', |
DB_ERROR_NODBSELECTED => 'no database selected', |
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_VALUE_COUNT_ON_ROW => 'value count on row', |
DB_ERROR_INVALID_DSN => 'invalid DSN', |
DB_ERROR_CONNECT_FAILED => 'connect failed', |
DB_OK => 'no error', |
DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied', |
DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found', |
DB_ERROR_NOSUCHDB => 'no such database', |
DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions', |
DB_ERROR_TRUNCATED => 'truncated' |
); |
} |
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 |
* |
* @author Tomas V.V.Cox <cox@idecnet.com> |
*/ |
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 |
// $dsn => proto(proto_opts)/database |
if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { |
$proto = $match[1]; |
$proto_opts = $match[2] ? $match[2] : false; |
$dsn = $match[3]; |
// $dsn => protocol+hostspec/database (old format) |
} else { |
if (strpos($dsn, '+') !== false) { |
list($proto, $dsn) = explode('+', $dsn, 2); |
} |
if (strpos($dsn, '/') !== false) { |
list($proto_opts, $dsn) = explode('/', $dsn, 2); |
} else { |
$proto_opts = $dsn; |
$dsn = null; |
} |
} |
// process the different protocol options |
$parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp'; |
$proto_opts = rawurldecode($proto_opts); |
if ($parsed['protocol'] == 'tcp') { |
if (strpos($proto_opts, ':') !== false) { |
list($parsed['hostspec'], $parsed['port']) = explode(':', $proto_opts); |
} else { |
$parsed['hostspec'] = $proto_opts; |
} |
} elseif ($parsed['protocol'] == 'unix') { |
$parsed['socket'] = $proto_opts; |
} |
// Get dabase if any |
// $dsn => database |
if ($dsn) { |
// /database |
if (($pos = strpos($dsn, '?')) === false) { |
$parsed['database'] = $dsn; |
// /database?param1=value1¶m2=value2 |
} else { |
$parsed['database'] = 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; |
} |
// }}} |
// {{{ assertExtension() |
/** |
* Load a PHP database extension if it is not loaded already. |
* |
* @access public |
* |
* @param string $name the base name of the extension (without the .so or |
* .dll suffix) |
* |
* @return boolean true if the extension was already or successfully |
* loaded, false if it could not be loaded |
*/ |
function assertExtension($name) |
{ |
if (!extension_loaded($name)) { |
$dlext = OS_WINDOWS ? '.dll' : '.so'; |
$dlprefix = OS_WINDOWS ? 'php_' : ''; |
@dl($dlprefix . $name . $dlext); |
return extension_loaded($name); |
} |
return true; |
} |
// }}} |
} |
// }}} |
// {{{ class DB_Error |
/** |
* DB_Error implements a class for reporting portable database error |
* messages. |
* |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
*/ |
class DB_Error extends PEAR_Error |
{ |
// {{{ constructor |
/** |
* DB_Error constructor. |
* |
* @param mixed $code DB error code, or string with error message. |
* @param integer $mode what "error mode" to operate in |
* @param integer $level what error level to use for $mode & PEAR_ERROR_TRIGGER |
* @param mixed $debuginfo additional debug info, such as the last query |
* |
* @access public |
* |
* @see PEAR_Error |
*/ |
function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN, |
$level = E_USER_NOTICE, $debuginfo = null) |
{ |
if (is_int($code)) { |
$this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo); |
} else { |
$this->PEAR_Error("DB Error: $code", DB_ERROR, $mode, $level, $debuginfo); |
} |
} |
// }}} |
} |
// }}} |
// {{{ class DB_result |
/** |
* This class implements a wrapper for a DB result set. |
* A new instance of this class will be returned by the DB implementation |
* after processing a query that returns data. |
* |
* @package DB |
* @author Stig Bakken <ssb@php.net> |
*/ |
class DB_result |
{ |
// {{{ properties |
var $dbh; |
var $result; |
var $row_counter = null; |
/** |
* for limit queries, the row to start fetching |
* @var integer |
*/ |
var $limit_from = null; |
/** |
* for limit queries, the number of rows to fetch |
* @var integer |
*/ |
var $limit_count = null; |
// }}} |
// {{{ constructor |
/** |
* DB_result constructor. |
* @param resource &$dbh DB object reference |
* @param resource $result result resource id |
* @param array $options assoc array with optional result options |
*/ |
function DB_result(&$dbh, $result, $options = array()) |
{ |
$this->dbh = &$dbh; |
$this->result = $result; |
foreach ($options as $key => $value) { |
$this->setOption($key, $value); |
} |
$this->limit_type = $dbh->features['limit']; |
$this->autofree = $dbh->options['autofree']; |
$this->fetchmode = $dbh->fetchmode; |
$this->fetchmode_object_class = $dbh->fetchmode_object_class; |
} |
function setOption($key, $value = null) |
{ |
switch ($key) { |
case 'limit_from': |
$this->limit_from = $value; break; |
case 'limit_count': |
$this->limit_count = $value; break; |
} |
} |
// }}} |
// {{{ 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(). |
* |
* + <samp>DB_PORTABILITY_LOWERCASE</samp> |
* convert names of fields to lower case |
* |
* + <samp>DB_PORTABILITY_RTRIM</samp> |
* right trim the data |
* |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch |
* |
* @return array a row of data, null on no more rows or PEAR_Error |
* object on error |
* |
* @see DB_common::setOption(), DB_common::setFetchMode() |
* @access public |
*/ |
function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null) |
{ |
if ($fetchmode === DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
if ($fetchmode === DB_FETCHMODE_OBJECT) { |
$fetchmode = DB_FETCHMODE_ASSOC; |
$object_class = $this->fetchmode_object_class; |
} |
if ($this->limit_from !== null) { |
if ($this->row_counter === null) { |
$this->row_counter = $this->limit_from; |
// Skip rows |
if ($this->limit_type == 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->limit_type == '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 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(). |
* |
* + <samp>DB_PORTABILITY_LOWERCASE</samp> |
* convert names of fields to lower case |
* |
* + <samp>DB_PORTABILITY_RTRIM</samp> |
* right trim the data |
* |
* @param array &$arr (reference) array where data from the row |
* should be placed |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch |
* |
* @return mixed DB_OK on success, null on no more rows or |
* a DB_Error object on error |
* |
* @see DB_common::setOption(), DB_common::setFetchMode() |
* @access public |
*/ |
function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null) |
{ |
if ($fetchmode === DB_FETCHMODE_DEFAULT) { |
$fetchmode = $this->fetchmode; |
} |
if ($fetchmode === DB_FETCHMODE_OBJECT) { |
$fetchmode = DB_FETCHMODE_ASSOC; |
$object_class = $this->fetchmode_object_class; |
} |
if ($this->limit_from !== null) { |
if ($this->row_counter === null) { |
$this->row_counter = $this->limit_from; |
// Skip rows |
if ($this->limit_type == 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->limit_type == '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 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, or a DB error |
* |
* @access public |
*/ |
function numCols() |
{ |
return $this->dbh->numCols($this->result); |
} |
// }}} |
// {{{ numRows() |
/** |
* Get the number of rows in a result set. |
* |
* @return int the number of rows, or a DB error |
* |
* @access public |
*/ |
function numRows() |
{ |
return $this->dbh->numRows($this->result); |
} |
// }}} |
// {{{ nextResult() |
/** |
* Get the next result if a batch of queries was executed. |
* |
* @return bool true if a new result is available or false if not. |
* |
* @access public |
*/ |
function nextResult() |
{ |
return $this->dbh->nextResult($this->result); |
} |
// }}} |
// {{{ free() |
/** |
* Frees the resources allocated for this result set. |
* @return int error code |
* |
* @access public |
*/ |
function free() |
{ |
$err = $this->dbh->freeResult($this->result); |
if (DB::isError($err)) { |
return $err; |
} |
$this->result = false; |
return true; |
} |
// }}} |
// {{{ tableInfo() |
/** |
* @deprecated |
* @internal |
* @see DB_common::tableInfo() |
*/ |
function tableInfo($mode = null) |
{ |
if (is_string($mode)) { |
return $this->dbh->raiseError(DB_ERROR_NEED_MORE_DATA); |
} |
return $this->dbh->tableInfo($this, $mode); |
} |
// }}} |
// {{{ getRowCounter() |
/** |
* returns the actual row number |
* @return integer |
*/ |
function getRowCounter() |
{ |
return $this->row_counter; |
} |
// }}} |
} |
// }}} |
// {{{ class DB_row |
/** |
* Pear DB Row Object |
* @see DB_common::setFetchMode() |
*/ |
class DB_row |
{ |
// {{{ constructor |
/** |
* constructor |
* |
* @param resource row data as array |
*/ |
function DB_row(&$arr) |
{ |
foreach ($arr as $key => $value) { |
$this->$key = &$arr[$key]; |
} |
} |
// }}} |
} |
// }}} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/v1.6-croc/jrest/lib/PEAR.php |
---|
New file |
0,0 → 1,971 |
<?php |
// |
// +----------------------------------------------------------------------+ |
// | PEAR, the PHP Extension and Application Repository | |
// +----------------------------------------------------------------------+ |
// | Copyright (c) 1997-2004 The PHP Group | |
// +----------------------------------------------------------------------+ |
// | This source file is subject to version 2.0 of the PHP license, | |
// | that is bundled with this package in the file LICENSE, and is | |
// | available through the world-wide-web at the following url: | |
// | http://www.php.net/license/3_0.txt. | |
// | If you did not receive a copy of the PHP license and are unable to | |
// | obtain it through the world-wide-web, please send a note to | |
// | license@php.net so we can mail you a copy immediately. | |
// +----------------------------------------------------------------------+ |
// | Authors: Sterling Hughes <sterling@php.net> | |
// | Stig Bakken <ssb@php.net> | |
// | Tomas V.V.Cox <cox@idecnet.com> | |
// +----------------------------------------------------------------------+ |
// |
// $Id$ |
// |
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); |
define('PEAR_ERROR_EXCEPTION', 32); |
define('PEAR_ZE2', (function_exists('version_compare') && |
version_compare(zend_version(), "2-dev", "ge"))); |
if (substr(PHP_OS, 0, 3) == 'WIN') { |
define('OS_WINDOWS', true); |
define('OS_UNIX', false); |
define('PEAR_OS', 'Windows'); |
} else { |
define('OS_WINDOWS', false); |
define('OS_UNIX', true); |
define('PEAR_OS', 'Unix'); // blatant assumption |
} |
// instant backwards compatibility |
if (!defined('PATH_SEPARATOR')) { |
if (OS_WINDOWS) { |
define('PATH_SEPARATOR', ';'); |
} else { |
define('PATH_SEPARATOR', ':'); |
} |
} |
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; |
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; |
$GLOBALS['_PEAR_destructor_object_list'] = array(); |
$GLOBALS['_PEAR_shutdown_funcs'] = array(); |
$GLOBALS['_PEAR_error_handler_stack'] = array(); |
ini_set('track_errors', true); |
/** |
* Base class for other PEAR classes. Provides rudimentary |
* emulation of destructors. |
* |
* If you want a destructor in your class, inherit PEAR and make a |
* destructor method called _yourclassname (same name as the |
* constructor, but with a "_" prefix). Also, in your constructor you |
* have to call the PEAR constructor: $this->PEAR();. |
* The destructor method will be called without parameters. Note that |
* at in some SAPI implementations (such as Apache), any output during |
* the request shutdown (in which destructors are called) seems to be |
* discarded. If you need to get any debug information from your |
* destructor, use error_log(), syslog() or something similar. |
* |
* IMPORTANT! To use the emulated destructors you need to create the |
* objects by reference: $obj =& new PEAR_child; |
* |
* @since PHP 4.0.2 |
* @author Stig Bakken <ssb@php.net> |
* @see http://pear.php.net/manual/ |
*/ |
class PEAR |
{ |
// {{{ properties |
/** |
* Whether to enable internal debug messages. |
* |
* @var bool |
* @access private |
*/ |
var $_debug = false; |
/** |
* Default error mode for this object. |
* |
* @var int |
* @access private |
*/ |
var $_default_error_mode = null; |
/** |
* Default error options used for this object when error mode |
* is PEAR_ERROR_TRIGGER. |
* |
* @var int |
* @access private |
*/ |
var $_default_error_options = null; |
/** |
* Default error handler (callback) for this object, if error mode is |
* PEAR_ERROR_CALLBACK. |
* |
* @var string |
* @access private |
*/ |
var $_default_error_handler = ''; |
/** |
* Which class to use for error objects. |
* |
* @var string |
* @access private |
*/ |
var $_error_class = 'PEAR_Error'; |
/** |
* An array of expected errors. |
* |
* @var array |
* @access private |
*/ |
var $_expected_errors = array(); |
// }}} |
// {{{ constructor |
/** |
* Constructor. Registers this object in |
* $_PEAR_destructor_object_list for destructor emulation if a |
* destructor object exists. |
* |
* @param string $error_class (optional) which class to use for |
* error objects, defaults to PEAR_Error. |
* @access public |
* @return void |
*/ |
function PEAR($error_class = null) |
{ |
$classname = get_class($this); |
if ($this->_debug) { |
print "PEAR constructor called, class=$classname\n"; |
} |
if ($error_class !== null) { |
$this->_error_class = $error_class; |
} |
while ($classname) { |
$destructor = "_$classname"; |
if (method_exists($this, $destructor)) { |
global $_PEAR_destructor_object_list; |
$_PEAR_destructor_object_list[] = &$this; |
break; |
} else { |
$classname = get_parent_class($classname); |
} |
} |
} |
// }}} |
// {{{ destructor |
/** |
* Destructor (the emulated type of...). Does nothing right now, |
* but is included for forward compatibility, so subclass |
* destructors should always call it. |
* |
* See the note in the class desciption about output from |
* destructors. |
* |
* @access public |
* @return void |
*/ |
function _PEAR() { |
if ($this->_debug) { |
printf("PEAR destructor called, class=%s\n", get_class($this)); |
} |
} |
// }}} |
// {{{ getStaticProperty() |
/** |
* If you have a class that's mostly/entirely static, and you need static |
* properties, you can use this method to simulate them. Eg. in your method(s) |
* do this: $myVar = &PEAR::getStaticProperty('myVar'); |
* You MUST use a reference, or they will not persist! |
* |
* @access public |
* @param string $class The calling classname, to prevent clashes |
* @param string $var The variable to retrieve. |
* @return mixed A reference to the variable. If not set it will be |
* auto initialised to NULL. |
*/ |
function &getStaticProperty($class, $var) |
{ |
static $properties; |
return $properties[$class][$var]; |
} |
// }}} |
// {{{ registerShutdownFunc() |
/** |
* Use this function to register a shutdown method for static |
* classes. |
* |
* @access public |
* @param mixed $func The function name (or array of class/method) to call |
* @param mixed $args The arguments to pass to the function |
* @return void |
*/ |
function registerShutdownFunc($func, $args = array()) |
{ |
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); |
} |
// }}} |
// {{{ isError() |
/** |
* Tell whether a value is a PEAR error. |
* |
* @param mixed $data the value to test |
* @param int $code if $data is an error object, return true |
* only if $code is a string and |
* $obj->getMessage() == $code or |
* $code is an integer and $obj->getCode() == $code |
* @access public |
* @return bool true if parameter is an error |
*/ |
function isError($data, $code = null) |
{ |
if (is_a($data, 'PEAR_Error')) { |
if (is_null($code)) { |
return true; |
} elseif (is_string($code)) { |
return $data->getMessage() == $code; |
} else { |
return $data->getCode() == $code; |
} |
} |
return false; |
} |
// }}} |
// {{{ setErrorHandling() |
/** |
* Sets how errors generated by this object should be handled. |
* Can be invoked both in objects and statically. If called |
* statically, setErrorHandling sets the default behaviour for all |
* PEAR objects. If called in an object, setErrorHandling sets |
* the default behaviour for that object. |
* |
* @param int $mode |
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, |
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, |
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. |
* |
* @param mixed $options |
* When $mode is PEAR_ERROR_TRIGGER, this is the error level (one |
* of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). |
* |
* When $mode is PEAR_ERROR_CALLBACK, this parameter is expected |
* to be the callback function or method. A callback |
* function is a string with the name of the function, a |
* callback method is an array of two elements: the element |
* at index 0 is the object, and the element at index 1 is |
* the name of the method to call in the object. |
* |
* When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is |
* a printf format string used when printing the error |
* message. |
* |
* @access public |
* @return void |
* @see PEAR_ERROR_RETURN |
* @see PEAR_ERROR_PRINT |
* @see PEAR_ERROR_TRIGGER |
* @see PEAR_ERROR_DIE |
* @see PEAR_ERROR_CALLBACK |
* @see PEAR_ERROR_EXCEPTION |
* |
* @since PHP 4.0.5 |
*/ |
function setErrorHandling($mode = null, $options = null) |
{ |
if (isset($this) && is_a($this, 'PEAR')) { |
$setmode = &$this->_default_error_mode; |
$setoptions = &$this->_default_error_options; |
} else { |
$setmode = &$GLOBALS['_PEAR_default_error_mode']; |
$setoptions = &$GLOBALS['_PEAR_default_error_options']; |
} |
switch ($mode) { |
case PEAR_ERROR_RETURN: |
case PEAR_ERROR_PRINT: |
case PEAR_ERROR_TRIGGER: |
case PEAR_ERROR_DIE: |
case PEAR_ERROR_EXCEPTION: |
case null: |
$setmode = $mode; |
$setoptions = $options; |
break; |
case PEAR_ERROR_CALLBACK: |
$setmode = $mode; |
// class/object method callback |
if (is_callable($options)) { |
$setoptions = $options; |
} else { |
trigger_error("invalid error callback", E_USER_WARNING); |
} |
break; |
default: |
trigger_error("invalid error mode", E_USER_WARNING); |
break; |
} |
} |
// }}} |
// {{{ expectError() |
/** |
* This method is used to tell which errors you expect to get. |
* Expected errors are always returned with error mode |
* PEAR_ERROR_RETURN. Expected error codes are stored in a stack, |
* and this method pushes a new element onto it. The list of |
* expected errors are in effect until they are popped off the |
* stack with the popExpect() method. |
* |
* Note that this method can not be called statically |
* |
* @param mixed $code a single error code or an array of error codes to expect |
* |
* @return int the new depth of the "expected errors" stack |
* @access public |
*/ |
function expectError($code = '*') |
{ |
if (is_array($code)) { |
array_push($this->_expected_errors, $code); |
} else { |
array_push($this->_expected_errors, array($code)); |
} |
return sizeof($this->_expected_errors); |
} |
// }}} |
// {{{ popExpect() |
/** |
* This method pops one element off the expected error codes |
* stack. |
* |
* @return array the list of error codes that were popped |
*/ |
function popExpect() |
{ |
return array_pop($this->_expected_errors); |
} |
// }}} |
// {{{ _checkDelExpect() |
/** |
* This method checks unsets an error code if available |
* |
* @param mixed error code |
* @return bool true if the error code was unset, false otherwise |
* @access private |
* @since PHP 4.3.0 |
*/ |
function _checkDelExpect($error_code) |
{ |
$deleted = false; |
foreach ($this->_expected_errors AS $key => $error_array) { |
if (in_array($error_code, $error_array)) { |
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); |
$deleted = true; |
} |
// clean up empty arrays |
if (0 == count($this->_expected_errors[$key])) { |
unset($this->_expected_errors[$key]); |
} |
} |
return $deleted; |
} |
// }}} |
// {{{ delExpect() |
/** |
* This method deletes all occurences of the specified element from |
* the expected error codes stack. |
* |
* @param mixed $error_code error code that should be deleted |
* @return mixed list of error codes that were deleted or error |
* @access public |
* @since PHP 4.3.0 |
*/ |
function delExpect($error_code) |
{ |
$deleted = false; |
if ((is_array($error_code) && (0 != count($error_code)))) { |
// $error_code is a non-empty array here; |
// we walk through it trying to unset all |
// values |
foreach($error_code as $key => $error) { |
if ($this->_checkDelExpect($error)) { |
$deleted = true; |
} else { |
$deleted = false; |
} |
} |
return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME |
} elseif (!empty($error_code)) { |
// $error_code comes alone, trying to unset it |
if ($this->_checkDelExpect($error_code)) { |
return true; |
} else { |
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME |
} |
} else { |
// $error_code is empty |
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME |
} |
} |
// }}} |
// {{{ raiseError() |
/** |
* This method is a wrapper that returns an instance of the |
* configured error class with this object's default error |
* handling applied. If the $mode and $options parameters are not |
* specified, the object's defaults are used. |
* |
* @param mixed $message a text error message or a PEAR error object |
* |
* @param int $code a numeric error code (it is up to your class |
* to define these if you want to use codes) |
* |
* @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, |
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, |
* PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. |
* |
* @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter |
* specifies the PHP-internal error level (one of |
* E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). |
* If $mode is PEAR_ERROR_CALLBACK, this |
* parameter specifies the callback function or |
* method. In other error modes this parameter |
* is ignored. |
* |
* @param string $userinfo If you need to pass along for example debug |
* information, this parameter is meant for that. |
* |
* @param string $error_class The returned error object will be |
* instantiated from this class, if specified. |
* |
* @param bool $skipmsg If true, raiseError will only pass error codes, |
* the error message parameter will be dropped. |
* |
* @access public |
* @return object a PEAR error object |
* @see PEAR::setErrorHandling |
* @since PHP 4.0.5 |
*/ |
function raiseError($message = null, |
$code = null, |
$mode = null, |
$options = null, |
$userinfo = null, |
$error_class = null, |
$skipmsg = false) |
{ |
// The error is yet a PEAR error object |
if (is_object($message)) { |
$code = $message->getCode(); |
$userinfo = $message->getUserInfo(); |
$error_class = $message->getType(); |
$message->error_message_prefix = ''; |
$message = $message->getMessage(); |
} |
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { |
if ($exp[0] == "*" || |
(is_int(reset($exp)) && in_array($code, $exp)) || |
(is_string(reset($exp)) && in_array($message, $exp))) { |
$mode = PEAR_ERROR_RETURN; |
} |
} |
// No mode given, try global ones |
if ($mode === null) { |
// Class error handler |
if (isset($this) && isset($this->_default_error_mode)) { |
$mode = $this->_default_error_mode; |
$options = $this->_default_error_options; |
// Global error handler |
} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { |
$mode = $GLOBALS['_PEAR_default_error_mode']; |
$options = $GLOBALS['_PEAR_default_error_options']; |
} |
} |
if ($error_class !== null) { |
$ec = $error_class; |
} elseif (isset($this) && isset($this->_error_class)) { |
$ec = $this->_error_class; |
} else { |
$ec = 'PEAR_Error'; |
} |
if ($skipmsg) { |
return new $ec($code, $mode, $options, $userinfo); |
} else { |
return new $ec($message, $code, $mode, $options, $userinfo); |
} |
} |
// }}} |
// {{{ throwError() |
/** |
* Simpler form of raiseError with fewer options. In most cases |
* message, code and userinfo are enough. |
* |
* @param string $message |
* |
*/ |
function throwError($message = null, |
$code = null, |
$userinfo = null) |
{ |
if (isset($this) && is_subclass_of($this, 'PEAR_Error')) { |
return $this->raiseError($message, $code, null, null, $userinfo); |
} else { |
return PEAR::raiseError($message, $code, null, null, $userinfo); |
} |
} |
// }}} |
// {{{ pushErrorHandling() |
/** |
* Push a new error handler on top of the error handler options stack. With this |
* you can easily override the actual error handler for some code and restore |
* it later with popErrorHandling. |
* |
* @param mixed $mode (same as setErrorHandling) |
* @param mixed $options (same as setErrorHandling) |
* |
* @return bool Always true |
* |
* @see PEAR::setErrorHandling |
*/ |
function pushErrorHandling($mode, $options = null) |
{ |
$stack = &$GLOBALS['_PEAR_error_handler_stack']; |
if (isset($this) && is_a($this, 'PEAR')) { |
$def_mode = &$this->_default_error_mode; |
$def_options = &$this->_default_error_options; |
} else { |
$def_mode = &$GLOBALS['_PEAR_default_error_mode']; |
$def_options = &$GLOBALS['_PEAR_default_error_options']; |
} |
$stack[] = array($def_mode, $def_options); |
if (isset($this) && is_a($this, 'PEAR')) { |
$this->setErrorHandling($mode, $options); |
} else { |
PEAR::setErrorHandling($mode, $options); |
} |
$stack[] = array($mode, $options); |
return true; |
} |
// }}} |
// {{{ popErrorHandling() |
/** |
* Pop the last error handler used |
* |
* @return bool Always true |
* |
* @see PEAR::pushErrorHandling |
*/ |
function popErrorHandling() |
{ |
$stack = &$GLOBALS['_PEAR_error_handler_stack']; |
array_pop($stack); |
list($mode, $options) = $stack[sizeof($stack) - 1]; |
array_pop($stack); |
if (isset($this) && is_a($this, 'PEAR')) { |
$this->setErrorHandling($mode, $options); |
} else { |
PEAR::setErrorHandling($mode, $options); |
} |
return true; |
} |
// }}} |
// {{{ loadExtension() |
/** |
* OS independant PHP extension load. Remember to take care |
* on the correct extension name for case sensitive OSes. |
* |
* @param string $ext The extension name |
* @return bool Success or not on the dl() call |
*/ |
function loadExtension($ext) |
{ |
if (!extension_loaded($ext)) { |
// if either returns true dl() will produce a FATAL error, stop that |
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) { |
return false; |
} |
if (OS_WINDOWS) { |
$suffix = '.dll'; |
} elseif (PHP_OS == 'HP-UX') { |
$suffix = '.sl'; |
} elseif (PHP_OS == 'AIX') { |
$suffix = '.a'; |
} elseif (PHP_OS == 'OSX') { |
$suffix = '.bundle'; |
} else { |
$suffix = '.so'; |
} |
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); |
} |
return true; |
} |
// }}} |
} |
// {{{ _PEAR_call_destructors() |
function _PEAR_call_destructors() |
{ |
global $_PEAR_destructor_object_list; |
if (is_array($_PEAR_destructor_object_list) && |
sizeof($_PEAR_destructor_object_list)) |
{ |
reset($_PEAR_destructor_object_list); |
while (list($k, $objref) = each($_PEAR_destructor_object_list)) { |
$classname = get_class($objref); |
while ($classname) { |
$destructor = "_$classname"; |
if (method_exists($objref, $destructor)) { |
$objref->$destructor(); |
break; |
} else { |
$classname = get_parent_class($classname); |
} |
} |
} |
// Empty the object list to ensure that destructors are |
// not called more than once. |
$_PEAR_destructor_object_list = array(); |
} |
// Now call the shutdown functions |
if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { |
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { |
call_user_func_array($value[0], $value[1]); |
} |
} |
} |
// }}} |
class PEAR_Error |
{ |
// {{{ properties |
var $error_message_prefix = ''; |
var $mode = PEAR_ERROR_RETURN; |
var $level = E_USER_NOTICE; |
var $code = -1; |
var $message = ''; |
var $userinfo = ''; |
var $backtrace = null; |
// }}} |
// {{{ constructor |
/** |
* PEAR_Error constructor |
* |
* @param string $message message |
* |
* @param int $code (optional) error code |
* |
* @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, |
* PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, |
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION |
* |
* @param mixed $options (optional) error level, _OR_ in the case of |
* PEAR_ERROR_CALLBACK, the callback function or object/method |
* tuple. |
* |
* @param string $userinfo (optional) additional user/debug info |
* |
* @access public |
* |
*/ |
function PEAR_Error($message = 'unknown error', $code = null, |
$mode = null, $options = null, $userinfo = null) |
{ |
if ($mode === null) { |
$mode = PEAR_ERROR_RETURN; |
} |
$this->message = $message; |
$this->code = $code; |
$this->mode = $mode; |
$this->userinfo = $userinfo; |
if (function_exists("debug_backtrace")) { |
$this->backtrace = debug_backtrace(); |
} |
if ($mode & PEAR_ERROR_CALLBACK) { |
$this->level = E_USER_NOTICE; |
$this->callback = $options; |
} else { |
if ($options === null) { |
$options = E_USER_NOTICE; |
} |
$this->level = $options; |
$this->callback = null; |
} |
if ($this->mode & PEAR_ERROR_PRINT) { |
if (is_null($options) || is_int($options)) { |
$format = "%s"; |
} else { |
$format = $options; |
} |
printf($format, $this->getMessage()); |
} |
if ($this->mode & PEAR_ERROR_TRIGGER) { |
trigger_error($this->getMessage(), $this->level); |
} |
if ($this->mode & PEAR_ERROR_DIE) { |
$msg = $this->getMessage(); |
if (is_null($options) || is_int($options)) { |
$format = "%s"; |
if (substr($msg, -1) != "\n") { |
$msg .= "\n"; |
} |
} else { |
$format = $options; |
} |
die(sprintf($format, $msg)); |
} |
if ($this->mode & PEAR_ERROR_CALLBACK) { |
if (is_callable($this->callback)) { |
call_user_func($this->callback, $this); |
} |
} |
if (PEAR_ZE2 && $this->mode & PEAR_ERROR_EXCEPTION) { |
eval('throw $this;'); |
} |
} |
// }}} |
// {{{ getMode() |
/** |
* Get the error mode from an error object. |
* |
* @return int error mode |
* @access public |
*/ |
function getMode() { |
return $this->mode; |
} |
// }}} |
// {{{ getCallback() |
/** |
* Get the callback function/method from an error object. |
* |
* @return mixed callback function or object/method array |
* @access public |
*/ |
function getCallback() { |
return $this->callback; |
} |
// }}} |
// {{{ getMessage() |
/** |
* Get the error message from an error object. |
* |
* @return string full error message |
* @access public |
*/ |
function getMessage() |
{ |
return ($this->error_message_prefix . $this->message); |
} |
// }}} |
// {{{ getCode() |
/** |
* Get error code from an error object |
* |
* @return int error code |
* @access public |
*/ |
function getCode() |
{ |
return $this->code; |
} |
// }}} |
// {{{ getType() |
/** |
* Get the name of this error/exception. |
* |
* @return string error/exception name (type) |
* @access public |
*/ |
function getType() |
{ |
return get_class($this); |
} |
// }}} |
// {{{ getUserInfo() |
/** |
* Get additional user-supplied information. |
* |
* @return string user-supplied information |
* @access public |
*/ |
function getUserInfo() |
{ |
return $this->userinfo; |
} |
// }}} |
// {{{ getDebugInfo() |
/** |
* Get additional debug information supplied by the application. |
* |
* @return string debug information |
* @access public |
*/ |
function getDebugInfo() |
{ |
return $this->getUserInfo(); |
} |
// }}} |
// {{{ getBacktrace() |
/** |
* Get the call backtrace from where the error was generated. |
* Supported with PHP 4.3.0 or newer. |
* |
* @param int $frame (optional) what frame to fetch |
* @return array Backtrace, or NULL if not available. |
* @access public |
*/ |
function getBacktrace($frame = null) |
{ |
if ($frame === null) { |
return $this->backtrace; |
} |
return $this->backtrace[$frame]; |
} |
// }}} |
// {{{ addUserInfo() |
function addUserInfo($info) |
{ |
if (empty($this->userinfo)) { |
$this->userinfo = $info; |
} else { |
$this->userinfo .= " ** $info"; |
} |
} |
// }}} |
// {{{ toString() |
/** |
* Make a string representation of this object. |
* |
* @return string a string with an object summary |
* @access public |
*/ |
function toString() { |
$modes = array(); |
$levels = array(E_USER_NOTICE => 'notice', |
E_USER_WARNING => 'warning', |
E_USER_ERROR => 'error'); |
if ($this->mode & PEAR_ERROR_CALLBACK) { |
if (is_array($this->callback)) { |
$callback = get_class($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"]', |
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"]', |
get_class($this), $this->message, $this->code, |
implode("|", $modes), $levels[$this->level], |
$this->error_message_prefix, |
$this->userinfo); |
} |
// }}} |
} |
register_shutdown_function("_PEAR_call_destructors"); |
/* |
* Local Variables: |
* mode: php |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/v1.6-croc/jrest/lib/HTTP/Download.php |
---|
New file |
0,0 → 1,1034 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* HTTP::Download |
* |
* PHP versions 4 and 5 |
* |
* @category HTTP |
* @package HTTP_Download |
* @author Michael Wallner <mike@php.net> |
* @copyright 2003-2005 Michael Wallner |
* @license BSD, revised |
* @version CVS: $Id$ |
* @link http://pear.php.net/package/HTTP_Download |
*/ |
// {{{ includes |
/** |
* Requires PEAR |
*/ |
require_once 'PEAR.php'; |
/** |
* Requires HTTP_Header |
*/ |
require_once 'HTTP/Header.php'; |
// }}} |
// {{{ constants |
/**#@+ Use with HTTP_Download::setContentDisposition() **/ |
/** |
* Send data as attachment |
*/ |
define('HTTP_DOWNLOAD_ATTACHMENT', 'attachment'); |
/** |
* Send data inline |
*/ |
define('HTTP_DOWNLOAD_INLINE', 'inline'); |
/**#@-**/ |
/**#@+ Use with HTTP_Download::sendArchive() **/ |
/** |
* Send as uncompressed tar archive |
*/ |
define('HTTP_DOWNLOAD_TAR', 'TAR'); |
/** |
* Send as gzipped tar archive |
*/ |
define('HTTP_DOWNLOAD_TGZ', 'TGZ'); |
/** |
* Send as bzip2 compressed tar archive |
*/ |
define('HTTP_DOWNLOAD_BZ2', 'BZ2'); |
/** |
* Send as zip archive |
*/ |
define('HTTP_DOWNLOAD_ZIP', 'ZIP'); |
/**#@-**/ |
/**#@+ |
* Error constants |
*/ |
define('HTTP_DOWNLOAD_E_HEADERS_SENT', -1); |
define('HTTP_DOWNLOAD_E_NO_EXT_ZLIB', -2); |
define('HTTP_DOWNLOAD_E_NO_EXT_MMAGIC', -3); |
define('HTTP_DOWNLOAD_E_INVALID_FILE', -4); |
define('HTTP_DOWNLOAD_E_INVALID_PARAM', -5); |
define('HTTP_DOWNLOAD_E_INVALID_RESOURCE', -6); |
define('HTTP_DOWNLOAD_E_INVALID_REQUEST', -7); |
define('HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE', -8); |
define('HTTP_DOWNLOAD_E_INVALID_ARCHIVE_TYPE', -9); |
/**#@-**/ |
// }}} |
/** |
* Send HTTP Downloads/Responses. |
* |
* With this package you can handle (hidden) downloads. |
* It supports partial downloads, resuming and sending |
* raw data ie. from database BLOBs. |
* |
* <i>ATTENTION:</i> |
* You shouldn't use this package together with ob_gzhandler or |
* zlib.output_compression enabled in your php.ini, especially |
* if you want to send already gzipped data! |
* |
* @access public |
* @version $Revision$ |
*/ |
class HTTP_Download |
{ |
// {{{ protected member variables |
/** |
* Path to file for download |
* |
* @see HTTP_Download::setFile() |
* @access protected |
* @var string |
*/ |
var $file = ''; |
/** |
* Data for download |
* |
* @see HTTP_Download::setData() |
* @access protected |
* @var string |
*/ |
var $data = null; |
/** |
* Resource handle for download |
* |
* @see HTTP_Download::setResource() |
* @access protected |
* @var int |
*/ |
var $handle = null; |
/** |
* Whether to gzip the download |
* |
* @access protected |
* @var bool |
*/ |
var $gzip = false; |
/** |
* Whether to allow caching of the download on the clients side |
* |
* @access protected |
* @var bool |
*/ |
var $cache = true; |
/** |
* Size of download |
* |
* @access protected |
* @var int |
*/ |
var $size = 0; |
/** |
* Last modified |
* |
* @access protected |
* @var int |
*/ |
var $lastModified = 0; |
/** |
* HTTP headers |
* |
* @access protected |
* @var array |
*/ |
var $headers = array( |
'Content-Type' => 'application/x-octetstream', |
'Pragma' => 'cache', |
'Cache-Control' => 'public, must-revalidate, max-age=0', |
'Accept-Ranges' => 'bytes', |
'X-Sent-By' => 'PEAR::HTTP::Download' |
); |
/** |
* HTTP_Header |
* |
* @access protected |
* @var object |
*/ |
var $HTTP = null; |
/** |
* ETag |
* |
* @access protected |
* @var string |
*/ |
var $etag = ''; |
/** |
* Buffer Size |
* |
* @access protected |
* @var int |
*/ |
var $bufferSize = 2097152; |
/** |
* Throttle Delay |
* |
* @access protected |
* @var float |
*/ |
var $throttleDelay = 0; |
/** |
* Sent Bytes |
* |
* @access public |
* @var int |
*/ |
var $sentBytes = 0; |
// }}} |
// {{{ constructor |
/** |
* Constructor |
* |
* Set supplied parameters. |
* |
* @access public |
* @param array $params associative array of parameters |
* |
* <b>one of:</b> |
* o 'file' => path to file for download |
* o 'data' => raw data for download |
* o 'resource' => resource handle for download |
* <br/> |
* <b>and any of:</b> |
* o 'cache' => whether to allow cs caching |
* o 'gzip' => whether to gzip the download |
* o 'lastmodified' => unix timestamp |
* o 'contenttype' => content type of download |
* o 'contentdisposition' => content disposition |
* o 'buffersize' => amount of bytes to buffer |
* o 'throttledelay' => amount of secs to sleep |
* o 'cachecontrol' => cache privacy and validity |
* |
* <br /> |
* 'Content-Disposition' is not HTTP compliant, but most browsers |
* follow this header, so it was borrowed from MIME standard. |
* |
* It looks like this: <br /> |
* "Content-Disposition: attachment; filename=example.tgz". |
* |
* @see HTTP_Download::setContentDisposition() |
*/ |
function HTTP_Download($params = array()) |
{ |
$this->HTTP = &new HTTP_Header; |
$this->setParams($params); |
} |
// }}} |
// {{{ public methods |
/** |
* Set parameters |
* |
* Set supplied parameters through its accessor methods. |
* |
* @access public |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param array $params associative array of parameters |
* |
* @see HTTP_Download::HTTP_Download() |
*/ |
function setParams($params) |
{ |
foreach((array) $params as $param => $value){ |
$method = 'set'. $param; |
if (!method_exists($this, $method)) { |
return PEAR::raiseError( |
"Method '$method' doesn't exist.", |
HTTP_DOWNLOAD_E_INVALID_PARAM |
); |
} |
$e = call_user_func_array(array(&$this, $method), (array) $value); |
if (PEAR::isError($e)) { |
return $e; |
} |
} |
return true; |
} |
/** |
* Set path to file for download |
* |
* The Last-Modified header will be set to files filemtime(), actually. |
* Returns PEAR_Error (HTTP_DOWNLOAD_E_INVALID_FILE) if file doesn't exist. |
* Sends HTTP 404 status if $send_404 is set to true. |
* |
* @access public |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param string $file path to file for download |
* @param bool $send_404 whether to send HTTP/404 if |
* the file wasn't found |
*/ |
function setFile($file, $send_404 = true) |
{ |
$file = realpath($file); |
if (!is_file($file)) { |
if ($send_404) { |
$this->HTTP->sendStatusCode(404); |
} |
return PEAR::raiseError( |
"File '$file' not found.", |
HTTP_DOWNLOAD_E_INVALID_FILE |
); |
} |
$this->setLastModified(filemtime($file)); |
$this->file = $file; |
$this->size = filesize($file); |
return true; |
} |
/** |
* Set data for download |
* |
* Set $data to null if you want to unset this. |
* |
* @access public |
* @return void |
* @param $data raw data to send |
*/ |
function setData($data = null) |
{ |
$this->data = $data; |
$this->size = strlen($data); |
} |
/** |
* Set resource for download |
* |
* The resource handle supplied will be closed after sending the download. |
* Returns a PEAR_Error (HTTP_DOWNLOAD_E_INVALID_RESOURCE) if $handle |
* is no valid resource. Set $handle to null if you want to unset this. |
* |
* @access public |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param int $handle resource handle |
*/ |
function setResource($handle = null) |
{ |
if (!isset($handle)) { |
$this->handle = null; |
$this->size = 0; |
return true; |
} |
if (is_resource($handle)) { |
$this->handle = $handle; |
$filestats = fstat($handle); |
$this->size = $filestats['size']; |
return true; |
} |
return PEAR::raiseError( |
"Handle '$handle' is no valid resource.", |
HTTP_DOWNLOAD_E_INVALID_RESOURCE |
); |
} |
/** |
* Whether to gzip the download |
* |
* Returns a PEAR_Error (HTTP_DOWNLOAD_E_NO_EXT_ZLIB) |
* if ext/zlib is not available/loadable. |
* |
* @access public |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param bool $gzip whether to gzip the download |
*/ |
function setGzip($gzip = false) |
{ |
if ($gzip && !PEAR::loadExtension('zlib')){ |
return PEAR::raiseError( |
'GZIP compression (ext/zlib) not available.', |
HTTP_DOWNLOAD_E_NO_EXT_ZLIB |
); |
} |
$this->gzip = (bool) $gzip; |
return true; |
} |
/** |
* Whether to allow caching |
* |
* If set to true (default) we'll send some headers that are commonly |
* used for caching purposes like ETag, Cache-Control and Last-Modified. |
* |
* If caching is disabled, we'll send the download no matter if it |
* would actually be cached at the client side. |
* |
* @access public |
* @return void |
* @param bool $cache whether to allow caching |
*/ |
function setCache($cache = true) |
{ |
$this->cache = (bool) $cache; |
} |
/** |
* Whether to allow proxies to cache |
* |
* If set to 'private' proxies shouldn't cache the response. |
* This setting defaults to 'public' and affects only cached responses. |
* |
* @access public |
* @return bool |
* @param string $cache private or public |
* @param int $maxage maximum age of the client cache entry |
*/ |
function setCacheControl($cache = 'public', $maxage = 0) |
{ |
switch ($cache = strToLower($cache)) |
{ |
case 'private': |
case 'public': |
$this->headers['Cache-Control'] = |
$cache .', must-revalidate, max-age='. abs($maxage); |
return true; |
break; |
} |
return false; |
} |
/** |
* Set ETag |
* |
* Sets a user-defined ETag for cache-validation. The ETag is usually |
* generated by HTTP_Download through its payload information. |
* |
* @access public |
* @return void |
* @param string $etag Entity tag used for strong cache validation. |
*/ |
function setETag($etag = null) |
{ |
$this->etag = (string) $etag; |
} |
/** |
* Set Size of Buffer |
* |
* The amount of bytes specified as buffer size is the maximum amount |
* of data read at once from resources or files. The default size is 2M |
* (2097152 bytes). Be aware that if you enable gzip compression and |
* you set a very low buffer size that the actual file size may grow |
* due to added gzip headers for each sent chunk of the specified size. |
* |
* Returns PEAR_Error (HTTP_DOWNLOAD_E_INVALID_PARAM) if $size is not |
* greater than 0 bytes. |
* |
* @access public |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param int $bytes Amount of bytes to use as buffer. |
*/ |
function setBufferSize($bytes = 2097152) |
{ |
if (0 >= $bytes) { |
return PEAR::raiseError( |
'Buffer size must be greater than 0 bytes ('. $bytes .' given)', |
HTTP_DOWNLOAD_E_INVALID_PARAM); |
} |
$this->bufferSize = abs($bytes); |
return true; |
} |
/** |
* Set Throttle Delay |
* |
* Set the amount of seconds to sleep after each chunck that has been |
* sent. One can implement some sort of throttle through adjusting the |
* buffer size and the throttle delay. With the following settings |
* HTTP_Download will sleep a second after each 25 K of data sent. |
* |
* <code> |
* Array( |
* 'throttledelay' => 1, |
* 'buffersize' => 1024 * 25, |
* ) |
* </code> |
* |
* Just be aware that if gzipp'ing is enabled, decreasing the chunk size |
* too much leads to proportionally increased network traffic due to added |
* gzip header and bottom bytes around each chunk. |
* |
* @access public |
* @return void |
* @param float $seconds Amount of seconds to sleep after each |
* chunk that has been sent. |
*/ |
function setThrottleDelay($seconds = 0) |
{ |
$this->throttleDelay = abs($seconds) * 1000; |
} |
/** |
* Set "Last-Modified" |
* |
* This is usually determined by filemtime() in HTTP_Download::setFile() |
* If you set raw data for download with HTTP_Download::setData() and you |
* want do send an appropiate "Last-Modified" header, you should call this |
* method. |
* |
* @access public |
* @return void |
* @param int unix timestamp |
*/ |
function setLastModified($last_modified) |
{ |
$this->lastModified = $this->headers['Last-Modified'] = (int) $last_modified; |
} |
/** |
* Set Content-Disposition header |
* |
* @see HTTP_Download::HTTP_Download |
* |
* @access public |
* @return void |
* @param string $disposition whether to send the download |
* inline or as attachment |
* @param string $file_name the filename to display in |
* the browser's download window |
* |
* <b>Example:</b> |
* <code> |
* $HTTP_Download->setContentDisposition( |
* HTTP_DOWNLOAD_ATTACHMENT, |
* 'download.tgz' |
* ); |
* </code> |
*/ |
function setContentDisposition( $disposition = HTTP_DOWNLOAD_ATTACHMENT, |
$file_name = null) |
{ |
$cd = $disposition; |
if (isset($file_name)) { |
$cd .= '; filename="' . $file_name . '"'; |
} elseif ($this->file) { |
$cd .= '; filename="' . basename($this->file) . '"'; |
} |
$this->headers['Content-Disposition'] = $cd; |
} |
/** |
* Set content type of the download |
* |
* Default content type of the download will be 'application/x-octetstream'. |
* Returns PEAR_Error (HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE) if |
* $content_type doesn't seem to be valid. |
* |
* @access public |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param string $content_type content type of file for download |
*/ |
function setContentType($content_type = 'application/x-octetstream') |
{ |
if (!preg_match('/^[a-z]+\w*\/[a-z]+[\w.;= -]*$/', $content_type)) { |
return PEAR::raiseError( |
"Invalid content type '$content_type' supplied.", |
HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE |
); |
} |
$this->headers['Content-Type'] = $content_type; |
return true; |
} |
/** |
* Guess content type of file |
* |
* First we try to use PEAR::MIME_Type, if installed, to detect the content |
* type, else we check if ext/mime_magic is loaded and properly configured. |
* |
* Returns PEAR_Error if: |
* o if PEAR::MIME_Type failed to detect a proper content type |
* (HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE) |
* o ext/magic.mime is not installed, or not properly configured |
* (HTTP_DOWNLOAD_E_NO_EXT_MMAGIC) |
* o mime_content_type() couldn't guess content type or returned |
* a content type considered to be bogus by setContentType() |
* (HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE) |
* |
* @access public |
* @return mixed Returns true on success or PEAR_Error on failure. |
*/ |
function guessContentType() |
{ |
if (class_exists('MIME_Type') || @include_once 'MIME/Type.php') { |
if (PEAR::isError($mime_type = MIME_Type::autoDetect($this->file))) { |
return PEAR::raiseError($mime_type->getMessage(), |
HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE); |
} |
return $this->setContentType($mime_type); |
} |
if (!function_exists('mime_content_type')) { |
return PEAR::raiseError( |
'This feature requires ext/mime_magic!', |
HTTP_DOWNLOAD_E_NO_EXT_MMAGIC |
); |
} |
if (!is_file(ini_get('mime_magic.magicfile'))) { |
return PEAR::raiseError( |
'ext/mime_magic is loaded but not properly configured!', |
HTTP_DOWNLOAD_E_NO_EXT_MMAGIC |
); |
} |
if (!$content_type = @mime_content_type($this->file)) { |
return PEAR::raiseError( |
'Couldn\'t guess content type with mime_content_type().', |
HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE |
); |
} |
return $this->setContentType($content_type); |
} |
/** |
* Send |
* |
* Returns PEAR_Error if: |
* o HTTP headers were already sent (HTTP_DOWNLOAD_E_HEADERS_SENT) |
* o HTTP Range was invalid (HTTP_DOWNLOAD_E_INVALID_REQUEST) |
* |
* @access public |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param bool $autoSetContentDisposition Whether to set the |
* Content-Disposition header if it isn't already. |
*/ |
function send($autoSetContentDisposition = true) |
{ |
if (headers_sent()) { |
return PEAR::raiseError( |
'Headers already sent.', |
HTTP_DOWNLOAD_E_HEADERS_SENT |
); |
} |
if (!ini_get('safe_mode')) { |
@set_time_limit(0); |
} |
if ($autoSetContentDisposition && |
!isset($this->headers['Content-Disposition'])) { |
$this->setContentDisposition(); |
} |
if ($this->cache) { |
$this->headers['ETag'] = $this->generateETag(); |
if ($this->isCached()) { |
$this->HTTP->sendStatusCode(304); |
$this->sendHeaders(); |
return true; |
} |
} else { |
unset($this->headers['Last-Modified']); |
} |
if (ob_get_level()) { |
while (@ob_end_clean()); |
} |
if ($this->gzip) { |
@ob_start('ob_gzhandler'); |
} else { |
ob_start(); |
} |
$this->sentBytes = 0; |
if ($this->isRangeRequest()) { |
$this->HTTP->sendStatusCode(206); |
$chunks = $this->getChunks(); |
} else { |
$this->HTTP->sendStatusCode(200); |
$chunks = array(array(0, $this->size)); |
if (!$this->gzip && count(ob_list_handlers()) < 2) { |
$this->headers['Content-Length'] = $this->size; |
} |
} |
if (PEAR::isError($e = $this->sendChunks($chunks))) { |
ob_end_clean(); |
$this->HTTP->sendStatusCode(416); |
return $e; |
} |
ob_end_flush(); |
flush(); |
return true; |
} |
/** |
* Static send |
* |
* @see HTTP_Download::HTTP_Download() |
* @see HTTP_Download::send() |
* |
* @static |
* @access public |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param array $params associative array of parameters |
* @param bool $guess whether HTTP_Download::guessContentType() |
* should be called |
*/ |
function staticSend($params, $guess = false) |
{ |
$d = &new HTTP_Download(); |
$e = $d->setParams($params); |
if (PEAR::isError($e)) { |
return $e; |
} |
if ($guess) { |
$e = $d->guessContentType(); |
if (PEAR::isError($e)) { |
return $e; |
} |
} |
return $d->send(); |
} |
/** |
* Send a bunch of files or directories as an archive |
* |
* Example: |
* <code> |
* require_once 'HTTP/Download.php'; |
* HTTP_Download::sendArchive( |
* 'myArchive.tgz', |
* '/var/ftp/pub/mike', |
* HTTP_DOWNLOAD_TGZ, |
* '', |
* '/var/ftp/pub' |
* ); |
* </code> |
* |
* @see Archive_Tar::createModify() |
* @deprecated use HTTP_Download_Archive::send() |
* @static |
* @access public |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param string $name name the sent archive should have |
* @param mixed $files files/directories |
* @param string $type archive type |
* @param string $add_path path that should be prepended to the files |
* @param string $strip_path path that should be stripped from the files |
*/ |
function sendArchive( $name, |
$files, |
$type = HTTP_DOWNLOAD_TGZ, |
$add_path = '', |
$strip_path = '') |
{ |
require_once 'HTTP/Download/Archive.php'; |
return HTTP_Download_Archive::send($name, $files, $type, |
$add_path, $strip_path); |
} |
// }}} |
// {{{ protected methods |
/** |
* Generate ETag |
* |
* @access protected |
* @return string |
*/ |
function generateETag() |
{ |
if (!$this->etag) { |
if ($this->data) { |
$md5 = md5($this->data); |
} else { |
$fst = is_resource($this->handle) ? |
fstat($this->handle) : stat($this->file); |
$md5 = md5($fst['mtime'] .'='. $fst['ino'] .'='. $fst['size']); |
} |
$this->etag = '"' . $md5 . '-' . crc32($md5) . '"'; |
} |
return $this->etag; |
} |
/** |
* Send multiple chunks |
* |
* @access protected |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param array $chunks |
*/ |
function sendChunks($chunks) |
{ |
if (count($chunks) == 1) { |
return $this->sendChunk(current($chunks)); |
} |
$bound = uniqid('HTTP_DOWNLOAD-', true); |
$cType = $this->headers['Content-Type']; |
$this->headers['Content-Type'] = |
'multipart/byteranges; boundary=' . $bound; |
$this->sendHeaders(); |
foreach ($chunks as $chunk){ |
if (PEAR::isError($e = $this->sendChunk($chunk, $cType, $bound))) { |
return $e; |
} |
} |
#echo "\r\n--$bound--\r\n"; |
return true; |
} |
/** |
* Send chunk of data |
* |
* @access protected |
* @return mixed Returns true on success or PEAR_Error on failure. |
* @param array $chunk start and end offset of the chunk to send |
* @param string $cType actual content type |
* @param string $bound boundary for multipart/byteranges |
*/ |
function sendChunk($chunk, $cType = null, $bound = null) |
{ |
list($offset, $lastbyte) = $chunk; |
$length = ($lastbyte - $offset) + 1; |
if ($length < 1) { |
return PEAR::raiseError( |
"Error processing range request: $offset-$lastbyte/$length", |
HTTP_DOWNLOAD_E_INVALID_REQUEST |
); |
} |
$range = $offset . '-' . $lastbyte . '/' . $this->size; |
if (isset($cType, $bound)) { |
echo "\r\n--$bound\r\n", |
"Content-Type: $cType\r\n", |
"Content-Range: bytes $range\r\n\r\n"; |
} else { |
if ($this->isRangeRequest()) { |
$this->headers['Content-Length'] = $length; |
$this->headers['Content-Range'] = 'bytes '. $range; |
} |
$this->sendHeaders(); |
} |
if ($this->data) { |
while (($length -= $this->bufferSize) > 0) { |
$this->flush(substr($this->data, $offset, $this->bufferSize)); |
$this->throttleDelay and $this->sleep(); |
$offset += $this->bufferSize; |
} |
if ($length) { |
$this->flush(substr($this->data, $offset, $this->bufferSize + $length)); |
} |
} else { |
if (!is_resource($this->handle)) { |
$this->handle = fopen($this->file, 'rb'); |
} |
fseek($this->handle, $offset); |
while (($length -= $this->bufferSize) > 0) { |
$this->flush(fread($this->handle, $this->bufferSize)); |
$this->throttleDelay and $this->sleep(); |
} |
if ($length) { |
$this->flush(fread($this->handle, $this->bufferSize + $length)); |
} |
} |
return true; |
} |
/** |
* Get chunks to send |
* |
* @access protected |
* @return array |
*/ |
function getChunks() |
{ |
$parts = array(); |
foreach (explode(',', $this->getRanges()) as $chunk){ |
list($o, $e) = explode('-', $chunk); |
if ($e >= $this->size || (empty($e) && $e !== 0 && $e !== '0')) { |
$e = $this->size - 1; |
} |
if (empty($o) && $o !== 0 && $o !== '0') { |
$o = $this->size - $e; |
$e = $this->size - 1; |
} |
$parts[] = array($o, $e); |
} |
return $parts; |
} |
/** |
* Check if range is requested |
* |
* @access protected |
* @return bool |
*/ |
function isRangeRequest() |
{ |
if (!isset($_SERVER['HTTP_RANGE'])) { |
return false; |
} |
return $this->isValidRange(); |
} |
/** |
* Get range request |
* |
* @access protected |
* @return array |
*/ |
function getRanges() |
{ |
return preg_match('/^bytes=((\d*-\d*,? ?)+)$/', |
@$_SERVER['HTTP_RANGE'], $matches) ? $matches[1] : array(); |
} |
/** |
* Check if entity is cached |
* |
* @access protected |
* @return bool |
*/ |
function isCached() |
{ |
return ( |
(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && |
$this->lastModified == strtotime(current($a = explode( |
';', $_SERVER['HTTP_IF_MODIFIED_SINCE'])))) || |
(isset($_SERVER['HTTP_IF_NONE_MATCH']) && |
$this->compareAsterisk('HTTP_IF_NONE_MATCH', $this->etag)) |
); |
} |
/** |
* Check if entity hasn't changed |
* |
* @access protected |
* @return bool |
*/ |
function isValidRange() |
{ |
if (isset($_SERVER['HTTP_IF_MATCH']) && |
!$this->compareAsterisk('HTTP_IF_MATCH', $this->etag)) { |
return false; |
} |
if (isset($_SERVER['HTTP_IF_RANGE']) && |
$_SERVER['HTTP_IF_RANGE'] !== $this->etag && |
strtotime($_SERVER['HTTP_IF_RANGE']) !== $this->lastModified) { |
return false; |
} |
if (isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE'])) { |
$lm = current($a = explode(';', $_SERVER['HTTP_IF_UNMODIFIED_SINCE'])); |
if (strtotime($lm) !== $this->lastModified) { |
return false; |
} |
} |
if (isset($_SERVER['HTTP_UNLESS_MODIFIED_SINCE'])) { |
$lm = current($a = explode(';', $_SERVER['HTTP_UNLESS_MODIFIED_SINCE'])); |
if (strtotime($lm) !== $this->lastModified) { |
return false; |
} |
} |
return true; |
} |
/** |
* Compare against an asterisk or check for equality |
* |
* @access protected |
* @return bool |
* @param string key for the $_SERVER array |
* @param string string to compare |
*/ |
function compareAsterisk($svar, $compare) |
{ |
foreach (array_map('trim', explode(',', $_SERVER[$svar])) as $request) { |
if ($request === '*' || $request === $compare) { |
return true; |
} |
} |
return false; |
} |
/** |
* Send HTTP headers |
* |
* @access protected |
* @return void |
*/ |
function sendHeaders() |
{ |
foreach ($this->headers as $header => $value) { |
$this->HTTP->setHeader($header, $value); |
} |
$this->HTTP->sendHeaders(); |
/* NSAPI won't output anything if we did this */ |
if (strncasecmp(PHP_SAPI, 'nsapi', 5)) { |
ob_flush(); |
flush(); |
} |
} |
/** |
* Flush |
* |
* @access protected |
* @return void |
* @param string $data |
*/ |
function flush($data = '') |
{ |
if ($dlen = strlen($data)) { |
$this->sentBytes += $dlen; |
echo $data; |
} |
ob_flush(); |
flush(); |
} |
/** |
* Sleep |
* |
* @access protected |
* @return void |
*/ |
function sleep() |
{ |
if (OS_WINDOWS) { |
com_message_pump($this->throttleDelay); |
} else { |
usleep($this->throttleDelay * 1000); |
} |
} |
// }}} |
} |
?> |
/branches/v1.6-croc/jrest/lib/HTTP/HTTP/.directory |
---|
New file |
0,0 → 1,5 |
[Dolphin] |
Timestamp=2010,10,19,15,1,53 |
[Settings] |
ShowDotFiles=true |
/branches/v1.6-croc/jrest/lib/HTTP/HTTP/Header.php |
---|
New file |
0,0 → 1,531 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* HTTP::Header |
* |
* PHP versions 4 and 5 |
* |
* @category HTTP |
* @package HTTP_Header |
* @author Wolfram Kriesing <wk@visionp.de> |
* @author Davey Shafik <davey@php.net> |
* @author Michael Wallner <mike@php.net> |
* @copyright 2003-2005 The Authors |
* @license BSD, revised |
* @version CVS: $Id$ |
* @link http://pear.php.net/package/HTTP_Header |
*/ |
/** |
* Requires HTTP |
*/ |
require_once 'HTTP.php'; |
/**#@+ |
* Information Codes |
*/ |
define('HTTP_HEADER_STATUS_100', '100 Continue'); |
define('HTTP_HEADER_STATUS_101', '101 Switching Protocols'); |
define('HTTP_HEADER_STATUS_102', '102 Processing'); |
define('HTTP_HEADER_STATUS_INFORMATIONAL',1); |
/**#@-*/ |
/**#+ |
* Success Codes |
*/ |
define('HTTP_HEADER_STATUS_200', '200 OK'); |
define('HTTP_HEADER_STATUS_201', '201 Created'); |
define('HTTP_HEADER_STATUS_202', '202 Accepted'); |
define('HTTP_HEADER_STATUS_203', '203 Non-Authoritative Information'); |
define('HTTP_HEADER_STATUS_204', '204 No Content'); |
define('HTTP_HEADER_STATUS_205', '205 Reset Content'); |
define('HTTP_HEADER_STATUS_206', '206 Partial Content'); |
define('HTTP_HEADER_STATUS_207', '207 Multi-Status'); |
define('HTTP_HEADER_STATUS_SUCCESSFUL',2); |
/**#@-*/ |
/**#@+ |
* Redirection Codes |
*/ |
define('HTTP_HEADER_STATUS_300', '300 Multiple Choices'); |
define('HTTP_HEADER_STATUS_301', '301 Moved Permanently'); |
define('HTTP_HEADER_STATUS_302', '302 Found'); |
define('HTTP_HEADER_STATUS_303', '303 See Other'); |
define('HTTP_HEADER_STATUS_304', '304 Not Modified'); |
define('HTTP_HEADER_STATUS_305', '305 Use Proxy'); |
define('HTTP_HEADER_STATUS_306', '306 (Unused)'); |
define('HTTP_HEADER_STATUS_307', '307 Temporary Redirect'); |
define('HTTP_HEADER_STATUS_REDIRECT',3); |
/**#@-*/ |
/**#@+ |
* Error Codes |
*/ |
define('HTTP_HEADER_STATUS_400', '400 Bad Request'); |
define('HTTP_HEADER_STATUS_401', '401 Unauthorized'); |
define('HTTP_HEADER_STATUS_402', '402 Payment Granted'); |
define('HTTP_HEADER_STATUS_403', '403 Forbidden'); |
define('HTTP_HEADER_STATUS_404', '404 File Not Found'); |
define('HTTP_HEADER_STATUS_405', '405 Method Not Allowed'); |
define('HTTP_HEADER_STATUS_406', '406 Not Acceptable'); |
define('HTTP_HEADER_STATUS_407', '407 Proxy Authentication Required'); |
define('HTTP_HEADER_STATUS_408', '408 Request Time-out'); |
define('HTTP_HEADER_STATUS_409', '409 Conflict'); |
define('HTTP_HEADER_STATUS_410', '410 Gone'); |
define('HTTP_HEADER_STATUS_411', '411 Length Required'); |
define('HTTP_HEADER_STATUS_412', '412 Precondition Failed'); |
define('HTTP_HEADER_STATUS_413', '413 Request Entity Too Large'); |
define('HTTP_HEADER_STATUS_414', '414 Request-URI Too Large'); |
define('HTTP_HEADER_STATUS_415', '415 Unsupported Media Type'); |
define('HTTP_HEADER_STATUS_416', '416 Requested range not satisfiable'); |
define('HTTP_HEADER_STATUS_417', '417 Expectation Failed'); |
define('HTTP_HEADER_STATUS_422', '422 Unprocessable Entity'); |
define('HTTP_HEADER_STATUS_423', '423 Locked'); |
define('HTTP_HEADER_STATUS_424', '424 Failed Dependency'); |
define('HTTP_HEADER_STATUS_CLIENT_ERROR',4); |
/**#@-*/ |
/**#@+ |
* Server Errors |
*/ |
define('HTTP_HEADER_STATUS_500', '500 Internal Server Error'); |
define('HTTP_HEADER_STATUS_501', '501 Not Implemented'); |
define('HTTP_HEADER_STATUS_502', '502 Bad Gateway'); |
define('HTTP_HEADER_STATUS_503', '503 Service Unavailable'); |
define('HTTP_HEADER_STATUS_504', '504 Gateway Time-out'); |
define('HTTP_HEADER_STATUS_505', '505 HTTP Version not supported'); |
define('HTTP_HEADER_STATUS_507', '507 Insufficient Storage'); |
define('HTTP_HEADER_STATUS_SERVER_ERROR',5); |
/**#@-*/ |
/** |
* HTTP_Header |
* |
* @package HTTP_Header |
* @category HTTP |
* @access public |
* @version $Revision$ |
*/ |
class HTTP_Header extends HTTP |
{ |
/** |
* Default Headers |
* |
* The values that are set as default, are the same as PHP sends by default. |
* |
* @var array |
* @access private |
*/ |
var $_headers = array( |
'content-type' => 'text/html', |
'pragma' => 'no-cache', |
'cache-control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0' |
); |
/** |
* HTTP version |
* |
* @var string |
* @access private |
*/ |
var $_httpVersion = '1.0'; |
/** |
* Constructor |
* |
* Sets HTTP version. |
* |
* @access public |
* @return object HTTP_Header |
*/ |
function HTTP_Header() |
{ |
if (isset($_SERVER['SERVER_PROTOCOL'])) { |
$this->setHttpVersion(substr($_SERVER['SERVER_PROTOCOL'], -3)); |
} |
} |
/** |
* Set HTTP version |
* |
* @access public |
* @return bool Returns true on success or false if version doesn't |
* match 1.0 or 1.1 (note: 1 will result in 1.0) |
* @param mixed $version HTTP version, either 1.0 or 1.1 |
*/ |
function setHttpVersion($version) |
{ |
$version = round((float) $version, 1); |
if ($version < 1.0 || $version > 1.1) { |
return false; |
} |
$this->_httpVersion = sprintf('%0.1f', $version); |
return true; |
} |
/** |
* Get HTTP version |
* |
* @access public |
* @return string |
*/ |
function getHttpVersion() |
{ |
return $this->_httpVersion; |
} |
/** |
* Set Header |
* |
* The default value for the Last-Modified header will be current |
* date and atime if $value is omitted. |
* |
* @access public |
* @return bool Returns true on success or false if $key was empty or |
* $value was not of an scalar type. |
* @param string $key The name of the header. |
* @param string $value The value of the header. (NULL to unset header) |
*/ |
function setHeader($key, $value = null) |
{ |
if (empty($key) || (isset($value) && !is_scalar($value))) { |
return false; |
} |
$key = strToLower($key); |
if ($key == 'last-modified') { |
if (!isset($value)) { |
$value = HTTP::Date(time()); |
} elseif (is_numeric($value)) { |
$value = HTTP::Date($value); |
} |
} |
if (isset($value)) { |
$this->_headers[$key] = $value; |
} else { |
unset($this->_headers[$key]); |
} |
return true; |
} |
/** |
* Get Header |
* |
* If $key is omitted, all stored headers will be returned. |
* |
* @access public |
* @return mixed Returns string value of the requested header, |
* array values of all headers or false if header $key |
* is not set. |
* @param string $key The name of the header to fetch. |
*/ |
function getHeader($key = null) |
{ |
if (!isset($key)) { |
return $this->_headers; |
} |
$key = strToLower($key); |
if (!isset($this->_headers[$key])) { |
return false; |
} |
return $this->_headers[$key]; |
} |
/** |
* Send Headers |
* |
* Send out the header that you set via setHeader(). |
* |
* @access public |
* @return bool Returns true on success or false if headers are already |
* sent. |
* @param array $keys Headers to (not) send, see $include. |
* @param array $include If true only $keys matching headers will be |
* sent, if false only header not matching $keys will be |
* sent. |
*/ |
function sendHeaders($keys = array(), $include = true) |
{ |
if (headers_sent()) { |
return false; |
} |
if (count($keys)) { |
array_change_key_case($keys, CASE_LOWER); |
foreach ($this->_headers as $key => $value) { |
if ($include ? in_array($key, $keys) : !in_array($key, $keys)) { |
header($key .': '. $value); |
} |
} |
} else { |
foreach ($this->_headers as $header => $value) { |
header($header .': '. $value); |
} |
} |
return true; |
} |
/** |
* Send Satus Code |
* |
* Send out the given HTTP-Status code. Use this for example when you |
* want to tell the client this page is cached, then you would call |
* sendStatusCode(304). |
* |
* @see HTTP_Header_Cache::exitIfCached() |
* |
* @access public |
* @return bool Returns true on success or false if headers are already |
* sent. |
* @param int $code The status code to send, i.e. 404, 304, 200, etc. |
*/ |
function sendStatusCode($code) |
{ |
if (headers_sent()) { |
return false; |
} |
if ($code == (int) $code && defined('HTTP_HEADER_STATUS_'. $code)) { |
$code = constant('HTTP_HEADER_STATUS_'. $code); |
} |
if (strncasecmp(PHP_SAPI, 'cgi', 3)) { |
header('HTTP/'. $this->_httpVersion .' '. $code); |
} else { |
header('Status: '. $code); |
} |
return true; |
} |
/** |
* Date to Timestamp |
* |
* Converts dates like |
* Mon, 31 Mar 2003 15:26:34 GMT |
* Tue, 15 Nov 1994 12:45:26 GMT |
* into a timestamp, strtotime() didn't do it in older versions. |
* |
* @deprecated Use PHPs strtotime() instead. |
* @access public |
* @return mixed Returns int unix timestamp or false if the date doesn't |
* seem to be a valid GMT date. |
* @param string $date The GMT date. |
*/ |
function dateToTimestamp($date) |
{ |
static $months = array( |
null => 0, 'Jan' => 1, 'Feb' => 2, 'Mar' => 3, 'Apr' => 4, |
'May' => 5, 'Jun' => 6, 'Jul' => 7, 'Aug' => 8, 'Sep' => 9, |
'Oct' => 10, 'Nov' => 11, 'Dec' => 12 |
); |
if (-1 < $timestamp = strToTime($date)) { |
return $timestamp; |
} |
if (!preg_match('~[^,]*,\s(\d+)\s(\w+)\s(\d+)\s(\d+):(\d+):(\d+).*~', |
$date, $m)) { |
return false; |
} |
// [0] => Mon, 31 Mar 2003 15:42:55 GMT |
// [1] => 31 [2] => Mar [3] => 2003 [4] => 15 [5] => 42 [6] => 55 |
return mktime($m[4], $m[5], $m[6], $months[$m[2]], $m[1], $m[3]); |
} |
/** |
* Redirect |
* |
* This function redirects the client. This is done by issuing a Location |
* header and exiting. Additionally to HTTP::redirect() you can also add |
* parameters to the url. |
* |
* If you dont need parameters to be added, simply use HTTP::redirect() |
* otherwise use HTTP_Header::redirect(). |
* |
* @see HTTP::redirect() |
* @author Wolfram Kriesing <wk@visionp.de> |
* @access public |
* @return void |
* @param string $url The URL to redirect to, if none is given it |
* redirects to the current page. |
* @param array $param Array of query string parameters to add; usually |
* a set of key => value pairs; if an array entry consists |
* only of an value it is used as key and the respective |
* value is fetched from $GLOBALS[$value] |
* @param bool $session Whether the session name/id should be added |
*/ |
function redirect($url = null, $param = array(), $session = false) |
{ |
if (!isset($url)) { |
$url = $_SERVER['PHP_SELF']; |
} |
$qs = array(); |
if ($session) { |
$qs[] = session_name() .'='. session_id(); |
} |
if (is_array($param) && count($param)) { |
if (count($param)) { |
foreach ($param as $key => $val) { |
if (is_string($key)) { |
$qs[] = urlencode($key) .'='. urlencode($val); |
} else { |
$qs[] = urlencode($val) .'='. urlencode(@$GLOBALS[$val]); |
} |
} |
} |
} |
if ($qstr = implode('&', $qs)) { |
$purl = parse_url($url); |
$url .= (isset($purl['query']) ? '&' : '?') . $qstr; |
} |
parent::redirect($url); |
} |
/**#@+ |
* @author Davey Shafik <davey@php.net> |
* @param int $http_code HTTP Code to check |
* @access public |
*/ |
/** |
* Return HTTP Status Code Type |
* |
* @return int|false |
*/ |
function getStatusType($http_code) |
{ |
if(is_int($http_code) && defined('HTTP_HEADER_STATUS_' .$http_code) || defined($http_code)) { |
$type = substr($http_code,0,1); |
switch ($type) { |
case HTTP_HEADER_STATUS_INFORMATIONAL: |
case HTTP_HEADER_STATUS_SUCCESSFUL: |
case HTTP_HEADER_STATUS_REDIRECT: |
case HTTP_HEADER_STATUS_CLIENT_ERROR: |
case HTTP_HEADER_STATUS_SERVER_ERROR: |
return $type; |
break; |
default: |
return false; |
break; |
} |
} else { |
return false; |
} |
} |
/** |
* Return Status Code Message |
* |
* @return string|false |
*/ |
function getStatusText($http_code) |
{ |
if ($this->getStatusType($http_code)) { |
if (is_int($http_code) && defined('HTTP_HEADER_STATUS_' .$http_code)) { |
return substr(constant('HTTP_HEADER_STATUS_' .$http_code),4); |
} else { |
return substr($http_code,4); |
} |
} else { |
return false; |
} |
} |
/** |
* Checks if HTTP Status code is Information (1xx) |
* |
* @return boolean |
*/ |
function isInformational($http_code) |
{ |
if ($status_type = $this->getStatusType($http_code)) { |
return $status_type{0} == HTTP_HEADER_STATUS_INFORMATIONAL; |
} else { |
return false; |
} |
} |
/** |
* Checks if HTTP Status code is Successful (2xx) |
* |
* @return boolean |
*/ |
function isSuccessful($http_code) |
{ |
if ($status_type = $this->getStatusType($http_code)) { |
return $status_type{0} == HTTP_HEADER_STATUS_SUCCESSFUL; |
} else { |
return false; |
} |
} |
/** |
* Checks if HTTP Status code is a Redirect (3xx) |
* |
* @return boolean |
*/ |
function isRedirect($http_code) |
{ |
if ($status_type = $this->getStatusType($http_code)) { |
return $status_type{0} == HTTP_HEADER_STATUS_REDIRECT; |
} else { |
return false; |
} |
} |
/** |
* Checks if HTTP Status code is a Client Error (4xx) |
* |
* @return boolean |
*/ |
function isClientError($http_code) |
{ |
if ($status_type = $this->getStatusType($http_code)) { |
return $status_type{0} == HTTP_HEADER_STATUS_CLIENT_ERROR; |
} else { |
return false; |
} |
} |
/** |
* Checks if HTTP Status code is Server Error (5xx) |
* |
* @return boolean |
*/ |
function isServerError($http_code) |
{ |
if ($status_type = $this->getStatusType($http_code)) { |
return $status_type{0} == HTTP_HEADER_STATUS_SERVER_ERROR; |
} else { |
return false; |
} |
} |
/** |
* Checks if HTTP Status code is Server OR Client Error (4xx or 5xx) |
* |
* @return boolean |
*/ |
function isError($http_code) |
{ |
if ($status_type = $this->getStatusType($http_code)) { |
return (($status_type == HTTP_HEADER_STATUS_CLIENT_ERROR) || ($status_type == HTTP_HEADER_STATUS_SERVER_ERROR)) ? true : false; |
} else { |
return false; |
} |
} |
/**#@-*/ |
} |
?> |
/branches/v1.6-croc/jrest/lib/HTTP/.directory |
---|
New file |
0,0 → 1,5 |
[Dolphin] |
Timestamp=2010,10,19,15,1,48 |
[Settings] |
ShowDotFiles=true |
/branches/v1.6-croc/jrest/lib/Bdd.php |
---|
New file |
0,0 → 1,136 |
<?php |
/** |
* La classe de gestion de la base de données. |
* |
* @category php 5.2 |
* @package cel |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org) |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version $Id$ |
*/ |
class Bdd { |
const SQL_MODE_ASSOC = PDO::FETCH_ASSOC; |
const SQL_MODE_OBJET = PDO::FETCH_OBJ; |
const SQL_RETOUR_COMPLET = 'All'; |
const SQL_RETOUR_LIGNE = 'Row'; |
const SQL_RETOUR_COLONNE = 'Column'; |
const SQL_RETOUR_BRUT = 'Raw'; |
private $bdd = null; |
public function __construct($cfg) { |
// ATTENTION : la connexin à la bdd peut échouer si l'host vaut localhost. Utiliser 127.0.0.1 à la place. |
$dsn = $cfg['phptype'].':dbname='.$cfg['database'].';host='.$cfg['hostspec']; |
try { |
// Création de la connexion en UTF-8 à la BDD |
$this->bdd = new PDO($dsn, $cfg['username'], $cfg['password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'")); |
// Affiche les erreurs détectées par PDO (sinon mode silencieux => aucune erreur affiché) |
$this->bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
} catch (PDOException $e) { |
$message = "La connexion à la base de donnée via PDO a échouée : $dsn {$e->getMessage()}"; |
$code = E_USER_ERROR; |
throw new Exception($message, $code); |
} |
} |
/** |
* Protège automatiquement toutes les chaines comprises entre deux caractères '|'. |
* Puis execute la requete. |
* @see protegerRequete() |
* @param unknown_type $requete |
*/ |
public function requeter($requete, $retour = self::SQL_RETOUR_COMPLET, $mode = PDO::FETCH_ASSOC) { |
$resultat = false; |
try { |
switch ($retour) { |
case self::SQL_RETOUR_COMPLET : |
$resultat = $this->bdd->query($requete)->fetchAll($mode);// Retourne toutes les lignes |
break; |
case self::SQL_RETOUR_LIGNE : |
$resultat = $this->bdd->query($requete)->fetch($mode);// Retourne la première ligne |
break; |
case self::SQL_RETOUR_COLONNE : |
$resultat = $this->bdd->query($requete)->fetchColumn();// Retourne la première colonne de la première ligne |
break; |
case self::SQL_RETOUR_BRUT : |
$resultat = $this->bdd->query($requete);// Retourne l'objet brut pour être utilisé dans une boucle de type foreach |
break; |
default: |
$message = "Le type de retour '$retour' est inconnu."; |
$code = E_USER_ERROR; |
throw new Exception($message, $code); |
} |
if ($resultat === false) { |
$message = "La requête a retourné aucun résultat : $requete"; |
$code = E_USER_NOTICE; |
throw new Exception($message, $code); |
} |
} catch (PDOException $e) { |
$message = sprintf($this->getTxt('sql_erreur_requete'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete); |
$code = E_USER_ERROR; |
throw new Exception($message, $code); |
} |
return $resultat; |
} |
/** |
* Protège automatiquement toutes les chaines comprises entre deux caractères '|'. |
* @see protegerRequete() |
* @param unknown_type $requete |
*/ |
public function executer($requete) { |
$resultat = false; |
try { |
$resultat = $this->bdd->exec($requete); |
if ($resultat === false) { |
$this->debug[] = "La requête a échoué : $requete"; |
} |
} catch (PDOException $e) { |
$message = sprintf($this->getTxt('sql_erreur_requete'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete); |
$code = E_USER_ERROR; |
throw new Exception($message); |
} |
return $resultat; |
} |
public function proteger($element) { |
$element = is_array($element) ? $this->protegerTableau($element) : $this->protegerChaine($element); |
return $element; |
} |
private function protegerChaine($chaine) { |
return $this->bdd->quote($chaine); |
} |
private function protegerTableau(Array $tableau) { |
foreach ($tableau as $id => $val) { |
if (is_array($val)) { |
$tableau[$id] = $this->protegerTableau($val); |
} else { |
$tableau[$id] = $this->protegerChaine($val); |
} |
} |
return $tableau; |
} |
public function etreNull($valeur) { |
$etreNull = false; |
if ($valeur == '' || $valeur == null || $valeur == '000null' || $valeur == 'null' || $valeur == '*') { |
$etreNull = true; |
} |
return $etreNull; |
} |
public function getTxt($id) { |
$sortie = ''; |
switch ($id) { |
case 'sql_erreur_requete' : $sortie = "Requête echec.\nFichier : %s.\nLigne : %s.\nMessage : %s.\nRequête : %s"; break; |
default : $sortie = $id; |
} |
return $sortie; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/File/.directory |
---|
New file |
0,0 → 1,5 |
[Dolphin] |
Timestamp=2010,10,19,15,1,23 |
[Settings] |
ShowDotFiles=true |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/symbol.php |
---|
New file |
0,0 → 1,272 |
<?php |
/** |
* @package File_PDF |
*/ |
$font_widths['symbol'] = array( |
chr(0) => 250, |
chr(1) => 250, |
chr(2) => 250, |
chr(3) => 250, |
chr(4) => 250, |
chr(5) => 250, |
chr(6) => 250, |
chr(7) => 250, |
chr(8) => 250, |
chr(9) => 250, |
chr(10) => 250, |
chr(11) => 250, |
chr(12) => 250, |
chr(13) => 250, |
chr(14) => 250, |
chr(15) => 250, |
chr(16) => 250, |
chr(17) => 250, |
chr(18) => 250, |
chr(19) => 250, |
chr(20) => 250, |
chr(21) => 250, |
chr(22) => 250, |
chr(23) => 250, |
chr(24) => 250, |
chr(25) => 250, |
chr(26) => 250, |
chr(27) => 250, |
chr(28) => 250, |
chr(29) => 250, |
chr(30) => 250, |
chr(31) => 250, |
' ' => 250, |
'!' => 333, |
'"' => 713, |
'#' => 500, |
'$' => 549, |
'%' => 833, |
'&' => 778, |
'\'' => 439, |
'(' => 333, |
')' => 333, |
'*' => 500, |
'+' => 549, |
',' => 250, |
'-' => 549, |
'.' => 250, |
'/' => 278, |
'0' => 500, |
'1' => 500, |
'2' => 500, |
'3' => 500, |
'4' => 500, |
'5' => 500, |
'6' => 500, |
'7' => 500, |
'8' => 500, |
'9' => 500, |
':' => 278, |
';' => 278, |
'<' => 549, |
'=' => 549, |
'>' => 549, |
'?' => 444, |
'@' => 549, |
'A' => 722, |
'B' => 667, |
'C' => 722, |
'D' => 612, |
'E' => 611, |
'F' => 763, |
'G' => 603, |
'H' => 722, |
'I' => 333, |
'J' => 631, |
'K' => 722, |
'L' => 686, |
'M' => 889, |
'N' => 722, |
'O' => 722, |
'P' => 768, |
'Q' => 741, |
'R' => 556, |
'S' => 592, |
'T' => 611, |
'U' => 690, |
'V' => 439, |
'W' => 768, |
'X' => 645, |
'Y' => 795, |
'Z' => 611, |
'[' => 333, |
'\\' => 863, |
']' => 333, |
'^' => 658, |
'_' => 500, |
'`' => 500, |
'a' => 631, |
'b' => 549, |
'c' => 549, |
'd' => 494, |
'e' => 439, |
'f' => 521, |
'g' => 411, |
'h' => 603, |
'i' => 329, |
'j' => 603, |
'k' => 549, |
'l' => 549, |
'm' => 576, |
'n' => 521, |
'o' => 549, |
'p' => 549, |
'q' => 521, |
'r' => 549, |
's' => 603, |
't' => 439, |
'u' => 576, |
'v' => 713, |
'w' => 686, |
'x' => 493, |
'y' => 686, |
'z' => 494, |
'{' => 480, |
'|' => 200, |
'}' => 480, |
'~' => 549, |
chr(127) => 0, |
chr(128) => 0, |
chr(129) => 0, |
chr(130) => 0, |
chr(131) => 0, |
chr(132) => 0, |
chr(133) => 0, |
chr(134) => 0, |
chr(135) => 0, |
chr(136) => 0, |
chr(137) => 0, |
chr(138) => 0, |
chr(139) => 0, |
chr(140) => 0, |
chr(141) => 0, |
chr(142) => 0, |
chr(143) => 0, |
chr(144) => 0, |
chr(145) => 0, |
chr(146) => 0, |
chr(147) => 0, |
chr(148) => 0, |
chr(149) => 0, |
chr(150) => 0, |
chr(151) => 0, |
chr(152) => 0, |
chr(153) => 0, |
chr(154) => 0, |
chr(155) => 0, |
chr(156) => 0, |
chr(157) => 0, |
chr(158) => 0, |
chr(159) => 0, |
chr(160) => 750, |
chr(161) => 620, |
chr(162) => 247, |
chr(163) => 549, |
chr(164) => 167, |
chr(165) => 713, |
chr(166) => 500, |
chr(167) => 753, |
chr(168) => 753, |
chr(169) => 753, |
chr(170) => 753, |
chr(171) => 1042, |
chr(172) => 987, |
chr(173) => 603, |
chr(174) => 987, |
chr(175) => 603, |
chr(176) => 400, |
chr(177) => 549, |
chr(178) => 411, |
chr(179) => 549, |
chr(180) => 549, |
chr(181) => 713, |
chr(182) => 494, |
chr(183) => 460, |
chr(184) => 549, |
chr(185) => 549, |
chr(186) => 549, |
chr(187) => 549, |
chr(188) => 1000, |
chr(189) => 603, |
chr(190) => 1000, |
chr(191) => 658, |
chr(192) => 823, |
chr(193) => 686, |
chr(194) => 795, |
chr(195) => 987, |
chr(196) => 768, |
chr(197) => 768, |
chr(198) => 823, |
chr(199) => 768, |
chr(200) => 768, |
chr(201) => 713, |
chr(202) => 713, |
chr(203) => 713, |
chr(204) => 713, |
chr(205) => 713, |
chr(206) => 713, |
chr(207) => 713, |
chr(208) => 768, |
chr(209) => 713, |
chr(210) => 790, |
chr(211) => 790, |
chr(212) => 890, |
chr(213) => 823, |
chr(214) => 549, |
chr(215) => 250, |
chr(216) => 713, |
chr(217) => 603, |
chr(218) => 603, |
chr(219) => 1042, |
chr(220) => 987, |
chr(221) => 603, |
chr(222) => 987, |
chr(223) => 603, |
chr(224) => 494, |
chr(225) => 329, |
chr(226) => 790, |
chr(227) => 790, |
chr(228) => 786, |
chr(229) => 713, |
chr(230) => 384, |
chr(231) => 384, |
chr(232) => 384, |
chr(233) => 384, |
chr(234) => 384, |
chr(235) => 384, |
chr(236) => 494, |
chr(237) => 494, |
chr(238) => 494, |
chr(239) => 494, |
chr(240) => 0, |
chr(241) => 329, |
chr(242) => 274, |
chr(243) => 686, |
chr(244) => 686, |
chr(245) => 686, |
chr(246) => 384, |
chr(247) => 384, |
chr(248) => 384, |
chr(249) => 384, |
chr(250) => 384, |
chr(251) => 384, |
chr(252) => 494, |
chr(253) => 494, |
chr(254) => 494, |
chr(255) => 0); |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/helveticab.php |
---|
New file |
0,0 → 1,272 |
<?php |
/** |
* @package File_PDF |
*/ |
$font_widths['helveticaB'] = array( |
chr(0) => 278, |
chr(1) => 278, |
chr(2) => 278, |
chr(3) => 278, |
chr(4) => 278, |
chr(5) => 278, |
chr(6) => 278, |
chr(7) => 278, |
chr(8) => 278, |
chr(9) => 278, |
chr(10) => 278, |
chr(11) => 278, |
chr(12) => 278, |
chr(13) => 278, |
chr(14) => 278, |
chr(15) => 278, |
chr(16) => 278, |
chr(17) => 278, |
chr(18) => 278, |
chr(19) => 278, |
chr(20) => 278, |
chr(21) => 278, |
chr(22) => 278, |
chr(23) => 278, |
chr(24) => 278, |
chr(25) => 278, |
chr(26) => 278, |
chr(27) => 278, |
chr(28) => 278, |
chr(29) => 278, |
chr(30) => 278, |
chr(31) => 278, |
' ' => 278, |
'!' => 333, |
'"' => 474, |
'#' => 556, |
'$' => 556, |
'%' => 889, |
'&' => 722, |
'\'' => 238, |
'(' => 333, |
')' => 333, |
'*' => 389, |
'+' => 584, |
',' => 278, |
'-' => 333, |
'.' => 278, |
'/' => 278, |
'0' => 556, |
'1' => 556, |
'2' => 556, |
'3' => 556, |
'4' => 556, |
'5' => 556, |
'6' => 556, |
'7' => 556, |
'8' => 556, |
'9' => 556, |
':' => 333, |
';' => 333, |
'<' => 584, |
'=' => 584, |
'>' => 584, |
'?' => 611, |
'@' => 975, |
'A' => 722, |
'B' => 722, |
'C' => 722, |
'D' => 722, |
'E' => 667, |
'F' => 611, |
'G' => 778, |
'H' => 722, |
'I' => 278, |
'J' => 556, |
'K' => 722, |
'L' => 611, |
'M' => 833, |
'N' => 722, |
'O' => 778, |
'P' => 667, |
'Q' => 778, |
'R' => 722, |
'S' => 667, |
'T' => 611, |
'U' => 722, |
'V' => 667, |
'W' => 944, |
'X' => 667, |
'Y' => 667, |
'Z' => 611, |
'[' => 333, |
'\\' => 278, |
']' => 333, |
'^' => 584, |
'_' => 556, |
'`' => 333, |
'a' => 556, |
'b' => 611, |
'c' => 556, |
'd' => 611, |
'e' => 556, |
'f' => 333, |
'g' => 611, |
'h' => 611, |
'i' => 278, |
'j' => 278, |
'k' => 556, |
'l' => 278, |
'm' => 889, |
'n' => 611, |
'o' => 611, |
'p' => 611, |
'q' => 611, |
'r' => 389, |
's' => 556, |
't' => 333, |
'u' => 611, |
'v' => 556, |
'w' => 778, |
'x' => 556, |
'y' => 556, |
'z' => 500, |
'{' => 389, |
'|' => 280, |
'}' => 389, |
'~' => 584, |
chr(127) => 350, |
chr(128) => 556, |
chr(129) => 350, |
chr(130) => 278, |
chr(131) => 556, |
chr(132) => 500, |
chr(133) => 1000, |
chr(134) => 556, |
chr(135) => 556, |
chr(136) => 333, |
chr(137) => 1000, |
chr(138) => 667, |
chr(139) => 333, |
chr(140) => 1000, |
chr(141) => 350, |
chr(142) => 611, |
chr(143) => 350, |
chr(144) => 350, |
chr(145) => 278, |
chr(146) => 278, |
chr(147) => 500, |
chr(148) => 500, |
chr(149) => 350, |
chr(150) => 556, |
chr(151) => 1000, |
chr(152) => 333, |
chr(153) => 1000, |
chr(154) => 556, |
chr(155) => 333, |
chr(156) => 944, |
chr(157) => 350, |
chr(158) => 500, |
chr(159) => 667, |
chr(160) => 278, |
chr(161) => 333, |
chr(162) => 556, |
chr(163) => 556, |
chr(164) => 556, |
chr(165) => 556, |
chr(166) => 280, |
chr(167) => 556, |
chr(168) => 333, |
chr(169) => 737, |
chr(170) => 370, |
chr(171) => 556, |
chr(172) => 584, |
chr(173) => 333, |
chr(174) => 737, |
chr(175) => 333, |
chr(176) => 400, |
chr(177) => 584, |
chr(178) => 333, |
chr(179) => 333, |
chr(180) => 333, |
chr(181) => 611, |
chr(182) => 556, |
chr(183) => 278, |
chr(184) => 333, |
chr(185) => 333, |
chr(186) => 365, |
chr(187) => 556, |
chr(188) => 834, |
chr(189) => 834, |
chr(190) => 834, |
chr(191) => 611, |
chr(192) => 722, |
chr(193) => 722, |
chr(194) => 722, |
chr(195) => 722, |
chr(196) => 722, |
chr(197) => 722, |
chr(198) => 1000, |
chr(199) => 722, |
chr(200) => 667, |
chr(201) => 667, |
chr(202) => 667, |
chr(203) => 667, |
chr(204) => 278, |
chr(205) => 278, |
chr(206) => 278, |
chr(207) => 278, |
chr(208) => 722, |
chr(209) => 722, |
chr(210) => 778, |
chr(211) => 778, |
chr(212) => 778, |
chr(213) => 778, |
chr(214) => 778, |
chr(215) => 584, |
chr(216) => 778, |
chr(217) => 722, |
chr(218) => 722, |
chr(219) => 722, |
chr(220) => 722, |
chr(221) => 667, |
chr(222) => 667, |
chr(223) => 611, |
chr(224) => 556, |
chr(225) => 556, |
chr(226) => 556, |
chr(227) => 556, |
chr(228) => 556, |
chr(229) => 556, |
chr(230) => 889, |
chr(231) => 556, |
chr(232) => 556, |
chr(233) => 556, |
chr(234) => 556, |
chr(235) => 556, |
chr(236) => 278, |
chr(237) => 278, |
chr(238) => 278, |
chr(239) => 278, |
chr(240) => 611, |
chr(241) => 611, |
chr(242) => 611, |
chr(243) => 611, |
chr(244) => 611, |
chr(245) => 611, |
chr(246) => 611, |
chr(247) => 584, |
chr(248) => 611, |
chr(249) => 611, |
chr(250) => 611, |
chr(251) => 611, |
chr(252) => 611, |
chr(253) => 556, |
chr(254) => 611, |
chr(255) => 556); |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/courier.php |
---|
New file |
0,0 → 1,10 |
<?php |
/** |
* @package File_PDF |
*/ |
for ($i = 0; $i <= 255; $i++) { |
$font_widths['courier'][chr($i)] = 600; |
} |
$font_widths['courierB'] = $font_widths['courier']; |
$font_widths['courierI'] = $font_widths['courier']; |
$font_widths['courierBI'] = $font_widths['courier']; |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/timesi.php |
---|
New file |
0,0 → 1,272 |
<?php |
/** |
* @package File_PDF |
*/ |
$font_widths['timesI'] = array( |
chr(0) => 250, |
chr(1) => 250, |
chr(2) => 250, |
chr(3) => 250, |
chr(4) => 250, |
chr(5) => 250, |
chr(6) => 250, |
chr(7) => 250, |
chr(8) => 250, |
chr(9) => 250, |
chr(10) => 250, |
chr(11) => 250, |
chr(12) => 250, |
chr(13) => 250, |
chr(14) => 250, |
chr(15) => 250, |
chr(16) => 250, |
chr(17) => 250, |
chr(18) => 250, |
chr(19) => 250, |
chr(20) => 250, |
chr(21) => 250, |
chr(22) => 250, |
chr(23) => 250, |
chr(24) => 250, |
chr(25) => 250, |
chr(26) => 250, |
chr(27) => 250, |
chr(28) => 250, |
chr(29) => 250, |
chr(30) => 250, |
chr(31) => 250, |
' ' => 250, |
'!' => 333, |
'"' => 420, |
'#' => 500, |
'$' => 500, |
'%' => 833, |
'&' => 778, |
'\'' => 214, |
'(' => 333, |
')' => 333, |
'*' => 500, |
'+' => 675, |
',' => 250, |
'-' => 333, |
'.' => 250, |
'/' => 278, |
'0' => 500, |
'1' => 500, |
'2' => 500, |
'3' => 500, |
'4' => 500, |
'5' => 500, |
'6' => 500, |
'7' => 500, |
'8' => 500, |
'9' => 500, |
':' => 333, |
';' => 333, |
'<' => 675, |
'=' => 675, |
'>' => 675, |
'?' => 500, |
'@' => 920, |
'A' => 611, |
'B' => 611, |
'C' => 667, |
'D' => 722, |
'E' => 611, |
'F' => 611, |
'G' => 722, |
'H' => 722, |
'I' => 333, |
'J' => 444, |
'K' => 667, |
'L' => 556, |
'M' => 833, |
'N' => 667, |
'O' => 722, |
'P' => 611, |
'Q' => 722, |
'R' => 611, |
'S' => 500, |
'T' => 556, |
'U' => 722, |
'V' => 611, |
'W' => 833, |
'X' => 611, |
'Y' => 556, |
'Z' => 556, |
'[' => 389, |
'\\' => 278, |
']' => 389, |
'^' => 422, |
'_' => 500, |
'`' => 333, |
'a' => 500, |
'b' => 500, |
'c' => 444, |
'd' => 500, |
'e' => 444, |
'f' => 278, |
'g' => 500, |
'h' => 500, |
'i' => 278, |
'j' => 278, |
'k' => 444, |
'l' => 278, |
'm' => 722, |
'n' => 500, |
'o' => 500, |
'p' => 500, |
'q' => 500, |
'r' => 389, |
's' => 389, |
't' => 278, |
'u' => 500, |
'v' => 444, |
'w' => 667, |
'x' => 444, |
'y' => 444, |
'z' => 389, |
'{' => 400, |
'|' => 275, |
'}' => 400, |
'~' => 541, |
chr(127) => 350, |
chr(128) => 500, |
chr(129) => 350, |
chr(130) => 333, |
chr(131) => 500, |
chr(132) => 556, |
chr(133) => 889, |
chr(134) => 500, |
chr(135) => 500, |
chr(136) => 333, |
chr(137) => 1000, |
chr(138) => 500, |
chr(139) => 333, |
chr(140) => 944, |
chr(141) => 350, |
chr(142) => 556, |
chr(143) => 350, |
chr(144) => 350, |
chr(145) => 333, |
chr(146) => 333, |
chr(147) => 556, |
chr(148) => 556, |
chr(149) => 350, |
chr(150) => 500, |
chr(151) => 889, |
chr(152) => 333, |
chr(153) => 980, |
chr(154) => 389, |
chr(155) => 333, |
chr(156) => 667, |
chr(157) => 350, |
chr(158) => 389, |
chr(159) => 556, |
chr(160) => 250, |
chr(161) => 389, |
chr(162) => 500, |
chr(163) => 500, |
chr(164) => 500, |
chr(165) => 500, |
chr(166) => 275, |
chr(167) => 500, |
chr(168) => 333, |
chr(169) => 760, |
chr(170) => 276, |
chr(171) => 500, |
chr(172) => 675, |
chr(173) => 333, |
chr(174) => 760, |
chr(175) => 333, |
chr(176) => 400, |
chr(177) => 675, |
chr(178) => 300, |
chr(179) => 300, |
chr(180) => 333, |
chr(181) => 500, |
chr(182) => 523, |
chr(183) => 250, |
chr(184) => 333, |
chr(185) => 300, |
chr(186) => 310, |
chr(187) => 500, |
chr(188) => 750, |
chr(189) => 750, |
chr(190) => 750, |
chr(191) => 500, |
chr(192) => 611, |
chr(193) => 611, |
chr(194) => 611, |
chr(195) => 611, |
chr(196) => 611, |
chr(197) => 611, |
chr(198) => 889, |
chr(199) => 667, |
chr(200) => 611, |
chr(201) => 611, |
chr(202) => 611, |
chr(203) => 611, |
chr(204) => 333, |
chr(205) => 333, |
chr(206) => 333, |
chr(207) => 333, |
chr(208) => 722, |
chr(209) => 667, |
chr(210) => 722, |
chr(211) => 722, |
chr(212) => 722, |
chr(213) => 722, |
chr(214) => 722, |
chr(215) => 675, |
chr(216) => 722, |
chr(217) => 722, |
chr(218) => 722, |
chr(219) => 722, |
chr(220) => 722, |
chr(221) => 556, |
chr(222) => 611, |
chr(223) => 500, |
chr(224) => 500, |
chr(225) => 500, |
chr(226) => 500, |
chr(227) => 500, |
chr(228) => 500, |
chr(229) => 500, |
chr(230) => 667, |
chr(231) => 444, |
chr(232) => 444, |
chr(233) => 444, |
chr(234) => 444, |
chr(235) => 444, |
chr(236) => 278, |
chr(237) => 278, |
chr(238) => 278, |
chr(239) => 278, |
chr(240) => 500, |
chr(241) => 500, |
chr(242) => 500, |
chr(243) => 500, |
chr(244) => 500, |
chr(245) => 500, |
chr(246) => 500, |
chr(247) => 675, |
chr(248) => 500, |
chr(249) => 500, |
chr(250) => 500, |
chr(251) => 500, |
chr(252) => 500, |
chr(253) => 444, |
chr(254) => 500, |
chr(255) => 444); |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/.directory |
---|
New file |
0,0 → 1,5 |
[Dolphin] |
Timestamp=2010,10,19,15,1,33 |
[Settings] |
ShowDotFiles=true |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/timesbi.php |
---|
New file |
0,0 → 1,272 |
<?php |
/** |
* @package File_PDF |
*/ |
$font_widths['timesBI'] = array( |
chr(0) => 250, |
chr(1) => 250, |
chr(2) => 250, |
chr(3) => 250, |
chr(4) => 250, |
chr(5) => 250, |
chr(6) => 250, |
chr(7) => 250, |
chr(8) => 250, |
chr(9) => 250, |
chr(10) => 250, |
chr(11) => 250, |
chr(12) => 250, |
chr(13) => 250, |
chr(14) => 250, |
chr(15) => 250, |
chr(16) => 250, |
chr(17) => 250, |
chr(18) => 250, |
chr(19) => 250, |
chr(20) => 250, |
chr(21) => 250, |
chr(22) => 250, |
chr(23) => 250, |
chr(24) => 250, |
chr(25) => 250, |
chr(26) => 250, |
chr(27) => 250, |
chr(28) => 250, |
chr(29) => 250, |
chr(30) => 250, |
chr(31) => 250, |
' ' => 250, |
'!' => 389, |
'"' => 555, |
'#' => 500, |
'$' => 500, |
'%' => 833, |
'&' => 778, |
'\'' => 278, |
'(' => 333, |
')' => 333, |
'*' => 500, |
'+' => 570, |
',' => 250, |
'-' => 333, |
'.' => 250, |
'/' => 278, |
'0' => 500, |
'1' => 500, |
'2' => 500, |
'3' => 500, |
'4' => 500, |
'5' => 500, |
'6' => 500, |
'7' => 500, |
'8' => 500, |
'9' => 500, |
':' => 333, |
';' => 333, |
'<' => 570, |
'=' => 570, |
'>' => 570, |
'?' => 500, |
'@' => 832, |
'A' => 667, |
'B' => 667, |
'C' => 667, |
'D' => 722, |
'E' => 667, |
'F' => 667, |
'G' => 722, |
'H' => 778, |
'I' => 389, |
'J' => 500, |
'K' => 667, |
'L' => 611, |
'M' => 889, |
'N' => 722, |
'O' => 722, |
'P' => 611, |
'Q' => 722, |
'R' => 667, |
'S' => 556, |
'T' => 611, |
'U' => 722, |
'V' => 667, |
'W' => 889, |
'X' => 667, |
'Y' => 611, |
'Z' => 611, |
'[' => 333, |
'\\' => 278, |
']' => 333, |
'^' => 570, |
'_' => 500, |
'`' => 333, |
'a' => 500, |
'b' => 500, |
'c' => 444, |
'd' => 500, |
'e' => 444, |
'f' => 333, |
'g' => 500, |
'h' => 556, |
'i' => 278, |
'j' => 278, |
'k' => 500, |
'l' => 278, |
'm' => 778, |
'n' => 556, |
'o' => 500, |
'p' => 500, |
'q' => 500, |
'r' => 389, |
's' => 389, |
't' => 278, |
'u' => 556, |
'v' => 444, |
'w' => 667, |
'x' => 500, |
'y' => 444, |
'z' => 389, |
'{' => 348, |
'|' => 220, |
'}' => 348, |
'~' => 570, |
chr(127) => 350, |
chr(128) => 500, |
chr(129) => 350, |
chr(130) => 333, |
chr(131) => 500, |
chr(132) => 500, |
chr(133) => 1000, |
chr(134) => 500, |
chr(135) => 500, |
chr(136) => 333, |
chr(137) => 1000, |
chr(138) => 556, |
chr(139) => 333, |
chr(140) => 944, |
chr(141) => 350, |
chr(142) => 611, |
chr(143) => 350, |
chr(144) => 350, |
chr(145) => 333, |
chr(146) => 333, |
chr(147) => 500, |
chr(148) => 500, |
chr(149) => 350, |
chr(150) => 500, |
chr(151) => 1000, |
chr(152) => 333, |
chr(153) => 1000, |
chr(154) => 389, |
chr(155) => 333, |
chr(156) => 722, |
chr(157) => 350, |
chr(158) => 389, |
chr(159) => 611, |
chr(160) => 250, |
chr(161) => 389, |
chr(162) => 500, |
chr(163) => 500, |
chr(164) => 500, |
chr(165) => 500, |
chr(166) => 220, |
chr(167) => 500, |
chr(168) => 333, |
chr(169) => 747, |
chr(170) => 266, |
chr(171) => 500, |
chr(172) => 606, |
chr(173) => 333, |
chr(174) => 747, |
chr(175) => 333, |
chr(176) => 400, |
chr(177) => 570, |
chr(178) => 300, |
chr(179) => 300, |
chr(180) => 333, |
chr(181) => 576, |
chr(182) => 500, |
chr(183) => 250, |
chr(184) => 333, |
chr(185) => 300, |
chr(186) => 300, |
chr(187) => 500, |
chr(188) => 750, |
chr(189) => 750, |
chr(190) => 750, |
chr(191) => 500, |
chr(192) => 667, |
chr(193) => 667, |
chr(194) => 667, |
chr(195) => 667, |
chr(196) => 667, |
chr(197) => 667, |
chr(198) => 944, |
chr(199) => 667, |
chr(200) => 667, |
chr(201) => 667, |
chr(202) => 667, |
chr(203) => 667, |
chr(204) => 389, |
chr(205) => 389, |
chr(206) => 389, |
chr(207) => 389, |
chr(208) => 722, |
chr(209) => 722, |
chr(210) => 722, |
chr(211) => 722, |
chr(212) => 722, |
chr(213) => 722, |
chr(214) => 722, |
chr(215) => 570, |
chr(216) => 722, |
chr(217) => 722, |
chr(218) => 722, |
chr(219) => 722, |
chr(220) => 722, |
chr(221) => 611, |
chr(222) => 611, |
chr(223) => 500, |
chr(224) => 500, |
chr(225) => 500, |
chr(226) => 500, |
chr(227) => 500, |
chr(228) => 500, |
chr(229) => 500, |
chr(230) => 722, |
chr(231) => 444, |
chr(232) => 444, |
chr(233) => 444, |
chr(234) => 444, |
chr(235) => 444, |
chr(236) => 278, |
chr(237) => 278, |
chr(238) => 278, |
chr(239) => 278, |
chr(240) => 500, |
chr(241) => 556, |
chr(242) => 500, |
chr(243) => 500, |
chr(244) => 500, |
chr(245) => 500, |
chr(246) => 500, |
chr(247) => 570, |
chr(248) => 500, |
chr(249) => 556, |
chr(250) => 556, |
chr(251) => 556, |
chr(252) => 556, |
chr(253) => 444, |
chr(254) => 500, |
chr(255) => 444); |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/zapfdingbats.php |
---|
New file |
0,0 → 1,272 |
<?php |
/** |
* @package File_PDF |
*/ |
$font_widths['zapfdingbats'] = array( |
chr(0) => 0, |
chr(1) => 0, |
chr(2) => 0, |
chr(3) => 0, |
chr(4) => 0, |
chr(5) => 0, |
chr(6) => 0, |
chr(7) => 0, |
chr(8) => 0, |
chr(9) => 0, |
chr(10) => 0, |
chr(11) => 0, |
chr(12) => 0, |
chr(13) => 0, |
chr(14) => 0, |
chr(15) => 0, |
chr(16) => 0, |
chr(17) => 0, |
chr(18) => 0, |
chr(19) => 0, |
chr(20) => 0, |
chr(21) => 0, |
chr(22) => 0, |
chr(23) => 0, |
chr(24) => 0, |
chr(25) => 0, |
chr(26) => 0, |
chr(27) => 0, |
chr(28) => 0, |
chr(29) => 0, |
chr(30) => 0, |
chr(31) => 0, |
' ' => 278, |
'!' => 974, |
'"' => 961, |
'#' => 974, |
'$' => 980, |
'%' => 719, |
'&' => 789, |
'\'' => 790, |
'(' => 791, |
')' => 690, |
'*' => 960, |
'+' => 939, |
',' => 549, |
'-' => 855, |
'.' => 911, |
'/' => 933, |
'0' => 911, |
'1' => 945, |
'2' => 974, |
'3' => 755, |
'4' => 846, |
'5' => 762, |
'6' => 761, |
'7' => 571, |
'8' => 677, |
'9' => 763, |
':' => 760, |
';' => 759, |
'<' => 754, |
'=' => 494, |
'>' => 552, |
'?' => 537, |
'@' => 577, |
'A' => 692, |
'B' => 786, |
'C' => 788, |
'D' => 788, |
'E' => 790, |
'F' => 793, |
'G' => 794, |
'H' => 816, |
'I' => 823, |
'J' => 789, |
'K' => 841, |
'L' => 823, |
'M' => 833, |
'N' => 816, |
'O' => 831, |
'P' => 923, |
'Q' => 744, |
'R' => 723, |
'S' => 749, |
'T' => 790, |
'U' => 792, |
'V' => 695, |
'W' => 776, |
'X' => 768, |
'Y' => 792, |
'Z' => 759, |
'[' => 707, |
'\\' => 708, |
']' => 682, |
'^' => 701, |
'_' => 826, |
'`' => 815, |
'a' => 789, |
'b' => 789, |
'c' => 707, |
'd' => 687, |
'e' => 696, |
'f' => 689, |
'g' => 786, |
'h' => 787, |
'i' => 713, |
'j' => 791, |
'k' => 785, |
'l' => 791, |
'm' => 873, |
'n' => 761, |
'o' => 762, |
'p' => 762, |
'q' => 759, |
'r' => 759, |
's' => 892, |
't' => 892, |
'u' => 788, |
'v' => 784, |
'w' => 438, |
'x' => 138, |
'y' => 277, |
'z' => 415, |
'{' => 392, |
'|' => 392, |
'}' => 668, |
'~' => 668, |
chr(127) => 0, |
chr(128) => 390, |
chr(129) => 390, |
chr(130) => 317, |
chr(131) => 317, |
chr(132) => 276, |
chr(133) => 276, |
chr(134) => 509, |
chr(135) => 509, |
chr(136) => 410, |
chr(137) => 410, |
chr(138) => 234, |
chr(139) => 234, |
chr(140) => 334, |
chr(141) => 334, |
chr(142) => 0, |
chr(143) => 0, |
chr(144) => 0, |
chr(145) => 0, |
chr(146) => 0, |
chr(147) => 0, |
chr(148) => 0, |
chr(149) => 0, |
chr(150) => 0, |
chr(151) => 0, |
chr(152) => 0, |
chr(153) => 0, |
chr(154) => 0, |
chr(155) => 0, |
chr(156) => 0, |
chr(157) => 0, |
chr(158) => 0, |
chr(159) => 0, |
chr(160) => 0, |
chr(161) => 732, |
chr(162) => 544, |
chr(163) => 544, |
chr(164) => 910, |
chr(165) => 667, |
chr(166) => 760, |
chr(167) => 760, |
chr(168) => 776, |
chr(169) => 595, |
chr(170) => 694, |
chr(171) => 626, |
chr(172) => 788, |
chr(173) => 788, |
chr(174) => 788, |
chr(175) => 788, |
chr(176) => 788, |
chr(177) => 788, |
chr(178) => 788, |
chr(179) => 788, |
chr(180) => 788, |
chr(181) => 788, |
chr(182) => 788, |
chr(183) => 788, |
chr(184) => 788, |
chr(185) => 788, |
chr(186) => 788, |
chr(187) => 788, |
chr(188) => 788, |
chr(189) => 788, |
chr(190) => 788, |
chr(191) => 788, |
chr(192) => 788, |
chr(193) => 788, |
chr(194) => 788, |
chr(195) => 788, |
chr(196) => 788, |
chr(197) => 788, |
chr(198) => 788, |
chr(199) => 788, |
chr(200) => 788, |
chr(201) => 788, |
chr(202) => 788, |
chr(203) => 788, |
chr(204) => 788, |
chr(205) => 788, |
chr(206) => 788, |
chr(207) => 788, |
chr(208) => 788, |
chr(209) => 788, |
chr(210) => 788, |
chr(211) => 788, |
chr(212) => 894, |
chr(213) => 838, |
chr(214) => 1016, |
chr(215) => 458, |
chr(216) => 748, |
chr(217) => 924, |
chr(218) => 748, |
chr(219) => 918, |
chr(220) => 927, |
chr(221) => 928, |
chr(222) => 928, |
chr(223) => 834, |
chr(224) => 873, |
chr(225) => 828, |
chr(226) => 924, |
chr(227) => 924, |
chr(228) => 917, |
chr(229) => 930, |
chr(230) => 931, |
chr(231) => 463, |
chr(232) => 883, |
chr(233) => 836, |
chr(234) => 836, |
chr(235) => 867, |
chr(236) => 867, |
chr(237) => 696, |
chr(238) => 696, |
chr(239) => 874, |
chr(240) => 0, |
chr(241) => 874, |
chr(242) => 760, |
chr(243) => 946, |
chr(244) => 771, |
chr(245) => 865, |
chr(246) => 771, |
chr(247) => 888, |
chr(248) => 967, |
chr(249) => 888, |
chr(250) => 831, |
chr(251) => 873, |
chr(252) => 927, |
chr(253) => 970, |
chr(254) => 918, |
chr(255) => 0); |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/helveticai.php |
---|
New file |
0,0 → 1,272 |
<?php |
/** |
* @package File_PDF |
*/ |
$font_widths['helveticaI'] = array( |
chr(0) => 278, |
chr(1) => 278, |
chr(2) => 278, |
chr(3) => 278, |
chr(4) => 278, |
chr(5) => 278, |
chr(6) => 278, |
chr(7) => 278, |
chr(8) => 278, |
chr(9) => 278, |
chr(10) => 278, |
chr(11) => 278, |
chr(12) => 278, |
chr(13) => 278, |
chr(14) => 278, |
chr(15) => 278, |
chr(16) => 278, |
chr(17) => 278, |
chr(18) => 278, |
chr(19) => 278, |
chr(20) => 278, |
chr(21) => 278, |
chr(22) => 278, |
chr(23) => 278, |
chr(24) => 278, |
chr(25) => 278, |
chr(26) => 278, |
chr(27) => 278, |
chr(28) => 278, |
chr(29) => 278, |
chr(30) => 278, |
chr(31) => 278, |
' ' => 278, |
'!' => 278, |
'"' => 355, |
'#' => 556, |
'$' => 556, |
'%' => 889, |
'&' => 667, |
'\'' => 191, |
'(' => 333, |
')' => 333, |
'*' => 389, |
'+' => 584, |
',' => 278, |
'-' => 333, |
'.' => 278, |
'/' => 278, |
'0' => 556, |
'1' => 556, |
'2' => 556, |
'3' => 556, |
'4' => 556, |
'5' => 556, |
'6' => 556, |
'7' => 556, |
'8' => 556, |
'9' => 556, |
':' => 278, |
';' => 278, |
'<' => 584, |
'=' => 584, |
'>' => 584, |
'?' => 556, |
'@' => 1015, |
'A' => 667, |
'B' => 667, |
'C' => 722, |
'D' => 722, |
'E' => 667, |
'F' => 611, |
'G' => 778, |
'H' => 722, |
'I' => 278, |
'J' => 500, |
'K' => 667, |
'L' => 556, |
'M' => 833, |
'N' => 722, |
'O' => 778, |
'P' => 667, |
'Q' => 778, |
'R' => 722, |
'S' => 667, |
'T' => 611, |
'U' => 722, |
'V' => 667, |
'W' => 944, |
'X' => 667, |
'Y' => 667, |
'Z' => 611, |
'[' => 278, |
'\\' => 278, |
']' => 278, |
'^' => 469, |
'_' => 556, |
'`' => 333, |
'a' => 556, |
'b' => 556, |
'c' => 500, |
'd' => 556, |
'e' => 556, |
'f' => 278, |
'g' => 556, |
'h' => 556, |
'i' => 222, |
'j' => 222, |
'k' => 500, |
'l' => 222, |
'm' => 833, |
'n' => 556, |
'o' => 556, |
'p' => 556, |
'q' => 556, |
'r' => 333, |
's' => 500, |
't' => 278, |
'u' => 556, |
'v' => 500, |
'w' => 722, |
'x' => 500, |
'y' => 500, |
'z' => 500, |
'{' => 334, |
'|' => 260, |
'}' => 334, |
'~' => 584, |
chr(127) => 350, |
chr(128) => 556, |
chr(129) => 350, |
chr(130) => 222, |
chr(131) => 556, |
chr(132) => 333, |
chr(133) => 1000, |
chr(134) => 556, |
chr(135) => 556, |
chr(136) => 333, |
chr(137) => 1000, |
chr(138) => 667, |
chr(139) => 333, |
chr(140) => 1000, |
chr(141) => 350, |
chr(142) => 611, |
chr(143) => 350, |
chr(144) => 350, |
chr(145) => 222, |
chr(146) => 222, |
chr(147) => 333, |
chr(148) => 333, |
chr(149) => 350, |
chr(150) => 556, |
chr(151) => 1000, |
chr(152) => 333, |
chr(153) => 1000, |
chr(154) => 500, |
chr(155) => 333, |
chr(156) => 944, |
chr(157) => 350, |
chr(158) => 500, |
chr(159) => 667, |
chr(160) => 278, |
chr(161) => 333, |
chr(162) => 556, |
chr(163) => 556, |
chr(164) => 556, |
chr(165) => 556, |
chr(166) => 260, |
chr(167) => 556, |
chr(168) => 333, |
chr(169) => 737, |
chr(170) => 370, |
chr(171) => 556, |
chr(172) => 584, |
chr(173) => 333, |
chr(174) => 737, |
chr(175) => 333, |
chr(176) => 400, |
chr(177) => 584, |
chr(178) => 333, |
chr(179) => 333, |
chr(180) => 333, |
chr(181) => 556, |
chr(182) => 537, |
chr(183) => 278, |
chr(184) => 333, |
chr(185) => 333, |
chr(186) => 365, |
chr(187) => 556, |
chr(188) => 834, |
chr(189) => 834, |
chr(190) => 834, |
chr(191) => 611, |
chr(192) => 667, |
chr(193) => 667, |
chr(194) => 667, |
chr(195) => 667, |
chr(196) => 667, |
chr(197) => 667, |
chr(198) => 1000, |
chr(199) => 722, |
chr(200) => 667, |
chr(201) => 667, |
chr(202) => 667, |
chr(203) => 667, |
chr(204) => 278, |
chr(205) => 278, |
chr(206) => 278, |
chr(207) => 278, |
chr(208) => 722, |
chr(209) => 722, |
chr(210) => 778, |
chr(211) => 778, |
chr(212) => 778, |
chr(213) => 778, |
chr(214) => 778, |
chr(215) => 584, |
chr(216) => 778, |
chr(217) => 722, |
chr(218) => 722, |
chr(219) => 722, |
chr(220) => 722, |
chr(221) => 667, |
chr(222) => 667, |
chr(223) => 611, |
chr(224) => 556, |
chr(225) => 556, |
chr(226) => 556, |
chr(227) => 556, |
chr(228) => 556, |
chr(229) => 556, |
chr(230) => 889, |
chr(231) => 500, |
chr(232) => 556, |
chr(233) => 556, |
chr(234) => 556, |
chr(235) => 556, |
chr(236) => 278, |
chr(237) => 278, |
chr(238) => 278, |
chr(239) => 278, |
chr(240) => 556, |
chr(241) => 556, |
chr(242) => 556, |
chr(243) => 556, |
chr(244) => 556, |
chr(245) => 556, |
chr(246) => 556, |
chr(247) => 584, |
chr(248) => 611, |
chr(249) => 556, |
chr(250) => 556, |
chr(251) => 556, |
chr(252) => 556, |
chr(253) => 500, |
chr(254) => 556, |
chr(255) => 500); |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/helveticabi.php |
---|
New file |
0,0 → 1,272 |
<?php |
/** |
* @package File_PDF |
*/ |
$font_widths['helveticaBI'] = array( |
chr(0) => 278, |
chr(1) => 278, |
chr(2) => 278, |
chr(3) => 278, |
chr(4) => 278, |
chr(5) => 278, |
chr(6) => 278, |
chr(7) => 278, |
chr(8) => 278, |
chr(9) => 278, |
chr(10) => 278, |
chr(11) => 278, |
chr(12) => 278, |
chr(13) => 278, |
chr(14) => 278, |
chr(15) => 278, |
chr(16) => 278, |
chr(17) => 278, |
chr(18) => 278, |
chr(19) => 278, |
chr(20) => 278, |
chr(21) => 278, |
chr(22) => 278, |
chr(23) => 278, |
chr(24) => 278, |
chr(25) => 278, |
chr(26) => 278, |
chr(27) => 278, |
chr(28) => 278, |
chr(29) => 278, |
chr(30) => 278, |
chr(31) => 278, |
' ' => 278, |
'!' => 333, |
'"' => 474, |
'#' => 556, |
'$' => 556, |
'%' => 889, |
'&' => 722, |
'\'' => 238, |
'(' => 333, |
')' => 333, |
'*' => 389, |
'+' => 584, |
',' => 278, |
'-' => 333, |
'.' => 278, |
'/' => 278, |
'0' => 556, |
'1' => 556, |
'2' => 556, |
'3' => 556, |
'4' => 556, |
'5' => 556, |
'6' => 556, |
'7' => 556, |
'8' => 556, |
'9' => 556, |
':' => 333, |
';' => 333, |
'<' => 584, |
'=' => 584, |
'>' => 584, |
'?' => 611, |
'@' => 975, |
'A' => 722, |
'B' => 722, |
'C' => 722, |
'D' => 722, |
'E' => 667, |
'F' => 611, |
'G' => 778, |
'H' => 722, |
'I' => 278, |
'J' => 556, |
'K' => 722, |
'L' => 611, |
'M' => 833, |
'N' => 722, |
'O' => 778, |
'P' => 667, |
'Q' => 778, |
'R' => 722, |
'S' => 667, |
'T' => 611, |
'U' => 722, |
'V' => 667, |
'W' => 944, |
'X' => 667, |
'Y' => 667, |
'Z' => 611, |
'[' => 333, |
'\\' => 278, |
']' => 333, |
'^' => 584, |
'_' => 556, |
'`' => 333, |
'a' => 556, |
'b' => 611, |
'c' => 556, |
'd' => 611, |
'e' => 556, |
'f' => 333, |
'g' => 611, |
'h' => 611, |
'i' => 278, |
'j' => 278, |
'k' => 556, |
'l' => 278, |
'm' => 889, |
'n' => 611, |
'o' => 611, |
'p' => 611, |
'q' => 611, |
'r' => 389, |
's' => 556, |
't' => 333, |
'u' => 611, |
'v' => 556, |
'w' => 778, |
'x' => 556, |
'y' => 556, |
'z' => 500, |
'{' => 389, |
'|' => 280, |
'}' => 389, |
'~' => 584, |
chr(127) => 350, |
chr(128) => 556, |
chr(129) => 350, |
chr(130) => 278, |
chr(131) => 556, |
chr(132) => 500, |
chr(133) => 1000, |
chr(134) => 556, |
chr(135) => 556, |
chr(136) => 333, |
chr(137) => 1000, |
chr(138) => 667, |
chr(139) => 333, |
chr(140) => 1000, |
chr(141) => 350, |
chr(142) => 611, |
chr(143) => 350, |
chr(144) => 350, |
chr(145) => 278, |
chr(146) => 278, |
chr(147) => 500, |
chr(148) => 500, |
chr(149) => 350, |
chr(150) => 556, |
chr(151) => 1000, |
chr(152) => 333, |
chr(153) => 1000, |
chr(154) => 556, |
chr(155) => 333, |
chr(156) => 944, |
chr(157) => 350, |
chr(158) => 500, |
chr(159) => 667, |
chr(160) => 278, |
chr(161) => 333, |
chr(162) => 556, |
chr(163) => 556, |
chr(164) => 556, |
chr(165) => 556, |
chr(166) => 280, |
chr(167) => 556, |
chr(168) => 333, |
chr(169) => 737, |
chr(170) => 370, |
chr(171) => 556, |
chr(172) => 584, |
chr(173) => 333, |
chr(174) => 737, |
chr(175) => 333, |
chr(176) => 400, |
chr(177) => 584, |
chr(178) => 333, |
chr(179) => 333, |
chr(180) => 333, |
chr(181) => 611, |
chr(182) => 556, |
chr(183) => 278, |
chr(184) => 333, |
chr(185) => 333, |
chr(186) => 365, |
chr(187) => 556, |
chr(188) => 834, |
chr(189) => 834, |
chr(190) => 834, |
chr(191) => 611, |
chr(192) => 722, |
chr(193) => 722, |
chr(194) => 722, |
chr(195) => 722, |
chr(196) => 722, |
chr(197) => 722, |
chr(198) => 1000, |
chr(199) => 722, |
chr(200) => 667, |
chr(201) => 667, |
chr(202) => 667, |
chr(203) => 667, |
chr(204) => 278, |
chr(205) => 278, |
chr(206) => 278, |
chr(207) => 278, |
chr(208) => 722, |
chr(209) => 722, |
chr(210) => 778, |
chr(211) => 778, |
chr(212) => 778, |
chr(213) => 778, |
chr(214) => 778, |
chr(215) => 584, |
chr(216) => 778, |
chr(217) => 722, |
chr(218) => 722, |
chr(219) => 722, |
chr(220) => 722, |
chr(221) => 667, |
chr(222) => 667, |
chr(223) => 611, |
chr(224) => 556, |
chr(225) => 556, |
chr(226) => 556, |
chr(227) => 556, |
chr(228) => 556, |
chr(229) => 556, |
chr(230) => 889, |
chr(231) => 556, |
chr(232) => 556, |
chr(233) => 556, |
chr(234) => 556, |
chr(235) => 556, |
chr(236) => 278, |
chr(237) => 278, |
chr(238) => 278, |
chr(239) => 278, |
chr(240) => 611, |
chr(241) => 611, |
chr(242) => 611, |
chr(243) => 611, |
chr(244) => 611, |
chr(245) => 611, |
chr(246) => 611, |
chr(247) => 584, |
chr(248) => 611, |
chr(249) => 611, |
chr(250) => 611, |
chr(251) => 611, |
chr(252) => 611, |
chr(253) => 556, |
chr(254) => 611, |
chr(255) => 556); |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/times.php |
---|
New file |
0,0 → 1,272 |
<?php |
/** |
* @package File_PDF |
*/ |
$font_widths['times'] = array( |
chr(0) => 250, |
chr(1) => 250, |
chr(2) => 250, |
chr(3) => 250, |
chr(4) => 250, |
chr(5) => 250, |
chr(6) => 250, |
chr(7) => 250, |
chr(8) => 250, |
chr(9) => 250, |
chr(10) => 250, |
chr(11) => 250, |
chr(12) => 250, |
chr(13) => 250, |
chr(14) => 250, |
chr(15) => 250, |
chr(16) => 250, |
chr(17) => 250, |
chr(18) => 250, |
chr(19) => 250, |
chr(20) => 250, |
chr(21) => 250, |
chr(22) => 250, |
chr(23) => 250, |
chr(24) => 250, |
chr(25) => 250, |
chr(26) => 250, |
chr(27) => 250, |
chr(28) => 250, |
chr(29) => 250, |
chr(30) => 250, |
chr(31) => 250, |
' ' => 250, |
'!' => 333, |
'"' => 408, |
'#' => 500, |
'$' => 500, |
'%' => 833, |
'&' => 778, |
'\'' => 180, |
'(' => 333, |
')' => 333, |
'*' => 500, |
'+' => 564, |
',' => 250, |
'-' => 333, |
'.' => 250, |
'/' => 278, |
'0' => 500, |
'1' => 500, |
'2' => 500, |
'3' => 500, |
'4' => 500, |
'5' => 500, |
'6' => 500, |
'7' => 500, |
'8' => 500, |
'9' => 500, |
':' => 278, |
';' => 278, |
'<' => 564, |
'=' => 564, |
'>' => 564, |
'?' => 444, |
'@' => 921, |
'A' => 722, |
'B' => 667, |
'C' => 667, |
'D' => 722, |
'E' => 611, |
'F' => 556, |
'G' => 722, |
'H' => 722, |
'I' => 333, |
'J' => 389, |
'K' => 722, |
'L' => 611, |
'M' => 889, |
'N' => 722, |
'O' => 722, |
'P' => 556, |
'Q' => 722, |
'R' => 667, |
'S' => 556, |
'T' => 611, |
'U' => 722, |
'V' => 722, |
'W' => 944, |
'X' => 722, |
'Y' => 722, |
'Z' => 611, |
'[' => 333, |
'\\' => 278, |
']' => 333, |
'^' => 469, |
'_' => 500, |
'`' => 333, |
'a' => 444, |
'b' => 500, |
'c' => 444, |
'd' => 500, |
'e' => 444, |
'f' => 333, |
'g' => 500, |
'h' => 500, |
'i' => 278, |
'j' => 278, |
'k' => 500, |
'l' => 278, |
'm' => 778, |
'n' => 500, |
'o' => 500, |
'p' => 500, |
'q' => 500, |
'r' => 333, |
's' => 389, |
't' => 278, |
'u' => 500, |
'v' => 500, |
'w' => 722, |
'x' => 500, |
'y' => 500, |
'z' => 444, |
'{' => 480, |
'|' => 200, |
'}' => 480, |
'~' => 541, |
chr(127) => 350, |
chr(128) => 500, |
chr(129) => 350, |
chr(130) => 333, |
chr(131) => 500, |
chr(132) => 444, |
chr(133) => 1000, |
chr(134) => 500, |
chr(135) => 500, |
chr(136) => 333, |
chr(137) => 1000, |
chr(138) => 556, |
chr(139) => 333, |
chr(140) => 889, |
chr(141) => 350, |
chr(142) => 611, |
chr(143) => 350, |
chr(144) => 350, |
chr(145) => 333, |
chr(146) => 333, |
chr(147) => 444, |
chr(148) => 444, |
chr(149) => 350, |
chr(150) => 500, |
chr(151) => 1000, |
chr(152) => 333, |
chr(153) => 980, |
chr(154) => 389, |
chr(155) => 333, |
chr(156) => 722, |
chr(157) => 350, |
chr(158) => 444, |
chr(159) => 722, |
chr(160) => 250, |
chr(161) => 333, |
chr(162) => 500, |
chr(163) => 500, |
chr(164) => 500, |
chr(165) => 500, |
chr(166) => 200, |
chr(167) => 500, |
chr(168) => 333, |
chr(169) => 760, |
chr(170) => 276, |
chr(171) => 500, |
chr(172) => 564, |
chr(173) => 333, |
chr(174) => 760, |
chr(175) => 333, |
chr(176) => 400, |
chr(177) => 564, |
chr(178) => 300, |
chr(179) => 300, |
chr(180) => 333, |
chr(181) => 500, |
chr(182) => 453, |
chr(183) => 250, |
chr(184) => 333, |
chr(185) => 300, |
chr(186) => 310, |
chr(187) => 500, |
chr(188) => 750, |
chr(189) => 750, |
chr(190) => 750, |
chr(191) => 444, |
chr(192) => 722, |
chr(193) => 722, |
chr(194) => 722, |
chr(195) => 722, |
chr(196) => 722, |
chr(197) => 722, |
chr(198) => 889, |
chr(199) => 667, |
chr(200) => 611, |
chr(201) => 611, |
chr(202) => 611, |
chr(203) => 611, |
chr(204) => 333, |
chr(205) => 333, |
chr(206) => 333, |
chr(207) => 333, |
chr(208) => 722, |
chr(209) => 722, |
chr(210) => 722, |
chr(211) => 722, |
chr(212) => 722, |
chr(213) => 722, |
chr(214) => 722, |
chr(215) => 564, |
chr(216) => 722, |
chr(217) => 722, |
chr(218) => 722, |
chr(219) => 722, |
chr(220) => 722, |
chr(221) => 722, |
chr(222) => 556, |
chr(223) => 500, |
chr(224) => 444, |
chr(225) => 444, |
chr(226) => 444, |
chr(227) => 444, |
chr(228) => 444, |
chr(229) => 444, |
chr(230) => 667, |
chr(231) => 444, |
chr(232) => 444, |
chr(233) => 444, |
chr(234) => 444, |
chr(235) => 444, |
chr(236) => 278, |
chr(237) => 278, |
chr(238) => 278, |
chr(239) => 278, |
chr(240) => 500, |
chr(241) => 500, |
chr(242) => 500, |
chr(243) => 500, |
chr(244) => 500, |
chr(245) => 500, |
chr(246) => 500, |
chr(247) => 564, |
chr(248) => 500, |
chr(249) => 500, |
chr(250) => 500, |
chr(251) => 500, |
chr(252) => 500, |
chr(253) => 500, |
chr(254) => 500, |
chr(255) => 500); |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/timesb.php |
---|
New file |
0,0 → 1,272 |
<?php |
/** |
* @package File_PDF |
*/ |
$font_widths['timesB'] = array( |
chr(0) => 250, |
chr(1) => 250, |
chr(2) => 250, |
chr(3) => 250, |
chr(4) => 250, |
chr(5) => 250, |
chr(6) => 250, |
chr(7) => 250, |
chr(8) => 250, |
chr(9) => 250, |
chr(10) => 250, |
chr(11) => 250, |
chr(12) => 250, |
chr(13) => 250, |
chr(14) => 250, |
chr(15) => 250, |
chr(16) => 250, |
chr(17) => 250, |
chr(18) => 250, |
chr(19) => 250, |
chr(20) => 250, |
chr(21) => 250, |
chr(22) => 250, |
chr(23) => 250, |
chr(24) => 250, |
chr(25) => 250, |
chr(26) => 250, |
chr(27) => 250, |
chr(28) => 250, |
chr(29) => 250, |
chr(30) => 250, |
chr(31) => 250, |
' ' => 250, |
'!' => 333, |
'"' => 555, |
'#' => 500, |
'$' => 500, |
'%' => 1000, |
'&' => 833, |
'\'' => 278, |
'(' => 333, |
')' => 333, |
'*' => 500, |
'+' => 570, |
',' => 250, |
'-' => 333, |
'.' => 250, |
'/' => 278, |
'0' => 500, |
'1' => 500, |
'2' => 500, |
'3' => 500, |
'4' => 500, |
'5' => 500, |
'6' => 500, |
'7' => 500, |
'8' => 500, |
'9' => 500, |
':' => 333, |
';' => 333, |
'<' => 570, |
'=' => 570, |
'>' => 570, |
'?' => 500, |
'@' => 930, |
'A' => 722, |
'B' => 667, |
'C' => 722, |
'D' => 722, |
'E' => 667, |
'F' => 611, |
'G' => 778, |
'H' => 778, |
'I' => 389, |
'J' => 500, |
'K' => 778, |
'L' => 667, |
'M' => 944, |
'N' => 722, |
'O' => 778, |
'P' => 611, |
'Q' => 778, |
'R' => 722, |
'S' => 556, |
'T' => 667, |
'U' => 722, |
'V' => 722, |
'W' => 1000, |
'X' => 722, |
'Y' => 722, |
'Z' => 667, |
'[' => 333, |
'\\' => 278, |
']' => 333, |
'^' => 581, |
'_' => 500, |
'`' => 333, |
'a' => 500, |
'b' => 556, |
'c' => 444, |
'd' => 556, |
'e' => 444, |
'f' => 333, |
'g' => 500, |
'h' => 556, |
'i' => 278, |
'j' => 333, |
'k' => 556, |
'l' => 278, |
'm' => 833, |
'n' => 556, |
'o' => 500, |
'p' => 556, |
'q' => 556, |
'r' => 444, |
's' => 389, |
't' => 333, |
'u' => 556, |
'v' => 500, |
'w' => 722, |
'x' => 500, |
'y' => 500, |
'z' => 444, |
'{' => 394, |
'|' => 220, |
'}' => 394, |
'~' => 520, |
chr(127) => 350, |
chr(128) => 500, |
chr(129) => 350, |
chr(130) => 333, |
chr(131) => 500, |
chr(132) => 500, |
chr(133) => 1000, |
chr(134) => 500, |
chr(135) => 500, |
chr(136) => 333, |
chr(137) => 1000, |
chr(138) => 556, |
chr(139) => 333, |
chr(140) => 1000, |
chr(141) => 350, |
chr(142) => 667, |
chr(143) => 350, |
chr(144) => 350, |
chr(145) => 333, |
chr(146) => 333, |
chr(147) => 500, |
chr(148) => 500, |
chr(149) => 350, |
chr(150) => 500, |
chr(151) => 1000, |
chr(152) => 333, |
chr(153) => 1000, |
chr(154) => 389, |
chr(155) => 333, |
chr(156) => 722, |
chr(157) => 350, |
chr(158) => 444, |
chr(159) => 722, |
chr(160) => 250, |
chr(161) => 333, |
chr(162) => 500, |
chr(163) => 500, |
chr(164) => 500, |
chr(165) => 500, |
chr(166) => 220, |
chr(167) => 500, |
chr(168) => 333, |
chr(169) => 747, |
chr(170) => 300, |
chr(171) => 500, |
chr(172) => 570, |
chr(173) => 333, |
chr(174) => 747, |
chr(175) => 333, |
chr(176) => 400, |
chr(177) => 570, |
chr(178) => 300, |
chr(179) => 300, |
chr(180) => 333, |
chr(181) => 556, |
chr(182) => 540, |
chr(183) => 250, |
chr(184) => 333, |
chr(185) => 300, |
chr(186) => 330, |
chr(187) => 500, |
chr(188) => 750, |
chr(189) => 750, |
chr(190) => 750, |
chr(191) => 500, |
chr(192) => 722, |
chr(193) => 722, |
chr(194) => 722, |
chr(195) => 722, |
chr(196) => 722, |
chr(197) => 722, |
chr(198) => 1000, |
chr(199) => 722, |
chr(200) => 667, |
chr(201) => 667, |
chr(202) => 667, |
chr(203) => 667, |
chr(204) => 389, |
chr(205) => 389, |
chr(206) => 389, |
chr(207) => 389, |
chr(208) => 722, |
chr(209) => 722, |
chr(210) => 778, |
chr(211) => 778, |
chr(212) => 778, |
chr(213) => 778, |
chr(214) => 778, |
chr(215) => 570, |
chr(216) => 778, |
chr(217) => 722, |
chr(218) => 722, |
chr(219) => 722, |
chr(220) => 722, |
chr(221) => 722, |
chr(222) => 611, |
chr(223) => 556, |
chr(224) => 500, |
chr(225) => 500, |
chr(226) => 500, |
chr(227) => 500, |
chr(228) => 500, |
chr(229) => 500, |
chr(230) => 722, |
chr(231) => 444, |
chr(232) => 444, |
chr(233) => 444, |
chr(234) => 444, |
chr(235) => 444, |
chr(236) => 278, |
chr(237) => 278, |
chr(238) => 278, |
chr(239) => 278, |
chr(240) => 500, |
chr(241) => 556, |
chr(242) => 500, |
chr(243) => 500, |
chr(244) => 500, |
chr(245) => 500, |
chr(246) => 500, |
chr(247) => 570, |
chr(248) => 500, |
chr(249) => 556, |
chr(250) => 556, |
chr(251) => 556, |
chr(252) => 556, |
chr(253) => 500, |
chr(254) => 556, |
chr(255) => 500); |
/branches/v1.6-croc/jrest/lib/File/PDF/fonts/helvetica.php |
---|
New file |
0,0 → 1,272 |
<?php |
/** |
* @package File_PDF |
*/ |
$font_widths['helvetica'] = array( |
chr(0) => 278, |
chr(1) => 278, |
chr(2) => 278, |
chr(3) => 278, |
chr(4) => 278, |
chr(5) => 278, |
chr(6) => 278, |
chr(7) => 278, |
chr(8) => 278, |
chr(9) => 278, |
chr(10) => 278, |
chr(11) => 278, |
chr(12) => 278, |
chr(13) => 278, |
chr(14) => 278, |
chr(15) => 278, |
chr(16) => 278, |
chr(17) => 278, |
chr(18) => 278, |
chr(19) => 278, |
chr(20) => 278, |
chr(21) => 278, |
chr(22) => 278, |
chr(23) => 278, |
chr(24) => 278, |
chr(25) => 278, |
chr(26) => 278, |
chr(27) => 278, |
chr(28) => 278, |
chr(29) => 278, |
chr(30) => 278, |
chr(31) => 278, |
' ' => 278, |
'!' => 278, |
'"' => 355, |
'#' => 556, |
'$' => 556, |
'%' => 889, |
'&' => 667, |
'\'' => 191, |
'(' => 333, |
')' => 333, |
'*' => 389, |
'+' => 584, |
',' => 278, |
'-' => 333, |
'.' => 278, |
'/' => 278, |
'0' => 556, |
'1' => 556, |
'2' => 556, |
'3' => 556, |
'4' => 556, |
'5' => 556, |
'6' => 556, |
'7' => 556, |
'8' => 556, |
'9' => 556, |
':' => 278, |
';' => 278, |
'<' => 584, |
'=' => 584, |
'>' => 584, |
'?' => 556, |
'@' => 1015, |
'A' => 667, |
'B' => 667, |
'C' => 722, |
'D' => 722, |
'E' => 667, |
'F' => 611, |
'G' => 778, |
'H' => 722, |
'I' => 278, |
'J' => 500, |
'K' => 667, |
'L' => 556, |
'M' => 833, |
'N' => 722, |
'O' => 778, |
'P' => 667, |
'Q' => 778, |
'R' => 722, |
'S' => 667, |
'T' => 611, |
'U' => 722, |
'V' => 667, |
'W' => 944, |
'X' => 667, |
'Y' => 667, |
'Z' => 611, |
'[' => 278, |
'\\' => 278, |
']' => 278, |
'^' => 469, |
'_' => 556, |
'`' => 333, |
'a' => 556, |
'b' => 556, |
'c' => 500, |
'd' => 556, |
'e' => 556, |
'f' => 278, |
'g' => 556, |
'h' => 556, |
'i' => 222, |
'j' => 222, |
'k' => 500, |
'l' => 222, |
'm' => 833, |
'n' => 556, |
'o' => 556, |
'p' => 556, |
'q' => 556, |
'r' => 333, |
's' => 500, |
't' => 278, |
'u' => 556, |
'v' => 500, |
'w' => 722, |
'x' => 500, |
'y' => 500, |
'z' => 500, |
'{' => 334, |
'|' => 260, |
'}' => 334, |
'~' => 584, |
chr(127) => 350, |
chr(128) => 556, |
chr(129) => 350, |
chr(130) => 222, |
chr(131) => 556, |
chr(132) => 333, |
chr(133) => 1000, |
chr(134) => 556, |
chr(135) => 556, |
chr(136) => 333, |
chr(137) => 1000, |
chr(138) => 667, |
chr(139) => 333, |
chr(140) => 1000, |
chr(141) => 350, |
chr(142) => 611, |
chr(143) => 350, |
chr(144) => 350, |
chr(145) => 222, |
chr(146) => 222, |
chr(147) => 333, |
chr(148) => 333, |
chr(149) => 350, |
chr(150) => 556, |
chr(151) => 1000, |
chr(152) => 333, |
chr(153) => 1000, |
chr(154) => 500, |
chr(155) => 333, |
chr(156) => 944, |
chr(157) => 350, |
chr(158) => 500, |
chr(159) => 667, |
chr(160) => 278, |
chr(161) => 333, |
chr(162) => 556, |
chr(163) => 556, |
chr(164) => 556, |
chr(165) => 556, |
chr(166) => 260, |
chr(167) => 556, |
chr(168) => 333, |
chr(169) => 737, |
chr(170) => 370, |
chr(171) => 556, |
chr(172) => 584, |
chr(173) => 333, |
chr(174) => 737, |
chr(175) => 333, |
chr(176) => 400, |
chr(177) => 584, |
chr(178) => 333, |
chr(179) => 333, |
chr(180) => 333, |
chr(181) => 556, |
chr(182) => 537, |
chr(183) => 278, |
chr(184) => 333, |
chr(185) => 333, |
chr(186) => 365, |
chr(187) => 556, |
chr(188) => 834, |
chr(189) => 834, |
chr(190) => 834, |
chr(191) => 611, |
chr(192) => 667, |
chr(193) => 667, |
chr(194) => 667, |
chr(195) => 667, |
chr(196) => 667, |
chr(197) => 667, |
chr(198) => 1000, |
chr(199) => 722, |
chr(200) => 667, |
chr(201) => 667, |
chr(202) => 667, |
chr(203) => 667, |
chr(204) => 278, |
chr(205) => 278, |
chr(206) => 278, |
chr(207) => 278, |
chr(208) => 722, |
chr(209) => 722, |
chr(210) => 778, |
chr(211) => 778, |
chr(212) => 778, |
chr(213) => 778, |
chr(214) => 778, |
chr(215) => 584, |
chr(216) => 778, |
chr(217) => 722, |
chr(218) => 722, |
chr(219) => 722, |
chr(220) => 722, |
chr(221) => 667, |
chr(222) => 667, |
chr(223) => 611, |
chr(224) => 556, |
chr(225) => 556, |
chr(226) => 556, |
chr(227) => 556, |
chr(228) => 556, |
chr(229) => 556, |
chr(230) => 889, |
chr(231) => 500, |
chr(232) => 556, |
chr(233) => 556, |
chr(234) => 556, |
chr(235) => 556, |
chr(236) => 278, |
chr(237) => 278, |
chr(238) => 278, |
chr(239) => 278, |
chr(240) => 556, |
chr(241) => 556, |
chr(242) => 556, |
chr(243) => 556, |
chr(244) => 556, |
chr(245) => 556, |
chr(246) => 556, |
chr(247) => 584, |
chr(248) => 611, |
chr(249) => 556, |
chr(250) => 556, |
chr(251) => 556, |
chr(252) => 556, |
chr(253) => 500, |
chr(254) => 556, |
chr(255) => 500); |
/branches/v1.6-croc/jrest/lib/File/PDF/.directory |
---|
New file |
0,0 → 1,5 |
[Dolphin] |
Timestamp=2010,10,19,15,1,28 |
[Settings] |
ShowDotFiles=true |
/branches/v1.6-croc/jrest/lib/GestionChampsEtendus.php |
---|
New file |
0,0 → 1,228 |
<?php |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurelien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* Classe de gestion de l'ajout, modification et suppression des champs supplémentaires des obs et images |
* |
* in=utf8 |
* out=utf8 |
* |
*/ |
class GestionChampsEtendus extends Cel { |
private $mode = null; |
private $table_champs_etendus = null; |
private $champ_id = null; |
public function GestionChampsEtendus($config, $mode) { |
parent::__construct($config); |
$this->mode = $mode; |
if($this->mode == 'obs') { |
$this->mode = 'obs'; |
$this->table_champs_etendus = 'cel_obs_etendues'; |
$this->champ_id = 'id_observation'; |
} else if($this->mode == 'image') { |
$this->mode = 'image'; |
$this->table_champs_etendus = 'cel_images_etendues'; |
$this->champ_id = 'id_image'; |
} else { |
throw new Exception('Mode inconnu, les modes autorisés sont "obs" et "image"'); |
} |
} |
/** |
* Renvoie true ou false suivant que l'element indiqué possède une valeur |
* pour la clé indiquée |
* |
* @param int $id_element_lie |
* @param string $cle |
* @param string $valeur |
* @return bool |
*/ |
public function champEtenduExistePourElement($id_element_lie, $cle) { |
$requete = "SELECT COUNT(*) >= 1 as existe FROM ".$this->table_champs_etendus." ". |
"WHERE ".$this->champ_id." = ".$this->proteger($id_element_lie)." ". |
"AND cle = ".$this->proteger($cle); |
$resultat = $this->executerRequete($requete); |
return ($resultat[0]['existe'] == "1"); |
} |
/** |
* Renvoie tous les champs étendus associé à l'élément passé en paramètre |
* |
* @param int $id_element_lie |
* @return array |
*/ |
public function obtenirChampsEtendusPourElement($id_element_lie) { |
$requete = "SELECT * FROM ".$this->table_champs_etendus." ". |
"WHERE ".$this->champ_id." = ".$this->proteger($id_element_lie)." "; |
$resultat = $this->executerRequete($requete); |
return $resultat; |
} |
/** |
* Renvoie tous les champs étendus associés aux éléments passés en paramètre |
* Sous forme tableau de tableaux associatifs clé valeur regroupé par id d'élement |
* |
* @param array $ids_element_lies |
* @return array |
*/ |
public function obtenirChampsEtendusPourElementsMultiples($ids_element_lies) { |
$champs_etendus_par_element = array(); |
if(!empty($ids_element_lies)) { |
$ids_element_lies = array_map(array($this, 'proteger'),$ids_element_lies); |
$requete = "SELECT * FROM ".$this->table_champs_etendus." ". |
"WHERE ".$this->champ_id." IN (".implode(',',$ids_element_lies).") "; |
$resultats = $this->executerRequete($requete); |
$champs_etendus_par_element = array(); |
foreach ($resultats as &$ligne) { |
$id_element = $ligne[$this->champ_id]; |
if(!isset($champs_etendus_par_element[$id_element])) { |
$champs_etendus_par_element[$id_element] = array(); |
} |
$champs_etendus_par_element[$id_element][$ligne['cle']] = $ligne['valeur']; |
} |
} |
return $champs_etendus_par_element; |
} |
/** |
* Ajoute un champ étendu à l'élément passé en paramètre, |
* si la clé existe déjà, seule valeur du champ est mise à jour |
* |
* @param int $id_element_lie |
* @param string $cle |
* @param string $valeur |
* @return bool |
*/ |
public function ajouterChampEtendu($id_element_lie, $cle, $valeur) { |
$requete = "INSERT INTO ".$this->table_champs_etendus." ". |
"(".$this->champ_id.", cle, valeur) ". |
"VALUES (".$this->proteger($id_element_lie).",".$this->proteger($cle).",".$this->proteger($valeur).") ". |
"ON DUPLICATE KEY UPDATE valeur = VALUES(valeur)"; |
// la partie on duplicate key est spécifique mysql mais il sera facile de s'en passer le jour |
// où l'on change de sgbd |
$ajout = $this->executerRequeteSimple($requete); |
return ($ajout !== false); |
} |
/** |
* Ajoute des champs étendus à l'élément passé en paramètre, |
* si la clé existe déjà, seule la valeur du champ est mise à jour |
* |
* @param int $id_element_lie |
* @param array $cles_valeurs tableau de clés => valeurs à associer à l'élément |
* @return bool |
*/ |
public function ajouterChampsEtendusMultiples($id_element_lie, $cles_valeurs) { |
$lignes = array(); |
foreach($cles_valeurs as $cle => $valeur) { |
$lignes[] = "(".$this->proteger($id_element_lie).",".$this->proteger($cle).",".$this->proteger($valeur).")"; |
} |
$requete = "INSERT INTO ".$this->table_champs_etendus." ". |
"(".$this->champ_id.", cle, valeur) ". |
"VALUES ".implode(',', $lignes)." ". |
"ON DUPLICATE KEY UPDATE valeur = VALUES(valeur)"; |
// la partie on duplicate key est spécifique mysql mais il sera facile de s'en passer le jour |
// où l'on change de sgbd |
$ajout = $this->executerRequeteSimple($requete); |
return ($ajout !== false); |
} |
/** |
* Ajoute des champs étendus aux éléments passés en paramètre, |
* si la clé existe déjà, seule la valeur du champ est mise à jour |
* |
* @param array $elements_cles_valeurs tableau associatif de la forme id, cle, valeur |
* @return bool |
*/ |
public function ajouterChampsEtendusMultiplesAElementsMultiples($elements_cles_valeurs) { |
$lignes = array(); |
foreach($elements_cles_valeurs as &$element) { |
$lignes[] = "(".$this->proteger($element['id']).",".$this->proteger($element['cle']).",".$this->proteger($element['valeur']).")"; |
} |
$requete = "INSERT INTO ".$this->table_champs_etendus." ". |
"(".$this->champ_id.", cle, valeur) ". |
"VALUES ".implode(',', $lignes)." ". |
"ON DUPLICATE KEY UPDATE valeur = VALUES(valeur)"; |
// la partie on duplicate key est spécifique mysql mais il sera facile de s'en passer le jour |
// où l'on change de sgbd |
$ajout = $this->executerRequeteSimple($requete); |
return ($ajout !== false); |
} |
/** |
* Modifie un champ étendu associé à l'élément passé en paramètre |
* |
* @param int $id_element_lie |
* @param string $cle |
* @param string $valeur |
* @return bool |
*/ |
public function modifierChampEtendu($id_element_lie, $cle, $valeur) { |
$requete = "UPDATE ".$this->table_champs_etendus." ". |
"SET valeur = ".$this->proteger($valeur)." ". |
"WHERE cle = ".$this->proteger($cle)." AND ". |
$this->champ_id." = ".$this->proteger($id_element_lie); |
$modif = $this->executerRequeteSimple($requete); |
return ($modif !== false); |
} |
/** |
* Supprime le champ champ étendu associé à l'élément et au nom de clé passés en paramètre |
* |
* @param int $id_element_lie |
* @param string $cle |
* @return bool |
*/ |
public function supprimerChampEtendu($id_element_lie, $cle) { |
$requete = "DELETE FROM ".$this->table_champs_etendus." ". |
"WHERE cle = ".$this->proteger($cle)." AND ". |
$this->champ_id." = ".$this->proteger($id_element_lie); |
$suppr = $this->executerRequeteSimple($requete); |
return ($suppr !== false); |
} |
/** |
* Supprime tous les champs champ étendu associés à l'élément passés en paramètre |
* |
* @param int $id_element_lie |
* @return bool |
*/ |
public function supprimerChampsEtendusAElement($id_element_lie) { |
$requete = "DELETE FROM ".$this->table_champs_etendus." ". |
"WHERE ".$this->champ_id." = ".$this->proteger($id_element_lie); |
$suppr = $this->executerRequeteSimple($requete); |
return ($suppr !== false); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Mail_mimeDecode.php |
---|
New file |
0,0 → 1,1003 |
<?php |
/** |
* The Mail_mimeDecode class is used to decode mail/mime messages |
* |
* This class will parse a raw mime email and return |
* the structure. Returned structure is similar to |
* that returned by imap_fetchstructure(). |
* |
* +----------------------------- IMPORTANT ------------------------------+ |
* | Usage of this class compared to native php extensions such as | |
* | mailparse or imap, is slow and may be feature deficient. If available| |
* | you are STRONGLY recommended to use the php extensions. | |
* +----------------------------------------------------------------------+ |
* |
* Compatible with PHP versions 4 and 5 |
* |
* LICENSE: This LICENSE is in the BSD license style. |
* Copyright (c) 2002-2003, Richard Heyes <richard@phpguru.org> |
* Copyright (c) 2003-2006, PEAR <pear-group@php.net> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or |
* without modification, are permitted provided that the following |
* conditions are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - Neither the name of the authors, nor the names of its contributors |
* may 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. |
* |
* @category Mail |
* @package Mail_Mime |
* @author Richard Heyes <richard@phpguru.org> |
* @author George Schlossnagle <george@omniti.com> |
* @author Cipriano Groenendal <cipri@php.net> |
* @author Sean Coates <sean@php.net> |
* @copyright 2003-2006 PEAR <pear-group@php.net> |
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
* @version CVS: $Id: mimeDecode.php 305875 2010-12-01 07:17:10Z alan_k $ |
* @link http://pear.php.net/package/Mail_mime |
*/ |
/** |
* require PEAR |
* |
* This package depends on PEAR to raise errors. |
*/ |
require_once 'PEAR.php'; |
/** |
* The Mail_mimeDecode class is used to decode mail/mime messages |
* |
* This class will parse a raw mime email and return the structure. |
* Returned structure is similar to that returned by imap_fetchstructure(). |
* |
* +----------------------------- IMPORTANT ------------------------------+ |
* | Usage of this class compared to native php extensions such as | |
* | mailparse or imap, is slow and may be feature deficient. If available| |
* | you are STRONGLY recommended to use the php extensions. | |
* +----------------------------------------------------------------------+ |
* |
* @category Mail |
* @package Mail_Mime |
* @author Richard Heyes <richard@phpguru.org> |
* @author George Schlossnagle <george@omniti.com> |
* @author Cipriano Groenendal <cipri@php.net> |
* @author Sean Coates <sean@php.net> |
* @copyright 2003-2006 PEAR <pear-group@php.net> |
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
* @version Release: @package_version@ |
* @link http://pear.php.net/package/Mail_mime |
*/ |
class Mail_mimeDecode extends PEAR |
{ |
/** |
* The raw email to decode |
* |
* @var string |
* @access private |
*/ |
var $_input; |
/** |
* The header part of the input |
* |
* @var string |
* @access private |
*/ |
var $_header; |
/** |
* The body part of the input |
* |
* @var string |
* @access private |
*/ |
var $_body; |
/** |
* If an error occurs, this is used to store the message |
* |
* @var string |
* @access private |
*/ |
var $_error; |
/** |
* Flag to determine whether to include bodies in the |
* returned object. |
* |
* @var boolean |
* @access private |
*/ |
var $_include_bodies; |
/** |
* Flag to determine whether to decode bodies |
* |
* @var boolean |
* @access private |
*/ |
var $_decode_bodies; |
/** |
* Flag to determine whether to decode headers |
* |
* @var boolean |
* @access private |
*/ |
var $_decode_headers; |
/** |
* Flag to determine whether to include attached messages |
* as body in the returned object. Depends on $_include_bodies |
* |
* @var boolean |
* @access private |
*/ |
var $_rfc822_bodies; |
/** |
* Constructor. |
* |
* Sets up the object, initialise the variables, and splits and |
* stores the header and body of the input. |
* |
* @param string The input to decode |
* @access public |
*/ |
function Mail_mimeDecode($input) |
{ |
list($header, $body) = $this->_splitBodyHeader($input); |
$this->_input = $input; |
$this->_header = $header; |
$this->_body = $body; |
$this->_decode_bodies = false; |
$this->_include_bodies = true; |
$this->_rfc822_bodies = false; |
} |
/** |
* Begins the decoding process. If called statically |
* it will create an object and call the decode() method |
* of it. |
* |
* @param array An array of various parameters that determine |
* various things: |
* include_bodies - Whether to include the body in the returned |
* object. |
* decode_bodies - Whether to decode the bodies |
* of the parts. (Transfer encoding) |
* decode_headers - Whether to decode headers |
* input - If called statically, this will be treated |
* as the input |
* @return object Decoded results |
* @access public |
*/ |
function decode($params = null) |
{ |
// determine if this method has been called statically |
$isStatic = empty($this) || !is_a($this, __CLASS__); |
// Have we been called statically? |
// If so, create an object and pass details to that. |
if ($isStatic AND isset($params['input'])) { |
$obj = new Mail_mimeDecode($params['input']); |
$structure = $obj->decode($params); |
// Called statically but no input |
} elseif ($isStatic) { |
return PEAR::raiseError('Called statically and no input given'); |
// Called via an object |
} else { |
$this->_include_bodies = isset($params['include_bodies']) ? |
$params['include_bodies'] : false; |
$this->_decode_bodies = isset($params['decode_bodies']) ? |
$params['decode_bodies'] : false; |
$this->_decode_headers = isset($params['decode_headers']) ? |
$params['decode_headers'] : false; |
$this->_rfc822_bodies = isset($params['rfc_822bodies']) ? |
$params['rfc_822bodies'] : false; |
$structure = $this->_decode($this->_header, $this->_body); |
if ($structure === false) { |
$structure = $this->raiseError($this->_error); |
} |
} |
return $structure; |
} |
/** |
* Performs the decoding. Decodes the body string passed to it |
* If it finds certain content-types it will call itself in a |
* recursive fashion |
* |
* @param string Header section |
* @param string Body section |
* @return object Results of decoding process |
* @access private |
*/ |
function _decode($headers, $body, $default_ctype = 'text/plain') |
{ |
$return = new stdClass; |
$return->headers = array(); |
$headers = $this->_parseHeaders($headers); |
foreach ($headers as $value) { |
$value['value'] = $this->_decode_headers ? $this->_decodeHeader($value['value']) : $value['value']; |
if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) { |
$return->headers[strtolower($value['name'])] = array($return->headers[strtolower($value['name'])]); |
$return->headers[strtolower($value['name'])][] = $value['value']; |
} elseif (isset($return->headers[strtolower($value['name'])])) { |
$return->headers[strtolower($value['name'])][] = $value['value']; |
} else { |
$return->headers[strtolower($value['name'])] = $value['value']; |
} |
} |
foreach ($headers as $key => $value) { |
$headers[$key]['name'] = strtolower($headers[$key]['name']); |
switch ($headers[$key]['name']) { |
case 'content-type': |
$content_type = $this->_parseHeaderValue($headers[$key]['value']); |
if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) { |
$return->ctype_primary = $regs[1]; |
$return->ctype_secondary = $regs[2]; |
} |
if (isset($content_type['other'])) { |
foreach($content_type['other'] as $p_name => $p_value) { |
$return->ctype_parameters[$p_name] = $p_value; |
} |
} |
break; |
case 'content-disposition': |
$content_disposition = $this->_parseHeaderValue($headers[$key]['value']); |
$return->disposition = $content_disposition['value']; |
if (isset($content_disposition['other'])) { |
foreach($content_disposition['other'] as $p_name => $p_value) { |
$return->d_parameters[$p_name] = $p_value; |
} |
} |
break; |
case 'content-transfer-encoding': |
$content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']); |
break; |
} |
} |
if (isset($content_type)) { |
switch (strtolower($content_type['value'])) { |
case 'text/plain': |
$encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; |
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; |
break; |
case 'text/html': |
$encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; |
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; |
break; |
case 'multipart/parallel': |
case 'multipart/appledouble': // Appledouble mail |
case 'multipart/report': // RFC1892 |
case 'multipart/signed': // PGP |
case 'multipart/digest': |
case 'multipart/alternative': |
case 'multipart/related': |
case 'multipart/mixed': |
case 'application/vnd.wap.multipart.related': |
if(!isset($content_type['other']['boundary'])){ |
$this->_error = 'No boundary found for ' . $content_type['value'] . ' part'; |
return false; |
} |
$default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain'; |
$parts = $this->_boundarySplit($body, $content_type['other']['boundary']); |
for ($i = 0; $i < count($parts); $i++) { |
list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]); |
$part = $this->_decode($part_header, $part_body, $default_ctype); |
if($part === false) |
$part = $this->raiseError($this->_error); |
$return->parts[] = $part; |
} |
break; |
case 'message/rfc822': |
if ($this->_rfc822_bodies) { |
$encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; |
$return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body); |
} |
$obj = new Mail_mimeDecode($body); |
$return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies, |
'decode_bodies' => $this->_decode_bodies, |
'decode_headers' => $this->_decode_headers)); |
unset($obj); |
break; |
default: |
if(!isset($content_transfer_encoding['value'])) |
$content_transfer_encoding['value'] = '7bit'; |
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null; |
break; |
} |
} else { |
$ctype = explode('/', $default_ctype); |
$return->ctype_primary = $ctype[0]; |
$return->ctype_secondary = $ctype[1]; |
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null; |
} |
return $return; |
} |
/** |
* Given the output of the above function, this will return an |
* array of references to the parts, indexed by mime number. |
* |
* @param object $structure The structure to go through |
* @param string $mime_number Internal use only. |
* @return array Mime numbers |
*/ |
function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '') |
{ |
$return = array(); |
if (!empty($structure->parts)) { |
if ($mime_number != '') { |
$structure->mime_id = $prepend . $mime_number; |
$return[$prepend . $mime_number] = &$structure; |
} |
for ($i = 0; $i < count($structure->parts); $i++) { |
if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') { |
$prepend = $prepend . $mime_number . '.'; |
$_mime_number = ''; |
} else { |
$_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1)); |
} |
$arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend); |
foreach ($arr as $key => $val) { |
$no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key]; |
} |
} |
} else { |
if ($mime_number == '') { |
$mime_number = '1'; |
} |
$structure->mime_id = $prepend . $mime_number; |
$no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure; |
} |
return $return; |
} |
/** |
* Given a string containing a header and body |
* section, this function will split them (at the first |
* blank line) and return them. |
* |
* @param string Input to split apart |
* @return array Contains header and body section |
* @access private |
*/ |
function _splitBodyHeader($input) |
{ |
if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) { |
return array($match[1], $match[2]); |
} |
// bug #17325 - empty bodies are allowed. - we just check that at least one line |
// of headers exist.. |
if (count(explode("\n",$input))) { |
return array($input, ''); |
} |
$this->_error = 'Could not split header and body'; |
return false; |
} |
/** |
* Parse headers given in $input and return |
* as assoc array. |
* |
* @param string Headers to parse |
* @return array Contains parsed headers |
* @access private |
*/ |
function _parseHeaders($input) |
{ |
if ($input !== '') { |
// Unfold the input |
$input = preg_replace("/\r?\n/", "\r\n", $input); |
//#7065 - wrapping.. with encoded stuff.. - probably not needed, |
// wrapping space should only get removed if the trailing item on previous line is a |
// encoded character |
$input = preg_replace("/=\r\n(\t| )+/", '=', $input); |
$input = preg_replace("/\r\n(\t| )+/", ' ', $input); |
$headers = explode("\r\n", trim($input)); |
foreach ($headers as $value) { |
$hdr_name = substr($value, 0, $pos = strpos($value, ':')); |
$hdr_value = substr($value, $pos+1); |
if($hdr_value[0] == ' ') |
$hdr_value = substr($hdr_value, 1); |
$return[] = array( |
'name' => $hdr_name, |
'value' => $hdr_value |
); |
} |
} else { |
$return = array(); |
} |
return $return; |
} |
/** |
* Function to parse a header value, |
* extract first part, and any secondary |
* parts (after ;) This function is not as |
* robust as it could be. Eg. header comments |
* in the wrong place will probably break it. |
* |
* @param string Header value to parse |
* @return array Contains parsed result |
* @access private |
*/ |
function _parseHeaderValue($input) |
{ |
if (($pos = strpos($input, ';')) === false) { |
$input = $this->_decode_headers ? $this->_decodeHeader($input) : $input; |
$return['value'] = trim($input); |
return $return; |
} |
$value = substr($input, 0, $pos); |
$value = $this->_decode_headers ? $this->_decodeHeader($value) : $value; |
$return['value'] = trim($value); |
$input = trim(substr($input, $pos+1)); |
if (!strlen($input) > 0) { |
return $return; |
} |
// at this point input contains xxxx=".....";zzzz="...." |
// since we are dealing with quoted strings, we need to handle this properly.. |
$i = 0; |
$l = strlen($input); |
$key = ''; |
$val = false; // our string - including quotes.. |
$q = false; // in quote.. |
$lq = ''; // last quote.. |
while ($i < $l) { |
$c = $input[$i]; |
//var_dump(array('i'=>$i,'c'=>$c,'q'=>$q, 'lq'=>$lq, 'key'=>$key, 'val' =>$val)); |
$escaped = false; |
if ($c == '\\') { |
$i++; |
if ($i == $l-1) { // end of string. |
break; |
} |
$escaped = true; |
$c = $input[$i]; |
} |
// state - in key.. |
if ($val === false) { |
if (!$escaped && $c == '=') { |
$val = ''; |
$key = trim($key); |
$i++; |
continue; |
} |
if (!$escaped && $c == ';') { |
if ($key) { // a key without a value.. |
$key= trim($key); |
$return['other'][$key] = ''; |
$return['other'][strtolower($key)] = ''; |
} |
$key = ''; |
} |
$key .= $c; |
$i++; |
continue; |
} |
// state - in value.. (as $val is set..) |
if ($q === false) { |
// not in quote yet. |
if ((!strlen($val) || $lq !== false) && $c == ' ' || $c == "\t") { |
$i++; |
continue; // skip leading spaces after '=' or after '"' |
} |
if (!$escaped && ($c == '"' || $c == "'")) { |
// start quoted area.. |
$q = $c; |
// in theory should not happen raw text in value part.. |
// but we will handle it as a merged part of the string.. |
$val = !strlen(trim($val)) ? '' : trim($val); |
$i++; |
continue; |
} |
// got end.... |
if (!$escaped && $c == ';') { |
$val = trim($val); |
$added = false; |
if (preg_match('/\*[0-9]+$/', $key)) { |
// this is the extended aaa*0=...;aaa*1=.... code |
// it assumes the pieces arrive in order, and are valid... |
$key = preg_replace('/\*[0-9]+$/', '', $key); |
if (isset($return['other'][$key])) { |
$return['other'][$key] .= $val; |
if (strtolower($key) != $key) { |
$return['other'][strtolower($key)] .= $val; |
} |
$added = true; |
} |
// continue and use standard setters.. |
} |
if (!$added) { |
$return['other'][$key] = $val; |
$return['other'][strtolower($key)] = $val; |
} |
$val = false; |
$key = ''; |
$lq = false; |
$i++; |
continue; |
} |
$val .= $c; |
$i++; |
continue; |
} |
// state - in quote.. |
if (!$escaped && $c == $q) { // potential exit state.. |
// end of quoted string.. |
$lq = $q; |
$q = false; |
$i++; |
continue; |
} |
// normal char inside of quoted string.. |
$val.= $c; |
$i++; |
} |
// do we have anything left.. |
if (strlen(trim($key)) || $val !== false) { |
$val = trim($val); |
$added = false; |
if ($val !== false && preg_match('/\*[0-9]+$/', $key)) { |
// no dupes due to our crazy regexp. |
$key = preg_replace('/\*[0-9]+$/', '', $key); |
if (isset($return['other'][$key])) { |
$return['other'][$key] .= $val; |
if (strtolower($key) != $key) { |
$return['other'][strtolower($key)] .= $val; |
} |
$added = true; |
} |
// continue and use standard setters.. |
} |
if (!$added) { |
$return['other'][$key] = $val; |
$return['other'][strtolower($key)] = $val; |
} |
} |
// decode values. |
foreach($return['other'] as $key =>$val) { |
$return['other'][$key] = $this->_decode_headers ? $this->_decodeHeader($val) : $val; |
} |
//print_r($return); |
return $return; |
} |
/** |
* This function splits the input based |
* on the given boundary |
* |
* @param string Input to parse |
* @return array Contains array of resulting mime parts |
* @access private |
*/ |
function _boundarySplit($input, $boundary) |
{ |
$parts = array(); |
$bs_possible = substr($boundary, 2, -2); |
$bs_check = '\"' . $bs_possible . '\"'; |
if ($boundary == $bs_check) { |
$boundary = $bs_possible; |
} |
$tmp = preg_split("/--".preg_quote($boundary, '/')."((?=\s)|--)/", $input); |
$len = count($tmp) -1; |
for ($i = 1; $i < $len; $i++) { |
if (strlen(trim($tmp[$i]))) { |
$parts[] = $tmp[$i]; |
} |
} |
// add the last part on if it does not end with the 'closing indicator' |
if (!empty($tmp[$len]) && strlen(trim($tmp[$len])) && $tmp[$len][0] != '-') { |
$parts[] = $tmp[$len]; |
} |
return $parts; |
} |
/** |
* Given a header, this function will decode it |
* according to RFC2047. Probably not *exactly* |
* conformant, but it does pass all the given |
* examples (in RFC2047). |
* |
* @param string Input header value to decode |
* @return string Decoded header value |
* @access private |
*/ |
function _decodeHeader($input) |
{ |
// Remove white space between encoded-words |
$input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); |
// For each encoded-word... |
while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { |
$encoded = $matches[1]; |
$charset = $matches[2]; |
$encoding = $matches[3]; |
$text = $matches[4]; |
switch (strtolower($encoding)) { |
case 'b': |
$text = base64_decode($text); |
break; |
case 'q': |
$text = str_replace('_', ' ', $text); |
preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); |
foreach($matches[1] as $value) |
$text = str_replace('='.$value, chr(hexdec($value)), $text); |
break; |
} |
$input = str_replace($encoded, $text, $input); |
} |
return $input; |
} |
/** |
* Given a body string and an encoding type, |
* this function will decode and return it. |
* |
* @param string Input body to decode |
* @param string Encoding type to use. |
* @return string Decoded body |
* @access private |
*/ |
function _decodeBody($input, $encoding = '7bit') |
{ |
switch (strtolower($encoding)) { |
case '7bit': |
return $input; |
break; |
case 'quoted-printable': |
return $this->_quotedPrintableDecode($input); |
break; |
case 'base64': |
return base64_decode($input); |
break; |
default: |
return $input; |
} |
} |
/** |
* Given a quoted-printable string, this |
* function will decode and return it. |
* |
* @param string Input body to decode |
* @return string Decoded body |
* @access private |
*/ |
function _quotedPrintableDecode($input) |
{ |
// Remove soft line breaks |
$input = preg_replace("/=\r?\n/", '', $input); |
// Replace encoded characters |
$input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input); |
return $input; |
} |
/** |
* Checks the input for uuencoded files and returns |
* an array of them. Can be called statically, eg: |
* |
* $files =& Mail_mimeDecode::uudecode($some_text); |
* |
* It will check for the begin 666 ... end syntax |
* however and won't just blindly decode whatever you |
* pass it. |
* |
* @param string Input body to look for attahcments in |
* @return array Decoded bodies, filenames and permissions |
* @access public |
* @author Unknown |
*/ |
function &uudecode($input) |
{ |
// Find all uuencoded sections |
preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches); |
for ($j = 0; $j < count($matches[3]); $j++) { |
$str = $matches[3][$j]; |
$filename = $matches[2][$j]; |
$fileperm = $matches[1][$j]; |
$file = ''; |
$str = preg_split("/\r?\n/", trim($str)); |
$strlen = count($str); |
for ($i = 0; $i < $strlen; $i++) { |
$pos = 1; |
$d = 0; |
$len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077); |
while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) { |
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); |
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); |
$c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); |
$c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20); |
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); |
$file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); |
$file .= chr(((($c2 - ' ') & 077) << 6) | (($c3 - ' ') & 077)); |
$pos += 4; |
$d += 3; |
} |
if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) { |
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); |
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); |
$c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); |
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); |
$file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); |
$pos += 3; |
$d += 2; |
} |
if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) { |
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); |
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); |
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); |
} |
} |
$files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file); |
} |
return $files; |
} |
/** |
* getSendArray() returns the arguments required for Mail::send() |
* used to build the arguments for a mail::send() call |
* |
* Usage: |
* $mailtext = Full email (for example generated by a template) |
* $decoder = new Mail_mimeDecode($mailtext); |
* $parts = $decoder->getSendArray(); |
* if (!PEAR::isError($parts) { |
* list($recipents,$headers,$body) = $parts; |
* $mail = Mail::factory('smtp'); |
* $mail->send($recipents,$headers,$body); |
* } else { |
* echo $parts->message; |
* } |
* @return mixed array of recipeint, headers,body or Pear_Error |
* @access public |
* @author Alan Knowles <alan@akbkhome.com> |
*/ |
function getSendArray() |
{ |
// prevent warning if this is not set |
$this->_decode_headers = FALSE; |
$headerlist =$this->_parseHeaders($this->_header); |
$to = ""; |
if (!$headerlist) { |
return $this->raiseError("Message did not contain headers"); |
} |
foreach($headerlist as $item) { |
$header[$item['name']] = $item['value']; |
switch (strtolower($item['name'])) { |
case "to": |
case "cc": |
case "bcc": |
$to .= ",".$item['value']; |
default: |
break; |
} |
} |
if ($to == "") { |
return $this->raiseError("Message did not contain any recipents"); |
} |
$to = substr($to,1); |
return array($to,$header,$this->_body); |
} |
/** |
* Returns a xml copy of the output of |
* Mail_mimeDecode::decode. Pass the output in as the |
* argument. This function can be called statically. Eg: |
* |
* $output = $obj->decode(); |
* $xml = Mail_mimeDecode::getXML($output); |
* |
* The DTD used for this should have been in the package. Or |
* alternatively you can get it from cvs, or here: |
* http://www.phpguru.org/xmail/xmail.dtd. |
* |
* @param object Input to convert to xml. This should be the |
* output of the Mail_mimeDecode::decode function |
* @return string XML version of input |
* @access public |
*/ |
function getXML($input) |
{ |
$crlf = "\r\n"; |
$output = '<?xml version=\'1.0\'?>' . $crlf . |
'<!DOCTYPE email SYSTEM "http://www.phpguru.org/xmail/xmail.dtd">' . $crlf . |
'<email>' . $crlf . |
Mail_mimeDecode::_getXML($input) . |
'</email>'; |
return $output; |
} |
/** |
* Function that does the actual conversion to xml. Does a single |
* mimepart at a time. |
* |
* @param object Input to convert to xml. This is a mimepart object. |
* It may or may not contain subparts. |
* @param integer Number of tabs to indent |
* @return string XML version of input |
* @access private |
*/ |
function _getXML($input, $indent = 1) |
{ |
$htab = "\t"; |
$crlf = "\r\n"; |
$output = ''; |
$headers = @(array)$input->headers; |
foreach ($headers as $hdr_name => $hdr_value) { |
// Multiple headers with this name |
if (is_array($headers[$hdr_name])) { |
for ($i = 0; $i < count($hdr_value); $i++) { |
$output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent); |
} |
// Only one header of this sort |
} else { |
$output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent); |
} |
} |
if (!empty($input->parts)) { |
for ($i = 0; $i < count($input->parts); $i++) { |
$output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf . |
Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) . |
str_repeat($htab, $indent) . '</mimepart>' . $crlf; |
} |
} elseif (isset($input->body)) { |
$output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' . |
$input->body . ']]></body>' . $crlf; |
} |
return $output; |
} |
/** |
* Helper function to _getXML(). Returns xml of a header. |
* |
* @param string Name of header |
* @param string Value of header |
* @param integer Number of tabs to indent |
* @return string XML version of input |
* @access private |
*/ |
function _getXML_helper($hdr_name, $hdr_value, $indent) |
{ |
$htab = "\t"; |
$crlf = "\r\n"; |
$return = ''; |
$new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value); |
$new_hdr_name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name))); |
// Sort out any parameters |
if (!empty($new_hdr_value['other'])) { |
foreach ($new_hdr_value['other'] as $paramname => $paramvalue) { |
$params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf . |
str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf . |
str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf . |
str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf; |
} |
$params = implode('', $params); |
} else { |
$params = ''; |
} |
$return = str_repeat($htab, $indent) . '<header>' . $crlf . |
str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf . |
str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf . |
$params . |
str_repeat($htab, $indent) . '</header>' . $crlf; |
return $return; |
} |
} // End of class |
/branches/v1.6-croc/jrest/lib/ImageRecreation.php |
---|
New file |
0,0 → 1,639 |
<?php |
Class ImageRecreation { |
private $droits = 0705; |
private $formats = array('CRX2S','CXS','CS','CRS','XS','S','M','L','XL','X2L','X3L'); |
const MODE_GD = 'gd'; |
const MODE_IMAGEMAGICK = 'imagemagick'; |
private $mode; |
private $verbose = true; |
public function __construct($config) { |
$this->config = $config; |
if (extension_loaded('imagick')) { |
$this->mode = self::MODE_IMAGEMAGICK; |
} else { |
$this->mode = self::MODE_GD; |
} |
} |
public function recreerMiniaturesRecursivement() { |
$this->itererRecursivement($this->config['cel']['chemin_images']); |
} |
public function regenererMiniaturesIntervalle($params) { |
$id_debut = $params[0]; |
$id_fin = $params[1]; |
if (is_numeric($id_debut) && is_numeric($id_fin)) { |
for ($i = $id_debut; $i <= $id_fin; $i++) {; |
$tab_param = array($i); |
$this->regenererMiniaturesPourId($tab_param); |
} |
} |
} |
public function regenererMiniaturesPourId($params) { |
$id = $params[0]; |
if (!is_numeric($id)) { |
return; |
} |
$dossier_fichier = $this->obtenirDossierPourFormat($id, 'O'); |
$nom_fichier = $this->convertirIdBddVersNomFichier($id, 'O'); |
$chemin_fichier = $dossier_fichier.'/'.$nom_fichier; |
if (file_exists($chemin_fichier)) { |
$infos_image_originale = $this->obtenirImageEtInfosPourChemin($chemin_fichier); |
// creation de miniatures pour chacuns des formats définis |
foreach ($this->formats as $format) { |
$this->creerEtStockerMiniatureFichierImageSelonFormat($id, $infos_image_originale, $format); |
}; |
} |
} |
public function itererRecursivement($dossier) { |
// on ne parse que le dossier des images originales |
$dossiers_a_exclure = $this->getFormats(); |
foreach (new DirectoryIterator($dossier) as $fichier_ou_dossier) { |
if ($fichier_ou_dossier->isDot()) { |
continue; |
} |
if (in_array($fichier_ou_dossier->getBasename(), $dossiers_a_exclure)) { |
continue; |
} |
if ($fichier_ou_dossier->isDir()) { |
$this->itererRecursivement($fichier_ou_dossier->getPathname()); |
} else { |
$nom_fichier = $fichier_ou_dossier->getFilename(); |
$infos_image_originale = $this->obtenirImageEtInfosPourChemin($fichier_ou_dossier->getPathname()); |
$id = $this->convertirBaseNomFichierVersIdBdd($nom_fichier, $this->formats); |
// creation de miniatures pour chacuns des formats définis |
foreach ($this->formats as $format) { |
$this->creerEtStockerMiniatureFichierImageSelonFormat($id, $infos_image_originale, $format); |
} |
} |
} |
} |
public function creerMiniatureImageSelonFormat($infos_image_originale, $format = 'O') { |
if ($format == 'O') { |
// format original : rien à faire |
$image_redimensionnee = $infos_image_originale['image']; |
} else { |
if ($this->estUnFormatRogne($format)) { |
if ($this->mode == self::MODE_IMAGEMAGICK) { |
// si l'on dispose de la librairie imageMagick |
// on applique l'algorithme d'auto détection de sujets |
// qui centre la miniature sur le sujet de l'image |
$image_redimensionnee = $this->opticrop($infos_image_originale, $format); |
} else { |
// si l'on ne dispose que de gd |
// la minature est une image redimensionnée rognée au centre |
$image_redimensionnee = $this->creerMiniatureCarreeRognee($infos_image_originale, $format); |
} |
} else if ($this->estUnFormatCarre($format)) { |
// le format carre et une image redimensionnée en gardant son ratio, insérée dans un carré blanc |
$image_redimensionnee = $this->creerMiniatureCarree($infos_image_originale, $format); |
} else { |
$image_redimensionnee = $this->creerMiniature($infos_image_originale, $format); |
} |
} |
return $image_redimensionnee; |
} |
public function creerEtStockerMiniatureFichierImageSelonFormat($id ,$infos_image_originale, $format = 'O') { |
$image_redimensionnee = $this->creerMiniatureImageSelonFormat($infos_image_originale, $format); |
$taux_compression = $this->renvoyerTauxCompressionPourPoids($infos_image_originale['poids_octets']); |
$this->ecrireImageSurDisque($image_redimensionnee, $id, $format, $taux_compression); |
return true; |
} |
public function creerImageRedimensionnee($infos_image_originale, $hauteur_redimension, $largeur_redimension) { |
$image_redimensionnee = imagecreatetruecolor($largeur_redimension, $hauteur_redimension); |
imagecopyresampled($image_redimensionnee, |
$infos_image_originale['image'], |
0, 0, |
0, 0, |
$largeur_redimension, |
$hauteur_redimension, |
$infos_image_originale['largeur'], |
$infos_image_originale['hauteur'] |
); |
return $image_redimensionnee; |
} |
public function creerMiniature($informations_images, $format) { |
$taille_reference_pour_format = $this->obtenirDimensionsPourFormat($format); |
$taille_image_redimensionnee = $this->calculerTailleImage($informations_images, $taille_reference_pour_format['hauteur']); |
$image_redimensionnee = $this->creerImageRedimensionnee($informations_images, $taille_image_redimensionnee['hauteur'], $taille_image_redimensionnee['largeur']); |
return $image_redimensionnee; |
} |
public function creerMiniatureCarree($informations_image, $format) { |
$taille_reference_pour_format = $this->obtenirDimensionsPourFormat($format); |
$cote_carre = $taille_reference_pour_format['largeur']; |
$image_redimensionnee_avec_rapport = $this->creerMiniature($informations_image, $format); |
$taille_redimensionnee_avec_rapport = $this->calculerTailleImage($informations_image, $taille_reference_pour_format['hauteur']); |
if ($this->estPaysage($informations_image)) { |
$debut_largeur_a_copier = 0 ; |
$debut_hauteur_a_copier = ($cote_carre - $taille_redimensionnee_avec_rapport['hauteur'])/2 ; |
} else { |
$debut_largeur_a_copier = ($cote_carre - $taille_redimensionnee_avec_rapport['largeur'])/2 ; |
$debut_hauteur_a_copier = 0 ; |
} |
$image_carre_blanc_cible = $this->renvoyerEtCreerImageCarreeBlancheSelonFormat($cote_carre); |
imagecopy($image_carre_blanc_cible, $image_redimensionnee_avec_rapport, |
$debut_largeur_a_copier ,$debut_hauteur_a_copier, 0, 0, |
$taille_redimensionnee_avec_rapport['largeur'], $taille_redimensionnee_avec_rapport['hauteur'] |
); |
return $image_carre_blanc_cible; |
} |
public function creerMiniatureCarreeRognee($informations_image, $format) { |
$taille_reference_pour_format = $this->obtenirDimensionsPourFormat($format); |
$cote_carre = $taille_reference_pour_format['largeur']; |
$cote_carre_non_redimensionne = 0; |
if ($this->estPaysage($informations_image)) { |
$cote_carre_non_redimensionne = $informations_image['hauteur']; |
$debut_largeur_a_copier = ($informations_image['hauteur'] - $cote_carre)/2 ; |
$debut_hauteur_a_copier = 0; |
if($debut_largeur_a_copier <= 0) { |
$debut_largeur_a_copier = 0; |
} |
$nb_pixels_largeur_a_copier = $cote_carre_non_redimensionne; |
$nb_pixels_hauteur_a_copier = $cote_carre_non_redimensionne; |
} else { |
$cote_carre_non_redimensionne = $informations_image['largeur']; |
$debut_largeur_a_copier = 0 ; |
$debut_hauteur_a_copier = ($informations_image['largeur'] - $cote_carre)/2; |
if($debut_hauteur_a_copier <= 0) { |
$debut_hauteur_a_copier = 0; |
} |
$nb_pixels_largeur_a_copier = $cote_carre_non_redimensionne; |
$nb_pixels_hauteur_a_copier = $cote_carre_non_redimensionne; |
} |
$image_carre_temporaire = imagecreatetruecolor($cote_carre_non_redimensionne, $cote_carre_non_redimensionne); |
imagecopyresampled($image_carre_temporaire, |
$informations_image['image'], |
0, 0, |
$debut_largeur_a_copier, |
$debut_hauteur_a_copier, |
$cote_carre_non_redimensionne, |
$cote_carre_non_redimensionne, |
$nb_pixels_largeur_a_copier, |
$nb_pixels_hauteur_a_copier |
); |
$image_redimensionnee = imagecreatetruecolor($cote_carre, $cote_carre); |
imagecopyresampled($image_redimensionnee, |
$image_carre_temporaire, |
0, 0, |
0, 0, |
$cote_carre, |
$cote_carre, |
$cote_carre_non_redimensionne, |
$cote_carre_non_redimensionne |
); |
return $image_redimensionnee; |
} |
public function stockerFichierEtCreerMiniatures($fichier, $id) { |
$chemin_fichier_origine = is_array($fichier) ? $fichier['tmp_name'] : $fichier; |
$chemin_base_fichier = $this->creerSiNecessaireEtRenvoyerCheminStockageFichierPourIdEtFormat($id, 'O'); |
$nom_fichier = $this->convertirIdBddVersNomFichier($id, 'O'); |
$chemin_fichier = $chemin_base_fichier.'/'.$nom_fichier; |
$deplacement_fichier = $this->stockerImageExterne($chemin_fichier_origine, $chemin_fichier); |
if ($deplacement_fichier) { |
$infos_image_originale = $this->obtenirImageEtInfosPourChemin($chemin_fichier); |
$taux_compression = $this->renvoyerTauxCompressionPourPoids($infos_image_originale['poids_octets']); |
if ($taux_compression < 100 && $this->mode == self::MODE_IMAGEMAGICK) { |
$this->ecrireImageSurDisqueAvecMeta($chemin_fichier, $taux_compression); |
} |
$infos_image_originale_stockee = $this->obtenirImageEtInfosPourChemin($chemin_fichier); |
$formats = $this->getFormats(); |
// creation de miniatures pour chacuns des formats définis |
foreach($formats as $format) { |
$this->creerEtStockerMiniatureFichierImageSelonFormat($id, $infos_image_originale_stockee, $format); |
} |
return true ; |
} else { |
$erreur = 'ERROR : probleme durant le déplacement du fichier temporaire \n' ; |
$this->logger('CEL_bugs',$erreur); |
return false ; |
} |
} |
public function stockerImageExterne($chemin_fichier_temp, $chemin_destination) { |
if (is_uploaded_file($chemin_fichier_temp)) { |
$deplacement = move_uploaded_file($chemin_fichier_temp, $chemin_destination); |
} else { |
$deplacement = rename($chemin_fichier_temp, $chemin_destination); |
} |
return $deplacement; |
} |
public function creerSiNecessaireEtRenvoyerCheminStockageFichierPourIdEtFormat($id, $format) { |
$chemin_sur_serveur_final = $this->obtenirDossierPourFormat($id, $format); |
if (!file_exists($chemin_sur_serveur_final)) { |
umask(0); |
if (!mkdir($chemin_sur_serveur_final, $this->droits, true)) { |
$erreur = 'ERROR : probleme durant l\'écriture du dossier '.$format.' \n' ; |
$this->logger('CEL_bugs', $erreur); |
return false; |
} |
} |
return $chemin_sur_serveur_final; |
} |
public function obtenirDossierPourFormat($id, $format) { |
$chemin_base = $this->config['cel']['chemin_images']; |
$chemin_sur_serveur = $chemin_base; |
$id = sprintf('%09s', $id); |
$id = wordwrap($id, 3 , '_', true); |
list($dossierNiveau1, $dossierNiveau2) = explode('_', $id); |
$chemin_sur_serveur_final = $chemin_sur_serveur.'/'.$dossierNiveau1.'/'.$dossierNiveau2.'/'.$format; |
return $chemin_sur_serveur_final; |
} |
public function obtenirCheminImageOriginale($id_image) { |
$nom = $this->convertirIdBddVersNomFichier($id_image, 'O'); |
$dossier = $this->obtenirDossierPourFormat($id_image,'O'); |
return $dossier.'/'.$nom; |
} |
public function obtenirImageEtInfosPourId($id_image) { |
$chemin_image_o = $this->obtenirCheminImageOriginale($id_image); |
return $this->obtenirImageEtInfosPourChemin($chemin_image_o); |
} |
public function obtenirImageEtInfosPourChemin($chemin_fichier) { |
$image_et_infos = false; |
if (file_exists($chemin_fichier)) { |
$image_et_infos = array(); |
list($image_et_infos['largeur'], $image_et_infos['hauteur']) = getimagesize($chemin_fichier); |
$image_et_infos['poids_octets'] = filesize($chemin_fichier); |
$image_et_infos['image'] = imagecreatefromjpeg($chemin_fichier); |
$image_et_infos['chemin'] = $chemin_fichier; |
} |
return $image_et_infos; |
} |
public function obtenirDimensionsPourFormat($format) { |
$dimensions = array('largeur' => 0, 'hauteur' => 0); |
if (isset($this->config['cel']['format_'.$format])) { |
list($dimensions['largeur'], $dimensions['hauteur']) = explode('_', $this->config['cel']['format_'.$format]); |
} |
return $dimensions; |
} |
public function calculerTailleImage($informations_images, $taille_max) { |
$HL_redimension = array(); |
if ($this->estPaysage($informations_images)) { |
$rapport = $informations_images['hauteur']/$informations_images['largeur'] ; |
$HL_redimension['largeur'] = round($taille_max) ; |
$HL_redimension['hauteur'] = round($taille_max*$rapport) ; |
} else { |
$rapport = $informations_images['largeur']/$informations_images['hauteur'] ; |
$HL_redimension['hauteur'] = round($taille_max) ; |
$HL_redimension['largeur'] = round($taille_max*$rapport) ; |
} |
return $HL_redimension; |
} |
public function getFormats() { |
return $this->formats; |
} |
public function estUnFormatCarre($format) { |
return (strpos($format,'C') === 0); |
} |
public function estUnFormatRogne($format) { |
return (strpos($format,'R') === 1); |
} |
public function estPaysage($informations_images) { |
return $informations_images['largeur'] > $informations_images['hauteur']; |
} |
public function estPortait($informations_images) { |
return $informations_images['largeur'] < $informations_images['hauteur']; |
} |
public function renvoyerTauxCompressionPourPoids($poids_octets) { |
$poids_max_octets = $this->config['cel']['taille_max']; |
$ratio_compression = 100 ; |
if ($poids_octets >= $poids_max_octets) { |
$ratio_compression = 75 ; |
} |
return $ratio_compression; |
} |
public function convertirIdBddVersNomFichier($id, $format, $extension = 'jpg') { |
// creation du format original |
$id_avec_zeros = sprintf('%09s', $id) ; |
$id_avec_zeros_underscores = wordwrap($id_avec_zeros, 3 , '_', true) ; |
$nom_fichier = $id_avec_zeros_underscores.'_'.$format.'.'.$extension; |
return $nom_fichier; |
} |
public function convertirBaseNomFichierVersIdBdd($nom_fichier, $formats) { |
$nom_fichier_sans_extension = trim($nom_fichier, '.jpg'); |
foreach($formats as $format) { |
$nom_fichier_sans_extension = trim($nom_fichier_sans_extension, '_'.$format); |
} |
$id_image = str_replace('_', '', $nom_fichier_sans_extension); |
// suppression des 0 devant |
$id_image += 0; |
return $id_image; |
} |
public function ecrireImageSurDisque($image_binaire, $id, $format, $compression = 100) { |
umask(0); |
$chemin_sur_serveur_final = $this->creerSiNecessaireEtRenvoyerCheminStockageFichierPourIdEtFormat($id, $format); |
$nom_fichier = $this->convertirIdBddVersNomFichier($id, $format); |
if (file_exists($chemin_sur_serveur_final.'/'.$nom_fichier)) { |
unlink($chemin_sur_serveur_final.'/'.$nom_fichier); |
} |
// attention, ceci ne preserve pas les metadonnées |
imagejpeg($image_binaire, $chemin_sur_serveur_final.'/'.$nom_fichier, $compression); |
chmod($chemin_sur_serveur_final.'/'.$nom_fichier,$this->droits); |
} |
public function ecrireImageSurDisqueAvecMeta($chemin_image_a_stocker, $compression = 100) { |
$img = new Imagick($chemin_image_a_stocker); |
// l'utilisation d'image magick préserve les métadonnées lors d'une recompression |
$img->setformat("jpeg"); |
$img->setImageCompression(imagick::COMPRESSION_JPEG); |
$img->setCompressionQuality($compression); |
$img->writeImage($chemin_image_a_stocker); |
$img->destroy(); |
chmod($chemin_image_a_stocker, $this->droits); |
} |
public function renvoyerEtCreerImageCarreeBlancheSelonFormat($cote) { |
$image_blanche = imagecreatetruecolor($cote, $cote); |
$blanc = imagecolorallocate($image_blanche, 255, 255, 255); |
imagefilledrectangle($image_blanche, 0, 0, $cote, $cote, $blanc); |
return $image_blanche; |
} |
public function detruireImageEnMemoire($image) { |
imagedestroy($image); |
} |
public function detruireImageSurDisque($id) { |
$formats = $this->getFormats(); |
// on detruit aussi l'image originale |
$formats[] = 'O'; |
$destruction_formats_fichier = false; |
// destructions de chacuns des formats définis |
foreach($formats as $format) { |
$dossier_format = $this->obtenirDossierPourFormat($id, $format); |
$nom_fichier = $this->convertirIdBddVersNomFichier($id, $format); |
if (file_exists($dossier_format.'/'.$nom_fichier)) { |
$destruction_formats_fichier = unlink($dossier_format.'/'.$nom_fichier); |
} else { |
$destruction_formats_fichier = true; |
} |
} |
return $destruction_formats_fichier; |
} |
/* |
* edge-maximizing crop |
* determines center-of-edginess, then tries different-sized crops around it. |
* picks the crop with the highest normalized edginess. |
* see documentation on how to tune the algorithm |
* |
* $informations_image - le tableau d'informations sur l'image tel que renvoyé par la fonction obtenirImageEtInfosPourChemin |
* $format - le format (ex. : CS, XS, XL, CRS) |
*/ |
public function opticrop($informations_image, $format) { |
umask(0); |
$nom_temp = md5(time()); |
$chemin_temp = |
$out = $this->config['cel']['chemin_stockage_temp'].'/'.$nom_temp; |
$dimension_vignettes = $this->obtenirDimensionsPourFormat($format); |
$largeur_vignette = $dimension_vignettes['largeur']; |
$hauteur_vignette = $dimension_vignettes['hauteur']; |
// source dimensions |
$largeur_image_originale = $informations_image['largeur']; |
$hauteur_image_originale = $informations_image['hauteur']; |
$chemin_image = $informations_image['chemin']; |
//if ($largeur_vignette > $largeur_image_originale || $hauteur_vignette > $hauteur_image_originale) |
// die("Target dimensions must be smaller or equal to source dimensions."); |
// parameters for the edge-maximizing crop algorithm |
$r = 1; // radius of edge filter |
$nk = 9; // scale count: number of crop sizes to try |
$gamma = 0.2; // edge normalization parameter -- see documentation |
$ar = $largeur_vignette/$hauteur_vignette; // target aspect ratio (AR) |
$ar0 = $largeur_image_originale/$hauteur_image_originale; // original aspect ratio (AR) |
//echo("$chemin_image: $largeur_image_originale x $hauteur_image_originale => $largeur_vignette x $hauteur_vignette"); |
$img = new Imagick($chemin_image); |
$imgcp = clone $img; |
// compute center of edginess |
$img->edgeImage($r); |
$img->modulateImage(100,0,100); // grayscale |
$img->blackThresholdImage("#0f0f0f"); |
$img->writeImage($out); |
// use gd for random pixel access |
$im = ImageCreateFromJpeg($out); |
$xcenter = 0; |
$ycenter = 0; |
$sum = 0; |
$n = 100000; |
for ($k=0; $k<$n; $k++) { |
$i = mt_rand(0,$largeur_image_originale-1); |
$j = mt_rand(0,$hauteur_image_originale-1); |
$val = imagecolorat($im, $i, $j) & 0xFF; |
$sum += $val; |
$xcenter += ($i+1)*$val; |
$ycenter += ($j+1)*$val; |
} |
$xcenter /= $sum; |
$ycenter /= $sum; |
// crop source img to target AR |
if ($largeur_image_originale/$hauteur_image_originale > $ar) { |
// source AR wider than target |
// crop width to target AR |
$wcrop0 = round($ar*$hauteur_image_originale); |
$hcrop0 = $hauteur_image_originale; |
} else { |
// crop height to target AR |
$wcrop0 = $largeur_image_originale; |
$hcrop0 = round($largeur_image_originale/$ar); |
} |
// crop parameters for all scales and translations |
$params = array(); |
// crop at different scales |
$hgap = $hcrop0 - $hauteur_vignette; |
$hinc = ($nk == 1) ? 0 : $hgap / ($nk - 1); |
$wgap = $wcrop0 - $largeur_vignette; |
$winc = ($nk == 1) ? 0 : $wgap / ($nk - 1); |
// find window with highest normalized edginess |
$n = 10000; |
$maxbetanorm = 0; |
$maxfile = ''; |
$maxparam = array('w'=>0, 'h'=>0, 'x'=>0, 'y'=>0); |
for ($k = 0; $k < $nk; $k++) { |
$hcrop = round($hcrop0 - $k*$hinc); |
$wcrop = round($wcrop0 - $k*$winc); |
$xcrop = $xcenter - $wcrop / 2; |
$ycrop = $ycenter - $hcrop / 2; |
//echo("crop: $wcrop, $hcrop, $xcrop, $ycrop"); |
if ($xcrop < 0) $xcrop = 0; |
if ($xcrop+$wcrop > $largeur_image_originale) $xcrop = $largeur_image_originale-$wcrop; |
if ($ycrop < 0) $ycrop = 0; |
if ($ycrop+$hcrop > $hauteur_image_originale) $ycrop = $hauteur_image_originale-$hcrop; |
/*if (self::MODE_DEBUG) { |
// debug |
$currfile = '/home/aurelien/web/file_tmp/'."image$k.jpg"; |
$currimg = clone $img; |
$c= new ImagickDraw(); |
$c->setFillColor("red"); |
$c->circle($xcenter, $ycenter, $xcenter, $ycenter+4); |
$currimg->drawImage($c); |
$currimg->cropImage($wcrop, $hcrop, $xcrop, $ycrop); |
$currimg->writeImage($currfile); |
$currimg->destroy(); |
}*/ |
$beta = 0; |
for ($c=0; $c<$n; $c++) { |
$i = mt_rand(0,$wcrop-1); |
$j = mt_rand(0,$hcrop-1); |
$beta += imagecolorat($im, $xcrop+$i, $ycrop+$j) & 0xFF; |
} |
$area = $wcrop * $hcrop; |
$betanorm = $beta / ($n*pow($area, $gamma-1)); |
// echo("beta: $beta; betan: $betanorm"); |
// echo("image$k.jpg:<br/>\n<img src=\"$currfile\"/>"); |
// best image found, save it |
if ($betanorm > $maxbetanorm) { |
$maxbetanorm = $betanorm; |
$maxparam['w'] = $wcrop; |
$maxparam['h'] = $hcrop; |
$maxparam['x'] = $xcrop; |
$maxparam['y'] = $ycrop; |
// $maxfile = $currfile; |
} |
} |
// return image |
$imgcp->cropImage($maxparam['w'], $maxparam['h'], $maxparam['x'], $maxparam['y']); |
$imgcp->scaleImage($largeur_vignette, $hauteur_vignette); |
$imgcp->writeImage($out); |
chmod($out, 0777); |
$img->destroy(); |
$imgcp->destroy(); |
$image_sortie = ImageCreateFromJpeg($out); |
unlink($out); |
return $image_sortie; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/DB/mysql.php |
---|
New file |
0,0 → 1,916 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ |
// +----------------------------------------------------------------------+ |
// | 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. | |
// +----------------------------------------------------------------------+ |
// | Author: Stig Bakken <ssb@php.net> | |
// | Maintainer: Daniel Convissor <danielc@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id$ |
// XXX legend: |
// |
// XXX ERRORMSG: The error message from the mysql function should |
// be registered here. |
// |
// TODO/wishlist: |
// longReadlen |
// binmode |
require_once 'common.php'; |
/** |
* Database independent query interface definition for PHP's MySQL |
* extension. |
* |
* This is for MySQL versions 4.0 and below. |
* |
* @package DB |
* @version $Id$ |
* @category Database |
* @author Stig Bakken <ssb@php.net> |
*/ |
class DB_mysql extends DB_common |
{ |
// {{{ properties |
var $connection; |
var $phptype, $dbsyntax; |
var $prepare_tokens = array(); |
var $prepare_types = array(); |
var $num_rows = array(); |
var $transaction_opcount = 0; |
var $autocommit = true; |
var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */ |
var $_db = false; |
// }}} |
// {{{ constructor |
/** |
* DB_mysql constructor. |
* |
* @access public |
*/ |
function DB_mysql() |
{ |
$this->DB_common(); |
$this->phptype = 'mysql'; |
$this->dbsyntax = 'mysql'; |
$this->features = array( |
'prepare' => false, |
'pconnect' => true, |
'transactions' => true, |
'limit' => 'alter' |
); |
$this->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, |
1046 => DB_ERROR_NODBSELECTED, |
1048 => DB_ERROR_CONSTRAINT, |
1050 => DB_ERROR_ALREADY_EXISTS, |
1051 => DB_ERROR_NOSUCHTABLE, |
1054 => DB_ERROR_NOSUCHFIELD, |
1062 => DB_ERROR_ALREADY_EXISTS, |
1064 => DB_ERROR_SYNTAX, |
1100 => DB_ERROR_NOT_LOCKED, |
1136 => DB_ERROR_VALUE_COUNT_ON_ROW, |
1146 => DB_ERROR_NOSUCHTABLE, |
1216 => DB_ERROR_CONSTRAINT, |
1217 => DB_ERROR_CONSTRAINT, |
); |
} |
// }}} |
// {{{ connect() |
/** |
* Connect to a database and log in as the specified user. |
* |
* @param $dsn the data source name (see DB::parseDSN for syntax) |
* @param $persistent (optional) whether the connection should |
* be persistent |
* @access public |
* @return int DB_OK on success, a DB error on failure |
*/ |
function connect($dsninfo, $persistent = false) |
{ |
if (!DB::assertExtension('mysql')) { |
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); |
} |
$this->dsn = $dsninfo; |
if ($dsninfo['protocol'] && $dsninfo['protocol'] == 'unix') { |
$dbhost = ':' . $dsninfo['socket']; |
} else { |
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; |
if ($dsninfo['port']) { |
$dbhost .= ':' . $dsninfo['port']; |
} |
} |
$connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect'; |
if ($dbhost && $dsninfo['username'] && isset($dsninfo['password'])) { |
$conn = @$connect_function($dbhost, $dsninfo['username'], |
$dsninfo['password']); |
} elseif ($dbhost && $dsninfo['username']) { |
$conn = @$connect_function($dbhost, $dsninfo['username']); |
} elseif ($dbhost) { |
$conn = @$connect_function($dbhost); |
} else { |
$conn = false; |
} |
if (!$conn) { |
if (($err = @mysql_error()) != '') { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, |
null, $err); |
} elseif (empty($php_errormsg)) { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED); |
} else { |
return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, |
null, $php_errormsg); |
} |
} |
if ($dsninfo['database']) { |
if (!@mysql_select_db($dsninfo['database'], $conn)) { |
switch(mysql_errno($conn)) { |
case 1049: |
return $this->raiseError(DB_ERROR_NOSUCHDB, null, null, |
null, @mysql_error($conn)); |
case 1044: |
return $this->raiseError(DB_ERROR_ACCESS_VIOLATION, null, null, |
null, @mysql_error($conn)); |
default: |
return $this->raiseError(DB_ERROR, null, null, |
null, @mysql_error($conn)); |
} |
} |
// fix to allow calls to different databases in the same script |
$this->_db = $dsninfo['database']; |
} |
$this->connection = $conn; |
return DB_OK; |
} |
// }}} |
// {{{ disconnect() |
/** |
* Log out and disconnect from the database. |
* |
* @access public |
* |
* @return bool true on success, false if not connected. |
*/ |
function disconnect() |
{ |
$ret = @mysql_close($this->connection); |
$this->connection = null; |
return $ret; |
} |
// }}} |
// {{{ simpleQuery() |
/** |
* Send a query to MySQL and return the results as a MySQL resource |
* identifier. |
* |
* @param the SQL query |
* |
* @access public |
* |
* @return mixed returns a valid MySQL result for successful SELECT |
* queries, DB_OK for other successful queries. A DB error is |
* returned on failure. |
*/ |
function simpleQuery($query) |
{ |
$ismanip = DB::isManip($query); |
$this->last_query = $query; |
$query = $this->modifyQuery($query); |
if ($this->_db) { |
if (!@mysql_select_db($this->_db, $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
if (!$this->autocommit && $ismanip) { |
if ($this->transaction_opcount == 0) { |
$result = @mysql_query('SET AUTOCOMMIT=0', $this->connection); |
$result = @mysql_query('BEGIN', $this->connection); |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
} |
$this->transaction_opcount++; |
} |
$result = @mysql_query($query, $this->connection); |
if (!$result) { |
return $this->mysqlRaiseError(); |
} |
if (is_resource($result)) { |
$numrows = $this->numrows($result); |
if (is_object($numrows)) { |
return $numrows; |
} |
$this->num_rows[(int)$result] = $numrows; |
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 |
* |
* @access public |
* |
* @return false |
*/ |
function nextResult($result) |
{ |
return false; |
} |
// }}} |
// {{{ fetchInto() |
/** |
* Fetch a row and insert the data into an existing array. |
* |
* Formating of the array and the data therein are configurable. |
* See DB_result::fetchInto() for more information. |
* |
* @param resource $result query result identifier |
* @param array $arr (reference) array where data from the row |
* should be placed |
* @param int $fetchmode how the resulting array should be indexed |
* @param int $rownum the row number to fetch |
* |
* @return mixed DB_OK on success, null when end of result set is |
* reached or on failure |
* |
* @see DB_result::fetchInto() |
* @access private |
*/ |
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) { |
// See: http://bugs.php.net/bug.php?id=22328 |
// for why we can't check errors on fetching |
return null; |
/* |
$errno = @mysql_errno($this->connection); |
if (!$errno) { |
return null; |
} |
return $this->mysqlRaiseError($errno); |
*/ |
} |
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() |
/** |
* Free the internal resources associated with $result. |
* |
* @param $result MySQL result identifier |
* |
* @access public |
* |
* @return bool true on success, false if $result is invalid |
*/ |
function freeResult($result) |
{ |
unset($this->num_rows[(int)$result]); |
return @mysql_free_result($result); |
} |
// }}} |
// {{{ numCols() |
/** |
* Get the number of columns in a result set. |
* |
* @param $result MySQL result identifier |
* |
* @access public |
* |
* @return int the number of columns per row in $result |
*/ |
function numCols($result) |
{ |
$cols = @mysql_num_fields($result); |
if (!$cols) { |
return $this->mysqlRaiseError(); |
} |
return $cols; |
} |
// }}} |
// {{{ numRows() |
/** |
* Get the number of rows in a result set. |
* |
* @param $result MySQL result identifier |
* |
* @access public |
* |
* @return int the number of rows in $result |
*/ |
function numRows($result) |
{ |
$rows = @mysql_num_rows($result); |
if ($rows === null) { |
return $this->mysqlRaiseError(); |
} |
return $rows; |
} |
// }}} |
// {{{ autoCommit() |
/** |
* Enable/disable automatic commits |
*/ |
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() |
/** |
* Commit the current transaction. |
*/ |
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() |
/** |
* Roll back (undo) the current transaction. |
*/ |
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() |
/** |
* Gets the number of rows affected by the data manipulation |
* query. For other queries, this function returns 0. |
* |
* @return number of rows affected by the last query |
*/ |
function affectedRows() |
{ |
if (DB::isManip($this->last_query)) { |
return @mysql_affected_rows($this->connection); |
} else { |
return 0; |
} |
} |
// }}} |
// {{{ errorNative() |
/** |
* Get the native error code of the last error (if any) that |
* occured on the current connection. |
* |
* @access public |
* |
* @return int native MySQL error code |
*/ |
function errorNative() |
{ |
return @mysql_errno($this->connection); |
} |
// }}} |
// {{{ 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. DB_Error if problem. |
* |
* @internal |
* @see DB_common::nextID() |
* @access public |
*/ |
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 |
// 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, bail with a DB_ERROR_NOT_LOCKED error |
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; |
/** ONDEMAND TABLE CREATION **/ |
} 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; |
} |
/** BACKWARDS COMPAT **/ |
} elseif (DB::isError($result) && |
$result->getCode() == DB_ERROR_ALREADY_EXISTS) |
{ |
// 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 is returned if |
* problems arise. |
* |
* @internal |
* @see DB_common::createSequence() |
* @access public |
*/ |
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. DB_Error if problems. |
* |
* @internal |
* @see DB_common::dropSequence() |
* @access public |
*/ |
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 mixed DB_Error or true |
*/ |
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() |
/** |
* Quote a string so it can be safely used as a table or column name |
* |
* Quoting style depends on which database driver is being used. |
* |
* 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 |
* |
* @since 1.6.0 |
* @access public |
* @internal |
*/ |
function quoteIdentifier($str) |
{ |
return '`' . $str . '`'; |
} |
// }}} |
// {{{ quote() |
/** |
* @deprecated Deprecated in release 1.6.0 |
* @internal |
*/ |
function quote($str) { |
return $this->quoteSmart($str); |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escape a string according to the current DBMS's standards |
* |
* @param string $str the string to be escaped |
* |
* @return string the escaped string |
* |
* @internal |
*/ |
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() |
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() |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
if (DB::isManip($query)) { |
return $query . " LIMIT $count"; |
} else { |
return $query . " LIMIT $from, $count"; |
} |
} |
// }}} |
// {{{ mysqlRaiseError() |
/** |
* Gather information about an error, then use that info to create a |
* DB error object and finally return that object. |
* |
* @param integer $errno PEAR error number (usually a DB constant) if |
* manually raising an error |
* @return object DB error object |
* @see DB_common::errorCode() |
* @see DB_common::raiseError() |
*/ |
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)); |
} |
// }}} |
// {{{ 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 |
* @param int $mode a valid tableInfo mode |
* @return array an associative array with the information requested |
* or an error object if something is wrong |
* @access public |
* @internal |
* @see DB_common::tableInfo() |
*/ |
function tableInfo($result, $mode = null) { |
if (isset($result->result)) { |
/* |
* Probably received a result object. |
* Extract the result resource identifier. |
*/ |
$id = $result->result; |
$got_string = false; |
} elseif (is_string($result)) { |
/* |
* Probably received a table name. |
* Create a result resource identifier. |
*/ |
$id = @mysql_list_fields($this->dsn['database'], |
$result, $this->connection); |
$got_string = true; |
} 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); |
// made this IF due to performance (one if is faster than $count if's) |
if (!$mode) { |
for ($i=0; $i<$count; $i++) { |
$res[$i]['table'] = $case_func(@mysql_field_table($id, $i)); |
$res[$i]['name'] = $case_func(@mysql_field_name($id, $i)); |
$res[$i]['type'] = @mysql_field_type($id, $i); |
$res[$i]['len'] = @mysql_field_len($id, $i); |
$res[$i]['flags'] = @mysql_field_flags($id, $i); |
} |
} else { // full |
$res['num_fields']= $count; |
for ($i=0; $i<$count; $i++) { |
$res[$i]['table'] = $case_func(@mysql_field_table($id, $i)); |
$res[$i]['name'] = $case_func(@mysql_field_name($id, $i)); |
$res[$i]['type'] = @mysql_field_type($id, $i); |
$res[$i]['len'] = @mysql_field_len($id, $i); |
$res[$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() |
/** |
* Returns the query needed to get some backend info |
* @param string $type What kind of info you want to retrieve |
* @return string The SQL query string |
*/ |
function getSpecialQuery($type) |
{ |
switch ($type) { |
case 'tables': |
return 'SHOW TABLES'; |
case 'views': |
return DB_ERROR_NOT_CAPABLE; |
case 'users': |
$sql = 'select distinct User from user'; |
if ($this->dsn['database'] != 'mysql') { |
$dsn = $this->dsn; |
$dsn['database'] = 'mysql'; |
if (DB::isError($db = DB::connect($dsn))) { |
return $db; |
} |
$sql = $db->getCol($sql); |
$db->disconnect(); |
// XXX Fixme the mysql driver should take care of this |
if (!@mysql_select_db($this->dsn['database'], $this->connection)) { |
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); |
} |
} |
return $sql; |
case 'databases': |
return 'SHOW DATABASES'; |
default: |
return null; |
} |
} |
// }}} |
} |
/* |
* Local variables: |
* tab-width: 4 |
* c-basic-offset: 4 |
* End: |
*/ |
?> |
/branches/v1.6-croc/jrest/lib/DB/common.php |
---|
New file |
0,0 → 1,2038 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ |
// +----------------------------------------------------------------------+ |
// | 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. | |
// +----------------------------------------------------------------------+ |
// | Author: Stig Bakken <ssb@php.net> | |
// | Tomas V.V.Cox <cox@idecnet.com> | |
// | Maintainer: Daniel Convissor <danielc@php.net> | |
// +----------------------------------------------------------------------+ |
// |
// $Id$ |
/** |
* DB_common is a base class for DB implementations, and must be |
* inherited by all such |
* |
* @package DB |
* @version $Id$ |
* @category Database |
* @author Stig Bakken <ssb@php.net> |
* @author Tomas V.V.Cox <cox@idecnet.com> |
*/ |
class DB_common extends PEAR |
{ |
// {{{ properties |
/** |
* assoc of capabilities for this DB implementation |
* $features['limit'] => 'emulate' => emulate with fetch row by number |
* 'alter' => alter the query |
* false => skip rows |
* @var array |
*/ |
var $features = array(); |
/** |
* assoc mapping native error codes to DB ones |
* @var array |
*/ |
var $errorcode_map = array(); |
/** |
* DB type (mysql, oci8, odbc etc.) |
* @var string |
*/ |
var $phptype; |
/** |
* @var string |
*/ |
var $prepare_tokens; |
/** |
* @var string |
*/ |
var $prepare_types; |
/** |
* @var string |
*/ |
var $prepared_queries; |
/** |
* @var integer |
*/ |
var $prepare_maxstmt = 0; |
/** |
* @var string |
*/ |
var $last_query = ''; |
/** |
* @var integer |
*/ |
var $fetchmode = DB_FETCHMODE_ORDERED; |
/** |
* @var string |
*/ |
var $fetchmode_object_class = 'stdClass'; |
/** |
* Run-time configuration options. |
* |
* The 'optimize' option has been deprecated. Use the 'portability' |
* option instead. |
* |
* @see DB_common::setOption() |
* @var array |
*/ |
var $options = array( |
'persistent' => false, |
'ssl' => false, |
'debug' => 0, |
'seqname_format' => '%s_seq', |
'autofree' => false, |
'portability' => DB_PORTABILITY_NONE, |
'optimize' => 'performance', // Deprecated. Use 'portability'. |
); |
/** |
* DB handle |
* @var resource |
*/ |
var $dbh; |
// }}} |
// {{{ toString() |
/** |
* String conversation |
* |
* @return string |
* @access private |
*/ |
function toString() |
{ |
$info = strtolower(get_class($this)); |
$info .= ': (phptype=' . $this->phptype . |
', dbsyntax=' . $this->dbsyntax . |
')'; |
if ($this->connection) { |
$info .= ' [connected]'; |
} |
return $info; |
} |
// }}} |
// {{{ constructor |
/** |
* Constructor |
*/ |
function DB_common() |
{ |
$this->PEAR('DB_Error'); |
} |
// }}} |
// {{{ quoteString() |
/** |
* DEPRECATED: Quotes a string so it can be safely used within string |
* delimiters in a query |
* |
* @return string quoted string |
* |
* @see DB_common::quoteSmart(), DB_common::escapeSimple() |
* @deprecated Deprecated in release 1.2 or lower |
* @internal |
*/ |
function quoteString($string) |
{ |
$string = $this->quote($string); |
if ($string{0} == "'") { |
return substr($string, 1, -1); |
} |
return $string; |
} |
// }}} |
// {{{ quote() |
/** |
* DEPRECATED: Quotes a string so it can be safely used in a query |
* |
* @param string $string the input string to quote |
* |
* @return string The NULL string or the string quotes |
* in magic_quote_sybase style |
* |
* @see DB_common::quoteSmart(), DB_common::escapeSimple() |
* @deprecated Deprecated in release 1.6.0 |
* @internal |
*/ |
function quote($string = null) |
{ |
return ($string === null) ? 'NULL' : "'".str_replace("'", "''", $string)."'"; |
} |
// }}} |
// {{{ quoteIdentifier() |
/** |
* Quote 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 |
* |
* InterBase doesn't seem to be able to use delimited identifiers |
* via PHP 4. They work fine under PHP 5. |
* |
* @param string $str identifier name to be quoted |
* |
* @return string quoted identifier string |
* |
* @since 1.6.0 |
* @access public |
*/ |
function quoteIdentifier($str) |
{ |
return '"' . str_replace('"', '""', $str) . '"'; |
} |
// }}} |
// {{{ quoteSmart() |
/** |
* Format 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 data to be quoted |
* |
* @return mixed the format of the results 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> |
* &type.bool; -> 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> |
* |
* @since 1.6.0 |
* @see DB_common::escapeSimple() |
* @access public |
*/ |
function quoteSmart($in) |
{ |
if (is_int($in) || is_double($in)) { |
return $in; |
} elseif (is_bool($in)) { |
return $in ? 1 : 0; |
} elseif (is_null($in)) { |
return 'NULL'; |
} else { |
return "'" . $this->escapeSimple($in) . "'"; |
} |
} |
// }}} |
// {{{ escapeSimple() |
/** |
* Escape 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 1.6.0 |
* @see DB_common::quoteSmart() |
* @access public |
*/ |
function escapeSimple($str) { |
return str_replace("'", "''", $str); |
} |
// }}} |
// {{{ provides() |
/** |
* Tell whether a DB implementation or its backend extension |
* supports a given feature |
* |
* @param array $feature name of the feature (see the DB class doc) |
* @return bool whether this DB implementation supports $feature |
* @access public |
*/ |
function provides($feature) |
{ |
return $this->features[$feature]; |
} |
// }}} |
// {{{ errorCode() |
/** |
* Map native error codes to DB's portable ones |
* |
* Requires that the DB implementation's constructor fills |
* in the <var>$errorcode_map</var> property. |
* |
* @param mixed $nativecode the native error code, as returned by the |
* backend database extension (string or integer) |
* |
* @return int a portable DB error code, or DB_ERROR if this DB |
* implementation has no mapping for the given error code. |
* |
* @access public |
*/ |
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() |
/** |
* Map a DB error code to a textual message. This is actually |
* just a wrapper for DB::errorMessage() |
* |
* @param integer $dbcode the DB error code |
* |
* @return string the corresponding error message, of false |
* if the error code was unknown |
* |
* @access public |
*/ |
function errorMessage($dbcode) |
{ |
return DB::errorMessage($this->errorcode_map[$dbcode]); |
} |
// }}} |
// {{{ raiseError() |
/** |
* Communicate an error and invoke error callbacks, etc |
* |
* Basically a wrapper for PEAR::raiseError without the message string. |
* |
* @param mixed integer error code, or a PEAR error object (all |
* other parameters are ignored if this parameter is |
* an object |
* |
* @param int error mode, see PEAR_Error docs |
* |
* @param mixed If error mode is PEAR_ERROR_TRIGGER, this is the |
* error level (E_USER_NOTICE etc). If error mode is |
* PEAR_ERROR_CALLBACK, this is the callback function, |
* either as a function name, or as an array of an |
* object and method name. For other error modes this |
* parameter is ignored. |
* |
* @param string Extra debug information. Defaults to the last |
* query and native error code. |
* |
* @param mixed Native error code, integer or string depending the |
* backend. |
* |
* @return object a PEAR error object |
* |
* @access public |
* @see PEAR_Error |
*/ |
function &raiseError($code = DB_ERROR, $mode = null, $options = null, |
$userinfo = null, $nativecode = null) |
{ |
// The error is yet a DB error object |
if (is_object($code)) { |
// because we the static PEAR::raiseError, our global |
// handler should be used if it is set |
if ($mode === null && !empty($this->_default_error_mode)) { |
$mode = $this->_default_error_mode; |
$options = $this->_default_error_options; |
} |
$tmp = PEAR::raiseError($code, null, $mode, $options, null, null, true); |
return $tmp; |
} |
if ($userinfo === null) { |
$userinfo = $this->last_query; |
} |
if ($nativecode) { |
$userinfo .= ' [nativecode=' . trim($nativecode) . ']'; |
} |
$tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo, |
'DB_Error', true); |
return $tmp; |
} |
// }}} |
// {{{ setFetchMode() |
/** |
* Sets which fetch mode should be used by default on queries |
* on this connection |
* |
* @param integer $fetchmode DB_FETCHMODE_ORDERED or |
* DB_FETCHMODE_ASSOC, possibly bit-wise OR'ed with |
* DB_FETCHMODE_FLIPPED. |
* |
* @param string $object_class The class 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 |
* @see DB_FETCHMODE_ASSOC |
* @see DB_FETCHMODE_FLIPPED |
* @see DB_FETCHMODE_OBJECT |
* @see DB_row::DB_row() |
* @access public |
*/ |
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() |
/** |
* Set 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>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> <?php |
* $dbh->setOption('autofree', true); |
* ?></code> |
* |
* Example 2. Portability for lowercasing and trimming |
* <code> <?php |
* $dbh->setOption('portability', |
* DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM); |
* ?></code> |
* |
* Example 3. All portability options except trimming |
* <code> <?php |
* $dbh->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. 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 option name |
* |
* @return mixed the option 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> <?php |
* $sth = $dbh->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); |
* $data = array( |
* "John's text", |
* "'it''s good'", |
* 'filename.txt' |
* ); |
* $res = $dbh->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 query to be prepared |
* |
* @return mixed DB statement resource on success. DB_Error on failure. |
* |
* @see DB_common::execute() |
* @access public |
*/ |
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 generate an insert or update query and pass it to prepare() |
* |
* @param string $table name of the table |
* @param array $table_fields ordered array containing the fields names |
* @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE) |
* @param string $where in case of update queries, this string will be put after the sql WHERE statement |
* @return resource handle for the query |
* @see DB_common::prepare(), DB_common::buildManipSQL() |
* @access public |
*/ |
function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT, $where = false) |
{ |
$query = $this->buildManipSQL($table, $table_fields, $mode, $where); |
return $this->prepare($query); |
} |
// }}} |
// {{{ autoExecute() |
/** |
* Automaticaly generate an insert or update query and call prepare() |
* and execute() with it |
* |
* @param string $table name of the table |
* @param array $fields_values assoc ($key=>$value) where $key is a field name and $value its value |
* @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE) |
* @param string $where in case of update queries, this string will be put after the sql WHERE statement |
* @return mixed a new DB_Result or a DB_Error when fail |
* @see DB_common::autoPrepare(), DB_common::buildManipSQL() |
* @access public |
*/ |
function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT, $where = false) |
{ |
$sth = $this->autoPrepare($table, array_keys($fields_values), $mode, $where); |
$ret =& $this->execute($sth, array_values($fields_values)); |
$this->freePrepared($sth); |
return $ret; |
} |
// }}} |
// {{{ buildManipSQL() |
/** |
* Make automaticaly an sql query for prepare() |
* |
* Example : buildManipSQL('table_sql', array('field1', 'field2', 'field3'), DB_AUTOQUERY_INSERT) |
* will return the string : INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?) |
* NB : - 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 name of the table |
* @param array $table_fields ordered array containing the fields names |
* @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE) |
* @param string $where in case of update queries, this string will be put after the sql WHERE statement |
* @return string sql query for prepare() |
* @access public |
*/ |
function buildManipSQL($table, $table_fields, $mode, $where = false) |
{ |
if (count($table_fields) == 0) { |
$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: |
$this->raiseError(DB_ERROR_SYNTAX); |
} |
} |
// }}} |
// {{{ execute() |
/** |
* Executes a DB statement prepared with prepare() |
* |
* Example 1. |
* <code> <?php |
* $sth = $dbh->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); |
* $data = array( |
* "John's text", |
* "'it''s good'", |
* 'filename.txt' |
* ); |
* $res =& $dbh->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 object a new DB_Result or a DB_Error when fail |
* |
* {@internal ibase and oci8 have their own execute() methods.}} |
* |
* @see DB_common::prepare() |
* @access public |
*/ |
function &execute($stmt, $data = array()) |
{ |
$realquery = $this->executeEmulateQuery($stmt, $data); |
if (DB::isError($realquery)) { |
return $realquery; |
} |
$result = $this->simpleQuery($realquery); |
if (DB::isError($result) || $result === DB_OK) { |
return $result; |
} else { |
$tmp =& new DB_result($this, $result); |
return $tmp; |
} |
} |
// }}} |
// {{{ executeEmulateQuery() |
/** |
* Emulates the execute statement, when not supported |
* |
* @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 code is returned on failure. |
* |
* @see DB_common::execute() |
* @access private |
*/ |
function executeEmulateQuery($stmt, $data = array()) |
{ |
if (!is_array($data)) { |
$data = array($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() |
/** |
* This function does 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 mixed DB_OK or DB_Error |
* |
* @see DB_common::prepare(), DB_common::execute() |
* @access public |
*/ |
function executeMultiple($stmt, $data) |
{ |
foreach ($data as $value) { |
$res =& $this->execute($stmt, $value); |
if (DB::isError($res)) { |
return $res; |
} |
} |
return DB_OK; |
} |
// }}} |
// {{{ freePrepared() |
/** |
* Free the resource used in a prepared query |
* |
* @param $stmt The resurce returned by the prepare() function |
* @see DB_common::prepare() |
*/ |
function freePrepared($stmt) |
{ |
// Free the internal prepared vars |
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() |
/** |
* This method is used by backends to alter queries for various |
* reasons |
* |
* It is defined here to assure that all implementations |
* have this method defined. |
* |
* @param string $query query to modify |
* |
* @return the new (modified) query |
* |
* @access private |
*/ |
function modifyQuery($query) { |
return $query; |
} |
// }}} |
// {{{ modifyLimitQuery() |
/** |
* This method is used by backends to alter limited queries |
* |
* @param string $query query to modify |
* @param integer $from the row to start to fetching |
* @param integer $count the numbers of rows to fetch |
* |
* @return the new (modified) query |
* |
* @access private |
*/ |
function modifyLimitQuery($query, $from, $count, $params = array()) |
{ |
return $query; |
} |
// }}} |
// {{{ query() |
/** |
* Send a query to the database and return any results with a |
* DB_result object |
* |
* 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 DB_result object or DB_OK on success, a DB |
* error on failure |
* |
* @see DB_result, DB_common::prepare(), DB_common::execute() |
* @access public |
*/ |
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); |
return $ret; |
} else { |
$result = $this->simpleQuery($query); |
if (DB::isError($result) || $result === DB_OK) { |
return $result; |
} else { |
$tmp =& new DB_result($this, $result); |
return $tmp; |
} |
} |
} |
// }}} |
// {{{ limitQuery() |
/** |
* Generates a limited query |
* |
* @param string $query query |
* @param integer $from the row to start to fetching |
* @param integer $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 DB_Result object, DB_OK or a DB_Error |
* |
* @access public |
*/ |
function &limitQuery($query, $from, $count, $params = array()) |
{ |
$query = $this->modifyLimitQuery($query, $from, $count, $params); |
if (DB::isError($query)){ |
return $query; |
} |
$result =& $this->query($query, $params); |
if (is_a($result, 'DB_result')) { |
$result->setOption('limit_from', $from); |
$result->setOption('limit_count', $count); |
} |
return $result; |
} |
// }}} |
// {{{ getOne() |
/** |
* Fetch the first column of the first row of data returned from |
* a query |
* |
* Takes care of doing the query and freeing the results when finished. |
* |
* @param 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. DB_Error on failure. |
* |
* @access public |
*/ |
function &getOne($query, $params = array()) |
{ |
settype($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 (DB::isError($res)) { |
return $res; |
} |
$err = $res->fetchInto($row, DB_FETCHMODE_ORDERED); |
$res->free(); |
if ($err !== DB_OK) { |
return $err; |
} |
return $row[0]; |
} |
// }}} |
// {{{ getRow() |
/** |
* Fetch the first row of data returned from a query |
* |
* Takes care of doing the query and freeing the results when finished. |
* |
* @param string $query the SQL query |
* @param array $params array to be used in execution of the statement. |
* Quantity of array elements must match quantity |
* of placeholders in query. This function does |
* NOT support scalars. |
* @param int $fetchmode the fetch mode to use |
* |
* @return array the first row of results as an array indexed from |
* 0, or a DB error code. |
* |
* @access public |
*/ |
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(); |
} |
} |
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() |
/** |
* Fetch a single column from a result set and return 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 an indexed array with the data from the first |
* row at index 0, or a DB error code |
* |
* @see DB_common::query() |
* @access public |
*/ |
function &getCol($query, $col = 0, $params = array()) |
{ |
settype($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 (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() |
/** |
* Fetch the entire result set of a query and return 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 boolean $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 boolean $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 associative array with results from the query. |
* DB Error on failure. |
* |
* @access public |
*/ |
function &getAssoc($query, $force_array = false, $params = array(), |
$fetchmode = DB_FETCHMODE_DEFAULT, $group = false) |
{ |
settype($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 (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() |
/** |
* Fetch all the rows returned from a query |
* |
* @param string $query the SQL query |
* @param array $params array to be used in execution of the statement. |
* Quantity of array elements must match quantity |
* of placeholders in query. This function does |
* NOT support scalars. |
* @param int $fetchmode the fetch mode to use |
* |
* @return array an nested array. DB error on failure. |
* |
* @access public |
*/ |
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 (DB::isError($res) || $res === DB_OK) { |
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() |
/** |
* enable automatic Commit |
* |
* @param boolean $onoff |
* @return mixed DB_Error |
* |
* @access public |
*/ |
function autoCommit($onoff=false) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ commit() |
/** |
* starts a Commit |
* |
* @return mixed DB_Error |
* |
* @access public |
*/ |
function commit() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ rollback() |
/** |
* starts a rollback |
* |
* @return mixed DB_Error |
* |
* @access public |
*/ |
function rollback() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ numRows() |
/** |
* Returns the number of rows in a result object |
* |
* @param object DB_Result the result object to check |
* |
* @return mixed DB_Error or the number of rows |
* |
* @access public |
*/ |
function numRows($result) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ affectedRows() |
/** |
* Returns the affected rows of a query |
* |
* @return mixed DB_Error or number of rows |
* |
* @access public |
*/ |
function affectedRows() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ errorNative() |
/** |
* Returns an errormessage, provides by the database |
* |
* @return mixed DB_Error or message |
* |
* @access public |
*/ |
function errorNative() |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ getSequenceName() |
/** |
* Generate 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 |
* |
* @see DB_common::createSequence(), DB_common::dropSequence(), |
* DB_common::nextID(), DB_common::setOption() |
* @access private |
*/ |
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. DB_Error if problem. |
* |
* @see DB_common::createSequence(), DB_common::dropSequence(), |
* DB_common::getSequenceName() |
* @access public |
*/ |
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 is returned if |
* problems arise. |
* |
* @see DB_common::dropSequence(), DB_common::getSequenceName(), |
* DB_common::nextID() |
* @access public |
*/ |
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. DB_Error if problems. |
* |
* @see DB_common::createSequence(), DB_common::getSequenceName(), |
* DB_common::nextID() |
* @access public |
*/ |
function dropSequence($seq_name) |
{ |
return $this->raiseError(DB_ERROR_NOT_CAPABLE); |
} |
// }}} |
// {{{ 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. |
* If something goes wrong an error object is returned. |
* |
* @see DB_common::setOption() |
* @access public |
*/ |
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() |
/** |
* @deprecated Deprecated in release 1.2 or lower |
*/ |
function getTables() |
{ |
return $this->getListOf('tables'); |
} |
// }}} |
// {{{ getListOf() |
/** |
* list internal DB info |
* valid values for $type are db dependent, |
* often: databases, users, view, functions |
* |
* @param string $type type of requested info |
* |
* @return mixed DB_Error or the requested data |
* |
* @access public |
*/ |
function getListOf($type) |
{ |
$sql = $this->getSpecialQuery($type); |
if ($sql === null) { // No support |
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; |
} |
return $this->getCol($sql); // Launch this query |
} |
// }}} |
// {{{ getSpecialQuery() |
/** |
* Returns the query needed to get some backend info |
* |
* @param string $type What kind of info you want to retrieve |
* |
* @return string The SQL query string |
* |
* @access public |
*/ |
function getSpecialQuery($type) |
{ |
return $this->raiseError(DB_ERROR_UNSUPPORTED); |
} |
// }}} |
// {{{ _rtrimArrayValues() |
/** |
* Right trim all strings in an array |
* |
* @param array $array the array to be trimmed (passed by reference) |
* @return void |
* @access private |
*/ |
function _rtrimArrayValues(&$array) |
{ |
foreach ($array as $key => $value) { |
if (is_string($value)) { |
$array[$key] = rtrim($value); |
} |
} |
} |
// }}} |
// {{{ _convertNullArrayValuesToEmpty() |
/** |
* Convert all null values in an array to empty strings |
* |
* @param array $array the array to be de-nullified (passed by reference) |
* @return void |
* @access private |
*/ |
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.6-croc/jrest/lib/DB/.directory |
---|
New file |
0,0 → 1,5 |
[Dolphin] |
Timestamp=2010,10,19,15,1,41 |
[Settings] |
ShowDotFiles=true |
/branches/v1.6-croc/jrest/lib/Decoupage.class.php |
---|
New file |
0,0 → 1,160 |
<?php |
// Encodage : UTF-8 |
// +-------------------------------------------------------------------------------------------------------------------+ |
/** |
* Découpage |
* |
* Description : classe abstraite mettant en comun des expressions régulière pour le découpage des noms latins. |
* |
//Auteur original : |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Tela-Botanica 1999-2009 |
* @licence GPL v3 & CeCILL v2 |
* @version $Id: Decoupage.class.php 1873 2009-03-31 10:07:24Z Jean-Pascal MILCENT $ |
*/ |
// +-------------------------------------------------------------------------------------------------------------------+ |
abstract class Decoupage { |
protected $min = '[a-z\x{E0}-\x{FF}\x{153}]';// Lettres minuscules : a à z et à à ÿ et œ |
protected $maj = "[A-Z'\x{C0}-\x{DF}\x{152}]";// Lettres majuscules : A à Z, ' et À à ß et Œ |
protected $hyb = '[+xX]'; |
protected $SupraSp;// Nom de type suprasp. |
protected $GenHy;// Hybride intergénérique |
protected $Gen;// Genre |
protected $Dou = '(?:\(\?\)|\?)';// Doute |
protected $Epi_cv;// Epithete de cultivar |
protected $Epi_nn_hy = '(?:nsp\.|)';// Epithète non nommé hybride |
protected $Epi_nn = '(?:sp\.[1-9]?|spp\.|)';// Epithète non nommé |
protected $Epi;// Epithete |
//------------------------------------------------------------------------------------------------------------// |
protected $Ran_ig = '[Ss]ect\.|subg(?:en|)\.|ser\.|subser\.';// Rang taxonomique infragénérique de type : sous-genre |
protected $Ran_ig_gr = 'gr\.';// Rang taxonomique infragénérique de type : groupe |
protected $Ran_ig_agg = 'agg\.';// Rang taxonomique infragénérique de type : aggrégat |
protected $Ran_bo_i1 = 'subsp\.';// Rang taxonomique infraspécifique de niveau 1 |
protected $Ran_bo_i2 = 'var\.|subvar\.';// Rang taxonomique infraspécifique de niveau 2 |
protected $Ran_bo_i3 = 'f\.|fa\.|fa|forma';// Rang taxonomique infraspécifique de niveau 3 |
protected $Ran_bo_i4 = 'race|prole|proles|prol\.';// Rang taxonomique infraspécifique de niveau 4 |
protected $Ran_bo;// Rang taxonomique infraspécifique botanique non hybride |
protected $Ran_hy_i1 = 'n-subsp\.|\[subsp\.\]|\[n-subsp\.\]';// Rang taxonomique infraspécifique hybride de niveau 1 |
protected $Ran_hy_i2 = '\[var\.\]|n-var\.|\[n-var\.\]';// Rang taxonomique infraspécifique hybride de niveau 2 |
protected $Ran_hy_i3 = '';// Rang taxonomique infraspécifique hybride de niveau 3 |
protected $Ran_hy_i4 = 'n-proles\.';// Rang taxonomique infraspécifique hybride de niveau 4 |
protected $Ran_hy;// Rang taxonomique infraspécifique hybridre |
protected $Ran_ht = 'convar\.|[cC]v\.';// Rang taxonomique horticole |
protected $Ran;// Rang taxonomique infraspécifique non hybride, hybride et horticole |
//------------------------------------------------------------------------------------------------------------// |
protected $Ini;// Initiale de prénoms |
protected $Pre;// Prénoms |
protected $Par = '(?i:de|des|le|la|de la|von|van|st\.|el)';// Particules |
protected $ParSsEs = "(?i:st\.-|d)";// Particules sans espace après |
protected $Nom; // Abreviation d'un nom d'auteur. Le "f." c'est pour "filius" et c'est collé au nom |
protected $NomSpe = '(?:[A-Z]\. (?:DC\.|St\.-Hil\.))|\(?hort\.\)?|al\.';// Prénom + nom spéciaux : "hort." est utilisé comme un nom d'auteur mais cela signifie "des jardins". "DC." est une exception deux majuscule suivi d'un point. |
protected $Int;// Intitulé d'auteurs (Prénom + Nom) |
//------------------------------------------------------------------------------------------------------------// |
protected $AutNo;// Intitulé auteur sans "ex", ni "&", ni "et", ni parenthèses |
protected $AutNoTa;// Intitulé auteur sans "ex", ni "&", ni "et" mais avec parenthèses possible pour la nomenclature |
protected $AutEx;// Intitulé auteur avec "ex" |
protected $et = '(?:&|et)'; |
protected $AutExEt;// Intitulé auteur avec "ex" et "&" ou "et" |
protected $AutEt;// Intitulé auteur avec "&" ou "et" et sans parenthèse spécifique à la nomenclature |
protected $AutEtTa;// Intitulé auteur avec "&" ou "et" et avec ou sans parenthèse spécifique à la nomenclature |
protected $AutBib;// Intitulés auteurs pour la biblio |
protected $AutInc = 'AUTEUR\?';// Intitulé auteur spéciaux pouvant être trouvés entre parenthèses |
protected $AutSpe;// Intitulé auteur spéciaux pouvant être trouvés entre parenthèses |
protected $AutSpeSe;// Intitulé auteur spéciaux type "sensu" |
protected $AutSpeTa;// Intitulé auteur spéciaux propre à la nomenclature |
protected $Aut;// Tous les intitulés auteurs possibles |
protected $Auteur;// Tous les intitulés auteurs possibles |
//------------------------------------------------------------------------------------------------------------// |
protected $ComEmend;// Commentaires nomenclaturaux |
protected $ComPp = 'p\.p\.';// Commentaires nomenclaturaux |
protected $Com;// Intitulé auteur spéciaux type "sensu" |
protected $ComNom = '\(?(?:hort\. non .*|sensu .*|auct\..*|comb\.\s*(?:nov\.|ined\.)|comb?\.\s*nov\.\s*provis\.|stat\.\s*provis\.|nov\.\s*stat\.|stat\.\s*nov\.|p\.p\.|emend\.)\)?'; |
//------------------------------------------------------------------------------------------------------------// |
protected $In;// In auteur |
protected $AneMoCo = 'janvier|fevrier|mars|avril|mai|juin|juillet|ao\x{FB}t|septembre|octobre|novembre|decembre'; //Mois devant l'année |
protected $AneMoAb = 'janv\.|f[e\x{E9}]v\.|sept\.|oct\.|d\x{E9}c\.'; //Mois devant l'année |
protected $AneBaSi = '(?:\d{4}|\d{4} ?\?|DATE \?)';// Date |
protected $AneBaCo = '(?:\d{4}-\d{4}|\d{4}-\d{2})';// Date |
protected $AneDo = '\?';// Doute |
protected $AneBa;// Date |
protected $AneSpe;// Date |
protected $Ane;// Date |
//------------------------------------------------------------------------------------------------------------// |
// Spécial BDNFF : |
protected $Date = ' \[.*\]'; |
protected $Num = '[0-9]|3\*|4\*';# Gestion des numéros de flore |
protected $NumAuteur;# Gestion des numéros de flore mélangés ou pas au nom d'auteur |
//------------------------------------------------------------------------------------------------------------// |
protected $BibBa;// Biblio de base : \x{B0} = ° \x{AB}\x{BB} = «» \x{26} = & |
protected $Bib;// Biblio de taxon |
protected $BibAu = '.+';// Biblio supplémentaire |
//------------------------------------------------------------------------------------------------------------// |
protected $ErrDet;// Biblio à exclure base |
//------------------------------------------------------------------------------------------------------------// |
protected $HomNon = 'non';// Homonymes à exclure : négation |
protected $HomBa;// Homonymes à exclure base |
protected $Hom;// Homonymes à exclure avec non et nec |
protected $HomCourt;// Homonymes à exclure avec non et nec avec expression régulière plus courte! |
//------------------------------------------------------------------------------------------------------------// |
protected $Inf = '.*';// Informations supplémentaires |
public function __construct() |
{ |
//mb_internal_encoding('UTF-8'); |
//mb_regex_encoding('UTF-8'); |
//setlocale(LC_ALL, 'fr-fr'); |
$this->SupraSp = '(?:'.$this->maj.$this->min.'+|'.$this->maj.$this->min.'+-'.$this->maj.$this->min.'+)';// Nom de type suprasp. |
$this->GenHy = "[Xx] $this->SupraSp";// Hybride intergénérique |
$this->Gen = "$this->SupraSp|$this->GenHy"; |
$this->Epi_cv = "$this->maj.(?:$this->min|-)+";// Epithete de cultivar |
$this->Epi_nn = $this->Epi_nn.$this->Epi_nn_hy; |
$this->Epi = "(?:(?:$this->min|-|')+|$this->Epi_nn)";// Epithete |
$this->Ran_ig = $this->Ran_ig.'|'.$this->Ran_ig_gr; |
$this->Ran_bo = "$this->Ran_bo_i1|$this->Ran_bo_i2|$this->Ran_bo_i3|$this->Ran_bo_i4";// Rang taxonomique infraspécifique botanique non hybride |
$this->Ran_hy = "$this->Ran_hy_i1|$this->Ran_hy_i2|$this->Ran_hy_i3|$this->Ran_hy_i4";// Rang taxonomique infraspécifique hybridre |
$this->Ran = "(?:$this->Ran_ig|$this->Ran_bo|$this->Ran_hy|$this->Ran_ht)";// Rang taxonomique infraspécifique non hybride, hybride et horticole |
$this->Ini = '(?:'.$this->maj.'[.]|'.$this->maj.$this->min.'+[.]?)';// Initiale de prénoms |
$this->Pre = $this->Ini.'{1,3}|'.$this->Ini.'[\- ]'.$this->Ini;// Prénoms |
$this->Nom = '(?:'.$this->maj."'".$this->maj.'|'.$this->maj.'|'.$this->maj.$this->min."+'".$this->min.'+)'.$this->min.'*[.]?(?: ?f\.|)'; |
$this->Int = "(?:(?:$this->Pre ?|)(?:$this->Par |$this->ParSsEs|)(?:$this->Nom|$this->Nom".'[\- .]'."$this->Nom)|$this->NomSpe)";// Intitulé d'auteurs (Prénom + Nom) |
$this->AutNo = "$this->Int";// Intitulé auteur sans "ex", ni "&", ni "et", ni parenthèses |
$this->AutNoTa = "$this->AutNo|$this->NomSpe $this->Int|\($this->Int\) $this->Int";// Intitulé auteur sans "ex", ni "&", ni "et" mais avec parenthèses possible pour la nomenclature |
$this->AutEx = "\($this->Int\) $this->Int ex $this->Int|\($this->Int ex $this->Int\) $this->Int|$this->Int ex $this->Int";// Intitulé auteur avec "ex" |
$this->AutExEt = "$this->Int $this->et $this->Int ex $this->Int|$this->Int $this->et $this->Int ex $this->Int $this->et $this->Int|$this->Int ex $this->Int $this->et $this->Int|\($this->Int ex $this->Int $this->et $this->Int\) $this->Int|\($this->Int ex $this->Int\) $this->Int $this->et $this->Int|\($this->Int $this->et $this->Int\) $this->Int ex $this->Int|$this->NomSpe $this->Int ex $this->Int";// Intitulé auteur avec "ex" et "&" ou "et" |
$this->AutEt = "$this->Int $this->et $this->Int";// Intitulé auteur avec "&" ou "et" et sans parenthèse spécifique à la nomenclature |
$this->AutEtTa = "\($this->Int\) $this->Int $this->et $this->Int|\($this->Int $this->et $this->Int\) $this->Int|$this->AutEt";// Intitulé auteur avec "&" ou "et" et avec ou sans parenthèse spécifique à la nomenclature |
$this->AutBib = "(?:$this->AutNo|$this->AutEt)";// Intitulés auteurs pour la biblio |
$this->AutSpe = "(?:sensu |)auct\.|auct\. mult\.|$this->AutInc";// Intitulé auteur spéciaux pouvant être trouvés entre parenthèses |
$this->AutSpeSe = "sensu $this->AutBib";// Intitulé auteur spéciaux type "sensu" |
$this->AutSpeTa = "$this->AutSpe|\((?:$this->AutSpe)\)|$this->AutSpeSe";// Intitulé auteur spéciaux propre à la nomenclature |
$this->Aut = "(?:$this->AutExEt|$this->AutEx|$this->AutEtTa|$this->AutSpeTa|$this->AutNoTa)";// Tous les intitulés auteurs possibles |
$this->Auteur = $this->Int.'|'.$this->Int.' '.$this->et.' '.$this->Int.'|(?:'.$this->Int.', )+'.$this->Int.' '.$this->et.' '.$this->Int;// Intitulé auteur avec "&" ou "et"; |
$this->ComEmend = "emend\. $this->AutBib";// Commentaires nomenclaturaux |
$this->Com = "$this->ComEmend|$this->ComPp";// Intitulé auteur spéciaux type "sensu" |
$this->In = "[iI]n $this->AutBib";// In auteur |
$this->AneBa = "$this->AneBaSi|$this->AneBaCo";// Date |
$this->AneSpe = "(?:$this->AneBa ?\[$this->AneBa\]|(?:$this->AneMoCo|$this->AneMoAb) $this->AneBaSi|$this->AneBaSi $this->AneBaSi)";// Date |
$this->Ane = "$this->AneBa||$this->AneDo|$this->AneSpe";// Date |
$this->BibBa = "(?:$this->maj$this->min*[.]?|in|hort\.)(?:$this->min*[.]?|[\d\/\- ,()'\x{B0}\x{26}\x{AB}\x{BB}[\]?])*";// Biblio de base : \x{B0} = ° \x{AB}\x{BB} = «» \x{26} = & |
$this->Bib = "([^:]+):(.+?)\(($this->Ane)\)";// Biblio de taxon |
$this->ErrDet = "($this->AutSpe,? non $this->Aut): ($this->Bib;?)+";// Biblio à exclure base |
$this->HomBa = "$this->Aut \($this->Ane\)";// Homonymes à exclure base |
$this->Hom = "$this->HomNon $this->HomBa(?: nec $this->HomBa)*?";// Homonymes à exclure avec non et nec |
$this->HomCourt = "$this->HomNon .+?(?: nec .+?)*?";// Homonymes à exclure avec non et nec avec expression régulière plus courte! |
$this->NumAuteur = $this->Num.'|(?:(?:'.$this->Num.'|'.$this->Auteur.'), )+(?:'.$this->Num.'|'.$this->Auteur.')';# Gestion des numéros de flore mélangés ou pas au nom d'auteur |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/DecoupageNomLatin.class.php |
---|
New file |
0,0 → 1,378 |
<?php |
// Encodage : UTF-8 |
// +-------------------------------------------------------------------------------------------------------------------+ |
/** |
* Découpage des noms latins |
* |
* Description : classe permettant de découper les noms latins. |
* |
//Auteur original : |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Tela-Botanica 1999-2009 |
* @licence GPL v3 & CeCILL v2 |
* @version $Id: DecoupageNomLatin.class.php 1873 2009-03-31 10:07:24Z Jean-Pascal MILCENT $ |
*/ |
// +-------------------------------------------------------------------------------------------------------------------+ |
class DecoupageNomLatin extends Decoupage { |
private $expression_principale = array(); |
private $expression_complement = array(); |
function DecoupageNomLatin() |
{ |
parent::__construct(); |
// Genre et nom supragénérique |
$this->expression_principale[1] = "/^((?:$this->hyb |)$this->Gen)(?:( $this->Inf)|)$/u"; |
// Sp |
$this->expression_principale[2] = "/^((?:$this->hyb |)$this->Gen) ((?:($this->hyb) |$this->Dou|)(?:$this->Epi|$this->Dou))(?:((?:,| $this->Ran) $this->Inf)| agg\.|)$/u"; |
// Rang infragénérique et supraspécifique |
$this->expression_principale[3] = '/^('.$this->Gen.') ('.$this->Ran.') ('.$this->Gen.'|.'.$this->Epi.')(?:(, '.$this->Inf.')|)$/u'; |
// Hybride interspécifique |
$this->expression_principale[4] = "/^((?:$this->Gen) $this->Epi (?:($this->Ran) $this->Epi )?x $this->Epi(?: ($this->Ran) $this->Epi)?)$/u"; |
// Aggrégat |
$this->expression_principale[5] = "/^($this->Gen) ($this->Epi) (agg\.)(?:( $this->Inf)|)$/u";// |
// Epithète infra-spécifique |
$this->expression_complement[1] = "/^ ($this->Ran) ((?:($this->hyb) |$this->Dou|)(?:$this->Epi|$this->Dou))(?:((?:,| $this->Ran) $this->Inf)|)$/Uu"; |
// Cultivar |
$this->expression_complement[5] = "/^ ($this->Ran_ht) ((?:(?:$this->Epi_cv) ?)+)$/u"; |
} |
public function decouper($nom_latin) |
{ |
$aso_nom_decompo = array( 'nom_genre' => '', 'nom_sp' => '', 'auteur_sp' => '', 'nom_complement' => '', |
'type_infrasp' => '', 'nom_infrasp' => '', |
'num_nomenc' => '', 'num_taxo' => '', 'rang_taxonomique' => '', |
'nom_courant' => '', 'nom_superieur' => '', 'agg' => ''); |
$aso_nom_decompo['nom_complet'] = $nom_latin; |
while ($nom_latin != '') { |
$morceau = array(); |
if (preg_match($this->expression_principale[4], $nom_latin, $morceau)) {// Formule d'hybridation |
// Nous tentons de déterminer le rang de l'hybride |
if (isset($morceau[2]) && isset($morceau[3]) && $morceau[2] == $morceau[3]) { |
$aso_nom_decompo['rang_taxonomique'] = $this->attribuerCodeRang('n-'.$morceau[2]); |
} else { |
$aso_nom_decompo['rang_taxonomique'] = 260;// Hybride instersp. |
} |
$aso_nom_decompo['mark_hybride_interspecifique'] = 'x'; |
$aso_nom_decompo['formule_hybridation'] = $morceau[0]; |
$nom_latin = ''; |
} else if (preg_match($this->expression_principale[5], $nom_latin, $morceau)) {// agg. |
$aso_nom_decompo['rang_taxonomique'] = 240;// agg. |
$aso_nom_decompo['nom_genre'] = $morceau[1]; |
$aso_nom_decompo['nom_sp'] = $morceau[2]; |
$aso_nom_decompo['agg'] = $morceau[3]; |
$nom_latin = $morceau[4]; |
$aso_nom_decompo['nom_superieur'] = $morceau[1]; |
$aso_nom_decompo['nom_courant'] = $morceau[2]; |
} else if (preg_match($this->expression_principale[2], $nom_latin, $morceau)) {// Nom d'sp. |
// Nous regardons si nous avons à faire à un hybride |
if (preg_match('/^'.$this->hyb.'$/', $morceau[3])) { |
$aso_nom_decompo['rang_taxonomique'] = 260;// hybride intersp. |
$aso_nom_decompo['mark_hybride_interspecifique'] = strtolower($morceau[3]); |
} else if (preg_match('/^'.$this->Epi_nn_hy.'$/', $morceau[2])) { |
$aso_nom_decompo['rang_taxonomique'] = 260;// hybride intersp. |
$aso_nom_decompo['mark_hybride_interspecifique'] = 'x'; |
} else { |
$aso_nom_decompo['rang_taxonomique'] = 250;// sp. |
} |
// Nous atribuons le genre |
$aso_nom_decompo['nom_genre'] = $morceau[1]; |
// Nous regardons si nous avons à faire à une phrase non nommé (ex : sp.1, spp., nsp.) |
if (preg_match('/^'.$this->Epi_nn.'$/', $morceau[2])) { |
$aso_nom_decompo['phrase_nom_non_nomme'] = $morceau[2];// hybride intersp. |
$aso_nom_decompo['nom_sp'] = ''; |
} else { |
$aso_nom_decompo['nom_sp'] = $morceau[2]; |
} |
$nom_latin = $morceau[4]; |
$aso_nom_decompo['nom_superieur'] = $morceau[1]; |
$aso_nom_decompo['nom_courant'] = $morceau[2]; |
} else if (preg_match($this->expression_principale[3], $nom_latin, $morceau)) {// Nom infragénérique et supraspécifique |
$aso_nom_decompo['nom_genre'] = $morceau[1]; |
$aso_nom_decompo['rang_taxonomique'] = $this->attribuerCodeRang($morceau[2]); |
// Nous regardons si nous avons à faire à un groupe |
if (preg_match('/^'.$this->Ran_ig_gr.'$/', $morceau[2])) { |
$aso_nom_decompo['nom_sp'] = $morceau[3]; |
} else { |
$aso_nom_decompo['nom_infra_genre'] = $morceau[3]; |
} |
$nom_latin = $morceau[4]; |
$aso_nom_decompo['nom_superieur'] = $morceau[1]; |
$aso_nom_decompo['nom_courant'] = $morceau[3]; |
} else if (preg_match($this->expression_principale[1], $nom_latin, $morceau)) {// Nom de genre et supragénérique |
$aso_nom_decompo['rang_taxonomique'] = $this->verifierTerminaisonLatine($nom_latin); |
$aso_nom_decompo['nom_suprasp'] = $morceau[1]; |
$nom_latin = $morceau[2]; |
$aso_nom_decompo['nom_superieur'] = null; |
$aso_nom_decompo['nom_courant'] = $morceau[1]; |
} else if (preg_match($this->expression_complement[5], $nom_latin, $morceau)) {// Cultivar |
$aso_nom_decompo['rang_cultivar'] = $this->attribuerCodeRang($morceau[1]); |
// Nous vérifions si nous avons à faire à un cultivar d'hybride |
if ($aso_nom_decompo['mark_hybride_interspecifique'] == 'x' && $aso_nom_decompo['rang_cultivar'] == 460) { |
$aso_nom_decompo['rang_cultivar'] = 470; |
} |
$aso_nom_decompo['cultivar'] = $morceau[2]; |
$nom_latin = ''; |
} else if (preg_match($this->expression_complement[1], $nom_latin, $morceau)) {// Nom infrasp. |
if (preg_match('/^'.$this->hyb.'$/', $morceau[3])) { |
$aso_nom_decompo['mark_hybride_interspecifique'] = strtolower($morceau[3]); |
} |
$aso_nom_decompo['rang_taxonomique'] = $this->attribuerCodeRang($morceau[1]); |
$aso_nom_decompo['type_infrasp'] = $morceau[1]; |
$aso_nom_decompo['nom_infrasp'] = $morceau[2]; |
$nom_latin = $morceau[4]; |
$aso_nom_decompo['nom_superieur'] = $aso_nom_decompo['nom_courant']; |
$aso_nom_decompo['nom_courant'] = $morceau[2]; |
} else {// Erreurs |
$aso_nom_decompo['erreur_mark'] = 'erreur'; |
$aso_nom_decompo['erreur_notes'] = $nom_latin; |
$nom_latin = ''; |
} |
} |
return $aso_nom_decompo; |
} |
public function verifierTerminaisonLatine($nom_latin) |
{ |
if (preg_match('/^Plantae$/', $nom_latin)) {// Règne |
return 10; |
} else if (preg_match('/phyta$/', $nom_latin)) {// Embranchement ou Division |
return 30; |
} else if (preg_match('/phytina$/', $nom_latin)) {// Sous-Embranchement ou Sous-Division |
return 40; |
} if (preg_match('/opsida$/', $nom_latin)) {// Classe |
return 70; |
} else if (preg_match('/idae$/', $nom_latin)) {// Sous-Classe |
return 80; |
} else if (preg_match('/ales$/', $nom_latin)) {// Ordre |
return 100; |
} else if (preg_match('/ineae$/', $nom_latin)) {// Sous-Ordre |
return 110; |
} else if (preg_match('/aceae$/', $nom_latin)) {// Famille |
return 120; |
} else if (preg_match('/oideae$/', $nom_latin)) {// Sous-Famille |
return 130; |
} else if (preg_match('/eae$/', $nom_latin)) {// Tribu |
return 140; |
} else if (preg_match('/inae$/', $nom_latin)) {// Sous-Tribu |
return 150; |
} else if (preg_match('/^[A-Z]/', $nom_latin)) {// Genre |
return 160; |
} else { |
return 1; |
} |
} |
static function fournirTableauAbreviationRang($type = 'tout') |
{ |
$rang_supra_sp = array('subgen.', 'subg.', 'sect.');// l'abréviation du rang est suivi par un nom supra spécifique commençant par une majuscule |
$rang_supra_gr = array('gr.');// l'abréviation du rang est suivi par un nom ne commençant pas par une majuscule |
$rang_supra_agg = array('agg.');// le nom latin est terminé par l'abréviation du rang |
$rang_infra_sp = array( 'subsp.', 'n-subsp.', '[subsp.]', '[n-subsp.]', |
'var.', 'nvar.', '[var.]', |
'prol.', 'proles', 'n-proles.', |
'f.', 'fa', 'fa.', 'forma', |
'subvar.', 'convar.', |
'cv.', 'Cv.', |
'n-f.', 'n-fa', 'n-fa.', |
'subf.', 'subfa', 'subfa.'); |
if ($type == 'supra') { |
return $rang_supra_sp; |
} else if ($type == 'supra-gr') { |
return $rang_supra_gr; |
} else if ($type == 'supra-agg') { |
return $rang_supra_agg; |
} else if ($type == 'infra') { |
return $rang_infra_sp; |
} else if ($type == 'tout') { |
return array_merge($rang_supra_sp, $rang_supra_gr, $rang_supra_agg, $rang_infra_sp); |
} |
} |
static function actualiserCodeRang($code_rang) |
{ |
$aso_rang = array( '1' => '10', // Règne |
'3' => '20', // Sous-Règne |
'5' => '30', // Phylum |
'7' => '40', // Sub-Phylum |
'9' => '50', // division |
'15' => '60', // sous-division |
'20' => '70', // classe |
'25' => '80', // sous-classe |
'30' => '100', // ordre |
'35' => '110', // sous-ordre |
'40' => '120', // famille |
'45' => '130', // sous-famille |
'50' => '140', // tribu |
'55' => '150', // sous-tribu |
'60' => '160', // genre |
'62' => '170', // genre hybride (nouveau compatibilité flore Réunion) |
'65' => '180', // sous-genre |
'65' => '190', // section |
'75' => '200', // sous-section |
'80' => '210', // série |
'85' => '220', // sous-série |
'90' => '230', // groupe |
'95' => '240', // aggrégat |
'100' => '250', // espèce |
'102' => '260', // espèce hybride intragénérique |
'104' => '260', // espèce hybride intergénérique |
'110' => '280', // sous-espèce |
'112' => '300', // sous-espèce hybride : hybride entre deux sous-espèces d'une espèce non hybride ; exemple : Polypodium vulgare L. nsubsp. mantoniae (Rothm.) Schidlay (Polypodium vulgare L. subsp. vulgare x Polypodium vulgare L. subsp. prionodes (Aschers.) Rothm.). |
'113' => '310', // sous-espèce hybride : sous-espèce d'espèce hybride sans spécification du rang parental (subspecies) (voir ICBN, art. H.12.1). |
'114' => '300', // sous-espèce hybride : sous-espèce hybride d'espèce hybride (nothosubspecies) (voir ICBN, art. H.12.1) ; exemple : Mentha x piperita L. nsubsp. piperita (Mentha aquatica L. x Mentha spicata L. subsp. glabrata (Lej. et Court.) Lebeau). |
'115' => '300', // sous-espèce hybride |
'120' => '1', // infra2 |
'122' => '330', // prole, race : peu employé souvent issu de nom ancien (antérieur au code). |
'124' => '340', // prole, race hybride : peu employé souvent issu de nom ancien (antérieur au code). |
'132' => '350', // convarietas : si on le conscidère comme un rang intermédiaire entre la sous-espèce et la variété. Voir aussi n°200. |
'130' => '1', // infra3 : niveau infra-spécifique de troisième niveau, sans plus de précision. |
'140' => '360', // variété |
'142' => '380', // variété : hybride entre deux variétés d'une espèce non hybride. |
'143' => '390', // variété : variété d'espèce hybride sans spécification du rang parental (varietas) (voir ICBN, art. H.12.1); exemple : Populus x canadensis Moench var. marilandica (Poir.) Rehder. |
'144' => '380', // variété : variété hybride d'espèce hybride (nothovarietas) ; exemple : Salix x sepulcralis Simonk. nvar. chrysocoma (Dode) Meikle. |
'145' => '380', // variété hybride |
'150' => '410', // sous-variété |
'160' => '420', // forme |
'162' => '430', // forme : hybride entre deux formes d'une espèce non hybride. |
'163' => '430', // forme : forme d'espèce hybride sans spécification du rang parental (forma) (voir ICBN, art. H.12.1); exemple : Mentha x piperita L. f. hirsuta Sole. |
'164' => '430', // forme : forme hybride d'espèce hybride (nothoforma). |
'170' => '440', // sous-forme |
'200' => '450', // groupe de cultivar |
'210' => '460', // cultivar |
'220' => '470', // cultivar d'hybride |
'0' => '480' // clade |
); |
return $aso_rang[$code_rang]; |
} |
public function attribuerCodeInfra($str_abreviation_type_infra) |
{ |
$aso_code_infra = array('type' => '', 'code' => 0, 'rang' => 2 ); |
switch ($str_abreviation_type_infra) { |
case 'subgen.' : |
case 'subg.' : |
$aso_code_infra['rang'] = 180; |
break; |
case 'sect.' : |
$aso_code_infra['rang'] = 190; |
break; |
case 'gr.' : |
$aso_code_infra['rang'] = 230; |
break; |
case 'subsp.' : |
$aso_code_infra['type'] = 'infra1'; |
$aso_code_infra['code'] = 1; |
$aso_code_infra['rang'] = 280; |
break; |
case 'n-subsp.' : |
$aso_code_infra['type'] = 'infra1'; |
$aso_code_infra['code'] = 2; |
$aso_code_infra['rang'] = 300; |
break; |
case '[subsp.]' : |
$aso_code_infra['type'] = 'infra1'; |
$aso_code_infra['code'] = 3; |
$aso_code_infra['rang'] = 290; |
break; |
case '[n-subsp.]' : |
$aso_code_infra['type'] = 'infra1'; |
$aso_code_infra['code'] = 4; |
$aso_code_infra['rang'] = 310; |
break; |
case 'var.' : |
$aso_code_infra['type'] = 'infra2'; |
$aso_code_infra['code'] = 1; |
$aso_code_infra['rang'] = 360; |
break; |
case '[var.]' : |
$aso_code_infra['type'] = 'infra2'; |
$aso_code_infra['code'] = 2; |
$aso_code_infra['rang'] = 370; |
break; |
case 'n-var.' : |
$aso_code_infra['type'] = 'infra2'; |
$aso_code_infra['code'] = 3; |
$aso_code_infra['rang'] = 380; |
break; |
case 'nvar.' : |
$aso_code_infra['type'] = 'infra2'; |
$aso_code_infra['code'] = 3; |
$aso_code_infra['rang'] = 384; |
break; |
case '[n-var.]' : |
$aso_code_infra['type'] = 'infra2'; |
$aso_code_infra['code'] = 5; |
$aso_code_infra['rang'] = 390; |
break; |
case 'prol.' : |
case 'proles' : |
$aso_code_infra['type'] = 'infra3'; |
$aso_code_infra['code'] = 2; |
$aso_code_infra['rang'] = 330; |
break; |
case 'n-proles' : |
case 'n-proles.' : |
$aso_code_infra['type'] = 'infra3'; |
$aso_code_infra['code'] = 1; |
$aso_code_infra['rang'] = 340; |
break; |
case 'f.': |
case 'fa': |
case 'fa.': |
case 'forma': |
$aso_code_infra['type'] = 'infra3'; |
$aso_code_infra['code'] = 3; |
$aso_code_infra['rang'] = 420; |
break; |
case 'subvar.' : |
$aso_code_infra['type'] = 'infra3'; |
$aso_code_infra['code'] = 4; |
$aso_code_infra['rang'] = 410; |
break; |
case 'convar.' : |
$aso_code_infra['type'] = 'infra3'; |
$aso_code_infra['code'] = 5; |
$aso_code_infra['rang'] = 350; |
break; |
case 'cv.': |
case 'Cv.': |
$aso_code_infra['type'] = 'infra3'; |
$aso_code_infra['code'] = 6; |
$aso_code_infra['rang'] = 460; |
break; |
case 'n-f.': |
case 'n-fa': |
case 'n-fa.': |
$aso_code_infra['type'] = 'infra3'; |
$aso_code_infra['code'] = 7; |
$aso_code_infra['rang'] = 430; |
break; |
case 'subf.': |
case 'subfa': |
case 'subfa.': |
$aso_code_infra['type'] = 'infra3'; |
$aso_code_infra['code'] = 8; |
$aso_code_infra['rang'] = 440; |
break; |
default: |
$aso_code_infra['erreur_mark'] = 'erreur'; |
$aso_code_infra['erreur_notes'] = $str_abreviation_type_infra; |
$aso_code_infra['rang'] = 2; |
} |
return $aso_code_infra; |
} |
public function attribuerCodeRang($str_abreviation_type_infra) |
{ |
$aso_code_infra = $this->attribuerCodeInfra($str_abreviation_type_infra); |
return $aso_code_infra['rang']; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Script.php |
---|
New file |
0,0 → 1,42 |
<?php |
/** |
* La classe fournissant des méthodes communes aux scripts. |
* |
* @category php 5.2 |
* @package cel |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org) |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version $Id$ |
*/ |
class Script { |
private static $avancement = array(); |
/** |
* Utiliser cette méthode dans une boucle pour afficher un message suivi du nombre de tour de boucle effectué. |
* Vous devrez vous même gérer le retour à la ligne à la sortie de la boucle. |
* |
* @param string le message d'information. |
* @param int le nombre de départ à afficher. Par défaut 0. |
* @return void le message est affiché dans la console. |
*/ |
public function afficherAvancement($message, $depart = 0) { |
if (! isset(self::$avancement[$message])) { |
self::$avancement[$message] = $depart; |
print "$message : "; |
$actuel =& self::$avancement[$message]; |
print $actuel++; |
} else { |
$actuel =& self::$avancement[$message]; |
// Cas du passage de 99 (= 2 caractères) à 100 (= 3 caractères) |
$passage = (strlen((string) ($actuel - 1)) < strlen((string) ($actuel))) ? 1 : 0; |
print str_repeat(chr(8), (strlen((string) $actuel) - $passage)); |
print $actuel++; |
} |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/RechercheObservation.php |
---|
New file |
0,0 → 1,355 |
<?php |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurélien Peronnet <aurelien@tela-botania.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* in : utf8 |
* out : utf8 |
* |
* Librairie recherche d'observations a partir de divers critères |
* |
*/ |
class RechercheObservation extends Cel { |
public function obtenirIdObservationsPourOrdre($id_utilisateur, $ordre) { |
$requete_selection_id = 'SELECT id_observation FROM cel_obs WHERE ordre '; |
if(is_array($ordre)) { |
$ordre = array_map(array($this,'proteger'), $ordre); |
$requete_selection_id .= ' IN ('.implode(',',$ordre).') '; |
} else { |
$requete_selection_id .= ' = '.$this->proteger($ordre).' '; |
} |
$requete_selection_id .= ' AND ce_utilisateur = '.$this->proteger($id_utilisateur); |
$requete_selection_id .= ' ORDER BY id_observation'; |
$resultat_ids = $this->executerRequete($requete_selection_id); |
$ids = array(); |
if(is_array($resultat_ids)) { |
foreach ($resultat_ids as $resultat) { |
$ids[] = $resultat['id_observation']; |
} |
} |
return $ids; |
} |
public function rechercherObservations($id_utilisateur = null, $criteres = array(), $debut = 0, $limite = 50) { |
$requete_selection_observations = 'SELECT * FROM cel_obs '; |
if($id_utilisateur != null) { |
$requete_selection_observations .= 'WHERE ce_utilisateur = '.$this->proteger($id_utilisateur).' AND '; |
} else if(count($criteres) > 0) { |
$requete_selection_observations .= 'WHERE '; |
} |
$sous_requete_recherche = $this->fabriquerSousRequeteRecherche($id_utilisateur, $criteres); |
$requete_selection_observations .= $sous_requete_recherche; |
$requete_selection_observations = rtrim($requete_selection_observations, 'AND '); |
$requete_selection_observations .= $id_utilisateur == null ? ' ORDER BY id_observation, ordre ' : ' ORDER BY ordre '; |
$requete_selection_observations .= ($debut == 0 && $limite == 0) ? '' : ' LIMIT '.$debut.','.$limite ; |
$resultats_observations = array(); |
$resultats_observations = $this->executerRequete($requete_selection_observations); |
return $resultats_observations; |
} |
public function compterObservations($id_utilisateur = null, $criteres = array()) { |
$requete_selection_observations = 'SELECT COUNT(*) as nb_obs FROM cel_obs '; |
if($id_utilisateur != null) { |
$requete_selection_observations .= 'WHERE ce_utilisateur = '.$this->proteger($id_utilisateur).' AND '; |
} else if(count($criteres) > 0) { |
$requete_selection_observations .= 'WHERE '; |
} |
$sous_requete_recherche = $this->fabriquerSousRequeteRecherche($id_utilisateur, $criteres); |
$requete_selection_observations .= $sous_requete_recherche; |
$requete_selection_observations = rtrim($requete_selection_observations, 'AND '); |
$nb_obs = '0'; |
$resultat_requete_nombre_observations = $this->executerRequete($requete_selection_observations); |
if($resultat_requete_nombre_observations && is_array($resultat_requete_nombre_observations) && count($resultat_requete_nombre_observations) > 0) { |
$nb_obs = $resultat_requete_nombre_observations[0]['nb_obs']; |
} |
return $nb_obs; |
} |
public function formaterPourEnvoiCel($tableau_observations) { |
$ids = array(); |
foreach($tableau_observations as &$observation) { |
$observation['ce_zone_geo'] = $this->convertirCodeZoneGeoVersCodeInsee($observation['ce_zone_geo']); |
$ids_mots_cles = $this->getIdsMotsClesObservation($observation['id_observation']); |
$ids[] = $observation['id_observation']; |
$mots_cles_chaine = ''; |
foreach($ids_mots_cles as $id_mot_cle) { |
$mots_cles_chaine .= $id_mot_cle['id_mot_cle_obs'].';'; |
} |
$mots_cles_chaine = rtrim($mots_cles_chaine,';'); |
$observation['mots_cles'] = $mots_cles_chaine; |
foreach($observation as $champ => $valeur) { |
if($valeur == 'NULL') { |
$observation[$champ] = ""; |
} |
} |
} |
$gestion_champs_etendus = new GestionChampsEtendus($this->config, 'obs'); |
$champs_supp = $gestion_champs_etendus->obtenirChampsEtendusPourElementsMultiples($ids); |
foreach($tableau_observations as &$obs) { |
if(isset($champs_supp[$obs['id_observation']])) { |
$obs['obs_etendue'] = $champs_supp[$obs['id_observation']]; |
} |
} |
return $tableau_observations; |
} |
public function obtenirCourrielUtilisateurPourIdObs($id_obs) { |
$requete = 'SELECT courriel_utilisateur FROM cel_obs WHERE '. |
'id_observation = '.$this->proteger($id_obs); |
$utilisateur_courriel = $this->executerRequete($requete); |
$retour = false; |
if(!empty($utilisateur_courriel) && isset($utilisateur_courriel[0]['courriel_utilisateur'])) { |
$retour = $utilisateur_courriel[0]['courriel_utilisateur']; |
} |
return $retour; |
} |
private function getIdsMotsClesObservation($id_observation) { |
$requete_selection_mots_cles = 'SELECT DISTINCT id_mot_cle_obs '. |
'FROM cel_obs_mots_cles '. |
'WHERE id_observation = '.$id_observation; |
return $this->executerRequete($requete_selection_mots_cles); |
} |
// TODO: fonction temporaire |
public function parserRequeteCriteres($chaine_criteres) { |
$criteres_parses = array(); |
$criteres = explode("&", $chaine_criteres) ; |
foreach($criteres as &$critere) { |
$nom_valeur = explode("=",$critere) ; |
if(count($nom_valeur) >= 2) { |
$criteres_parses[$nom_valeur[0]] = $nom_valeur[1]; |
} |
} |
return $criteres_parses; |
} |
private function fabriquerSousRequeteRecherche($id_utilisateur, $criteres) { |
$sous_requete = ''; |
foreach ($criteres as $nom => $valeur) |
{ |
if($valeur == null || trim($nom) == "" || trim($valeur) == "") { |
continue; |
} |
switch ($nom) { |
case "mots_cles"; |
$sous_requete .= $this->creerSousRequeteMotsCles($valeur); |
$sous_requete .= ' AND '; |
break; |
case 'annee': |
if($valeur == "NULL") { |
$sous_requete .= "(date_observation IS NULL OR year(date_observation) = 0000)" ; |
} else { |
$sous_requete .= "(year(date_observation) = ".$this->proteger($valeur).")" ; |
} |
$sous_requete .= ' AND ' ; |
break; |
case 'mois': |
if($valeur == "NULL") { |
$sous_requete .= "date_observation IS NULL OR month(date_observation) = 00" ; |
} else { |
$sous_requete .= "month(date_observation) = ".$this->proteger($valeur) ; |
} |
$sous_requete .= ' AND ' ; |
break; |
case 'jour': |
if($valeur == "NULL") { |
$sous_requete .= "date_observation IS NULL OR day(date_observation) = 00" ; |
} else { |
$sous_requete .= "day(date_observation) = ".$this->proteger($valeur) ; |
} |
$sous_requete .= ' AND ' ; |
break; |
case 'departement': |
if($valeur == "NULL") { |
$sous_requete .= "(ce_zone_geo IS NULL OR ce_zone_geo = '')"; |
} else { |
if(strpos($valeur,',') !== false) { |
$dpts = explode(',',$valeur); |
$sous_requete .= '('; |
foreach($dpts as $dpt) { |
$sous_requete .= "ce_zone_geo LIKE ".$this->proteger('INSEE-C:'.$dpt.'___').' OR '; |
} |
$sous_requete = rtrim($sous_requete,' OR ').') '; |
} else { |
$sous_requete .= "(ce_zone_geo LIKE ".$this->proteger('INSEE-C:'.$valeur.'___').')'; |
} |
} |
$sous_requete .= ' AND ' ; |
break; |
case 'commune': |
if($valeur == "NULL") { |
$sous_requete .= "(zone_geo IS NULL OR zone_geo = '')"; |
} else { |
$sous_requete .= "(zone_geo = ".$this->proteger($valeur).')'; |
} |
$sous_requete .= ' AND ' ; |
break; |
case 'id_mots_cles': |
$liste_mc = '"'.str_replace(';','","',$valeur).'"'; |
$sous_requete .= '' ; |
$sous_requete .= 'id_observation IN (SELECT id_observation FROM cel_obs_mots_cles WHERE id_mot_cle_obs IN ('.$liste_mc.'))'; |
$sous_requete .= ' AND ' ; |
break; |
case 'recherche': |
$sous_requete .= $this->fabriquerSousRequeteRechercheGenerale($id_utilisateur, $valeur); |
$sous_requete .= ' AND '; |
break; |
case 'date_debut': |
$sous_requete .= 'date_observation >= '.$this->proteger($this->formaterEnDateMysql($valeur)); |
$sous_requete .= ' AND '; |
break; |
case 'date_fin': |
$sous_requete .= 'date_observation <= '.$this->proteger($this->formaterEnDateMysql($valeur)); |
$sous_requete .= ' AND '; |
break; |
case 'taxon': |
$valeur_protegee = $this->proteger($valeur."%"); |
$sous_requete .= "( nom_sel LIKE ".$valeur_protegee." OR". |
" nom_ret LIKE ".$valeur_protegee." OR". |
" famille LIKE ".$valeur_protegee. |
" ) AND "; |
break; |
default: |
if(trim($nom) != '') |
{ |
$sous_requete .= $nom." = ".$this->proteger($valeur) ; |
$sous_requete .= ' AND ' ; |
} |
if(trim($nom) == "NULL") { |
$sous_requete .= "(".$nom." IS NULL OR ".$nom." = '')" ; |
$sous_requete .= ' AND ' ; |
} |
break; |
} |
} |
$sous_requete = rtrim($sous_requete,' AND '); |
return $sous_requete; |
} |
private function formaterEnDateMysql($date) { |
$annee = substr($date, 6, 4); |
$mois = substr($date, 3, 2); |
$jour = substr($date, 0, 2); |
$date = $annee . '-' . $mois . '-' . $jour; |
return $date; |
} |
private function fabriquerSousRequeteRechercheGenerale($id_utilisateur, $valeur) { |
$valeur = str_replace("*","%",$valeur); |
$valeur = $this->proteger('%'.$valeur.'%'); |
$sous_requete = "(nom_sel LIKE ".$valeur. |
" OR courriel_utilisateur LIKE ".$valeur. |
" OR prenom_utilisateur LIKE ".$valeur. |
" OR nom_utilisateur LIKE ".$valeur. |
" OR nom_sel LIKE ".$valeur. |
" OR nom_sel_nn LIKE ".$valeur. |
" OR nom_ret LIKE ".$valeur. |
" OR nom_ret_nn LIKE ".$valeur. |
" OR nt LIKE ".$valeur. |
" OR famille LIKE ".$valeur. |
" OR zone_geo LIKE ".$valeur. |
" OR ce_zone_geo LIKE ".$valeur. |
" OR date_observation LIKE ".$valeur. |
" OR lieudit LIKE ".$valeur. |
" OR station LIKE ".$valeur. |
" OR milieu LIKE ".$valeur. |
" OR commentaire LIKE ".$valeur. |
" OR transmission LIKE ".$valeur. |
" OR latitude LIKE ".$valeur. |
" OR longitude LIKE ".$valeur. |
" OR mots_cles_texte LIKE ".$valeur. |
")"; |
return $sous_requete; |
} |
private function creerSousRequeteMotsCles($mot_cle) { |
$requete = ''; |
if (preg_match('/.*OU.*/', $mot_cle)) { |
$mots_cles_tab = explode('OU',$mot_cle); |
foreach($mots_cles_tab as $mot_cle_item) { |
$requete .= '(mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') OR '; |
} |
$requete = '('.rtrim($requete,'OR ').')'; |
} else if (preg_match('/.*ET.*/', $mot_cle)) { |
$mots_cles_tab = explode('ET',$mot_cle); |
foreach($mots_cles_tab as $mot_cle_item) { |
$requete .= '(mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') AND '; |
} |
$requete = '('.rtrim($requete, 'AND ').') '; |
} else { |
$requete = "(mots_cles_texte LIKE ".$this->proteger('%'.$mot_cle.'%').') '; |
} |
return $requete; |
} |
private function estUnvaleurZeroNulle($valeur) { |
return $valeur == "000null"; |
} |
private function traiterRequeteValeurZeroNulle($valeur) { |
$champs = array('annee' => 'date_observation', |
'mois' => 'date_observation', |
'jour' => 'date_observation', |
'departement' => 'ce_zone_geo', |
'commune' => 'zone_geo' |
); |
return $sous_requete .= $champs[$valeur]." = ".$this->proteger(""); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/ExtracteurMetadonnees.php |
---|
New file |
0,0 → 1,652 |
<?php |
/** |
* Classe d'extraction de metadonnées afin de les mettre dans |
* un tableau au format du cel |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* @author Aurélien PERONNET <aurelien@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2012, Tela Botanica |
*/ |
class ExtracteurMetadonnees { |
private $meta = array(); |
private $tableau_ids_tags_exif = array( |
'InteropIndex' => '1', |
'InteropVersion' => '2', |
'ProcessingSoftware' => '11', |
'SubfileType' => '254', |
'OldSubfileType' => '255', |
'ImageWidth' => '256', |
'ImageHeight' => '257', |
'BitsPerSample' => '258', |
'Compression' => '259', |
'PhotometricInterpretation' => '262', |
'Thresholding' => '263', |
'CellWidth' => '264', |
'CellLength' => '265', |
'FillOrder' => '266', |
'DocumentName' => '269', |
'ImageDescription' => '270', |
'Make' => '271', |
'Model' => '272', |
'StripOffsets' => '273', |
'Orientation' => '274', |
'SamplesPerPixel' => '277', |
'RowsPerStrip' => '278', |
'StripByteCounts' => '279', |
'MinSampleValue' => '280', |
'MaxSampleValue' => '281', |
'XResolution' => '282', |
'YResolution' => '283', |
'PlanarConfiguration' => '284', |
'PageName' => '285', |
'XPosition' => '286', |
'YPosition' => '287', |
'FreeOffsets' => '288', |
'FreeByteCounts' => '289', |
'GrayResponseUnit' => '290', |
'GrayResponseCurve' => '291', |
'T4Options' => '292', |
'T6Options' => '293', |
'ResolutionUnit' => '296', |
'PageNumber' => '297', |
'ColorResponseUnit' => '300', |
'TransferFunction' => '301', |
'Software' => '305', |
'ModifyDate' => '306', |
'Artist' => '315', |
'HostComputer' => '316', |
'Predictor' => '317', |
'WhitePoint' => '318', |
'PrimaryChromaticities' => '319', |
'ColorMap' => '320', |
'HalftoneHints' => '321', |
'TileWidth' => '322', |
'TileLength' => '323', |
'TileOffsets' => '324', |
'TileByteCounts' => '325', |
'BadFaxLines' => '326', |
'CleanFaxData' => '327', |
'ConsecutiveBadFaxLines' => '328', |
'SubIFD' => '330', |
'InkSet' => '332', |
'InkNames' => '333', |
'NumberofInks' => '334', |
'DotRange' => '336', |
'TargetPrinter' => '337', |
'ExtraSamples' => '338', |
'SampleFormat' => '339', |
'SMinSampleValue' => '340', |
'SMaxSampleValue' => '341', |
'TransferRange' => '342', |
'ClipPath' => '343', |
'XClipPathUnits' => '344', |
'YClipPathUnits' => '345', |
'Indexed' => '346', |
'JPEGTables' => '347', |
'OPIProxy' => '351', |
'GlobalParametersIFD' => '400', |
'ProfileType' => '401', |
'FaxProfile' => '402', |
'CodingMethods' => '403', |
'VersionYear' => '404', |
'ModeNumber' => '405', |
'Decode' => '433', |
'DefaultImageColor' => '434', |
'T82Options' => '435', |
'JPEGTables' => '437', |
'JPEGProc' => '512', |
'ThumbnailOffset' => '513', |
'ThumbnailLength' => '514', |
'JPEGRestartInterval' => '515', |
'JPEGLosslessPredictors' => '517', |
'JPEGPointTransforms' => '518', |
'JPEGQTables' => '519', |
'JPEGDCTables' => '520', |
'JPEGACTables' => '521', |
'YCbCrCoefficients' => '529', |
'YCbCrSubSampling' => '530', |
'YCbCrPositioning' => '531', |
'ReferenceBlackWhite' => '532', |
'StripRowCounts' => '559', |
'ApplicationNotes' => '700', |
'USPTOMiscellaneous' => '999', |
'RelatedImageFileFormat' => '4096', |
'RelatedImageWidth' => '4097', |
'RelatedImageHeight' => '4098', |
'Rating' => '18246', |
'XP_DIP_XML' => '18247', |
'StitchInfo' => '18248', |
'RatingPercent' => '18249', |
'ImageID' => '32781', |
'WangTag1' => '32931', |
'WangAnnotation' => '32932', |
'WangTag3' => '32933', |
'WangTag4' => '32934', |
'Matteing' => '32995', |
'DataType' => '32996', |
'ImageDepth' => '32997', |
'TileDepth' => '32998', |
'Model2' => '33405', |
'CFARepeatPatternDim' => '33421', |
'CFAPattern2' => '33422', |
'BatteryLevel' => '33423', |
'KodakIFD' => '33424', |
'Copyright' => '33432', |
'ExposureTime' => '33434', |
'FNumber' => '33437', |
'MDFileTag' => '33445', |
'MDScalePixel' => '33446', |
'MDColorTable' => '33447', |
'MDLabName' => '33448', |
'MDSampleInfo' => '33449', |
'MDPrepDate' => '33450', |
'MDPrepTime' => '33451', |
'MDFileUnits' => '33452', |
'PixelScale' => '33550', |
'AdventScale' => '33589', |
'AdventRevision' => '33590', |
'UIC1Tag' => '33628', |
'UIC2Tag' => '33629', |
'UIC3Tag' => '33630', |
'UIC4Tag' => '33631', |
'IPTC-NAA' => '33723', |
'IntergraphPacketData' => '33918', |
'IntergraphFlagRegisters' => '33919', |
'IntergraphMatrix' => '33920', |
'INGRReserved' => '33921', |
'ModelTiePoint' => '33922', |
'Site' => '34016', |
'ColorSequence' => '34017', |
'IT8Header' => '34018', |
'RasterPadding' => '34019', |
'BitsPerRunLength' => '34020', |
'BitsPerExtendedRunLength' => '34021', |
'ColorTable' => '34022', |
'ImageColorIndicator' => '34023', |
'BackgroundColorIndicator' => '34024', |
'ImageColorValue' => '34025', |
'BackgroundColorValue' => '34026', |
'PixelIntensityRange' => '34027', |
'TransparencyIndicator' => '34028', |
'ColorCharacterization' => '34029', |
'HCUsage' => '34030', |
'TrapIndicator' => '34031', |
'CMYKEquivalent' => '34032', |
'SEMInfo' => '34118', |
'AFCP_IPTC' => '34152', |
'PixelMagicJBIGOptions' => '34232', |
'ModelTransform' => '34264', |
'WB_GRGBLevels' => '34306', |
'LeafData' => '34310', |
'PhotoshopSettings' => '34377', |
'ExifOffset' => '34665', |
'ICC_Profile' => '34675', |
'TIFF_FXExtensions' => '34687', |
'MultiProfiles' => '34688', |
'SharedData' => '34689', |
'T88Options' => '34690', |
'ImageLayer' => '34732', |
'GeoTiffDirectory' => '34735', |
'GeoTiffDoubleParams' => '34736', |
'GeoTiffAsciiParams' => '34737', |
'ExposureProgram' => '34850', |
'SpectralSensitivity' => '34852', |
'GPSInfo' => '34853', |
'ISO' => '34855', |
'Opto-ElectricConvFactor' => '34856', |
'Interlace' => '34857', |
'TimeZoneOffset' => '34858', |
'SelfTimerMode' => '34859', |
'SensitivityType' => '34864', |
'StandardOutputSensitivity' => '34865', |
'RecommendedExposureIndex' => '34866', |
'ISOSpeed' => '34867', |
'ISOSpeedLatitudeyyy' => '34868', |
'ISOSpeedLatitudezzz' => '34869', |
'FaxRecvParams' => '34908', |
'FaxSubAddress' => '34909', |
'FaxRecvTime' => '34910', |
'LeafSubIFD' => '34954', |
'ExifVersion' => '36864', |
'DateTimeOriginal' => '36867', |
'CreateDate' => '36868', |
'ComponentsConfiguration' => '37121', |
'CompressedBitsPerPixel' => '37122', |
'ShutterSpeedValue' => '37377', |
'ApertureValue' => '37378', |
'BrightnessValue' => '37379', |
'ExposureCompensation' => '37380', |
'MaxApertureValue' => '37381', |
'SubjectDistance' => '37382', |
'MeteringMode' => '37383', |
'LightSource' => '37384', |
'Flash' => '37385', |
'FocalLength' => '37386', |
'FlashEnergy' => '37387', |
'SpatialFrequencyResponse' => '37388', |
'Noise' => '37389', |
'FocalPlaneXResolution' => '37390', |
'FocalPlaneYResolution' => '37391', |
'FocalPlaneResolutionUnit' => '37392', |
'ImageNumber' => '37393', |
'SecurityClassification' => '37394', |
'ImageHistory' => '37395', |
'SubjectArea' => '37396', |
'ExposureIndex' => '37397', |
'TIFF-EPStandardID' => '37398', |
'SensingMethod' => '37399', |
'CIP3DataFile' => '37434', |
'CIP3Sheet' => '37435', |
'CIP3Side' => '37436', |
'StoNits' => '37439', |
'MakerNoteCanon' => '37500', |
'UserComment' => '37510', |
'SubSecTime' => '37520', |
'SubSecTimeOriginal' => '37521', |
'SubSecTimeDigitized' => '37522', |
'MSDocumentText' => '37679', |
'MSPropertySetStorage' => '37680', |
'MSDocumentTextPosition' => '37681', |
'ImageSourceData' => '37724', |
'XPTitle' => '40091', |
'XPComment' => '40092', |
'XPAuthor' => '40093', |
'XPKeywords' => '40094', |
'XPSubject' => '40095', |
'FlashpixVersion' => '40960', |
'ColorSpace' => '40961', |
'ExifImageWidth' => '40962', |
'ExifImageHeight' => '40963', |
'RelatedSoundFile' => '40964', |
'InteropOffset' => '40965', |
'FlashEnergy' => '41483', |
'SpatialFrequencyResponse' => '41484', |
'Noise' => '41485', |
'FocalPlaneXResolution' => '41486', |
'FocalPlaneYResolution' => '41487', |
'FocalPlaneResolutionUnit' => '41488', |
'ImageNumber' => '41489', |
'SecurityClassification' => '41490', |
'ImageHistory' => '41491', |
'SubjectLocation' => '41492', |
'ExposureIndex' => '41493', |
'TIFF-EPStandardID' => '41494', |
'SensingMethod' => '41495', |
'FileSource' => '41728', |
'SceneType' => '41729', |
'CFAPattern' => '41730', |
'CustomRendered' => '41985', |
'ExposureMode' => '41986', |
'WhiteBalance' => '41987', |
'DigitalZoomRatio' => '41988', |
'FocalLengthIn35mmFormat' => '41989', |
'SceneCaptureType' => '41990', |
'GainControl' => '41991', |
'Contrast' => '41992', |
'Saturation' => '41993', |
'Sharpness' => '41994', |
'DeviceSettingDescription' => '41995', |
'SubjectDistanceRange' => '41996', |
'ImageUniqueID' => '42016', |
'OwnerName' => '42032', |
'SerialNumber' => '42033', |
'LensInfo' => '42034', |
'LensMake' => '42035', |
'LensModel' => '42036', |
'LensSerialNumber' => '42037', |
'GDALMetadata' => '42112', |
'GDALNoData' => '42113', |
'Gamma' => '42240', |
'ExpandSoftware' => '44992', |
'ExpandLens' => '44993', |
'ExpandFilm' => '44994', |
'ExpandFilterLens' => '44995', |
'ExpandScanner' => '44996', |
'ExpandFlashLamp' => '44997', |
'PixelFormat' => '48129', |
'Transformation' => '48130', |
'Uncompressed' => '48131', |
'ImageType' => '48132', |
'ImageWidth' => '48256', |
'ImageHeight' => '48257', |
'WidthResolution' => '48258', |
'HeightResolution' => '48259', |
'ImageOffset' => '48320', |
'ImageByteCount' => '48321', |
'AlphaOffset' => '48322', |
'AlphaByteCount' => '48323', |
'ImageDataDiscard' => '48324', |
'AlphaDataDiscard' => '48325', |
'OceScanjobDesc' => '50215', |
'OceApplicationSelector' => '50216', |
'OceIDNumber' => '50217', |
'OceImageLogic' => '50218', |
'Annotations' => '50255', |
'PrintIM' => '50341', |
'USPTOOriginalContentType' => '50560', |
'DNGVersion' => '50706', |
'DNGBackwardVersion' => '50707', |
'UniqueCameraModel' => '50708', |
'LocalizedCameraModel' => '50709', |
'CFAPlaneColor' => '50710', |
'CFALayout' => '50711', |
'LinearizationTable' => '50712', |
'BlackLevelRepeatDim' => '50713', |
'BlackLevel' => '50714', |
'BlackLevelDeltaH' => '50715', |
'BlackLevelDeltaV' => '50716', |
'WhiteLevel' => '50717', |
'DefaultScale' => '50718', |
'DefaultCropOrigin' => '50719', |
'DefaultCropSize' => '50720', |
'ColorMatrix1' => '50721', |
'ColorMatrix2' => '50722', |
'CameraCalibration1' => '50723', |
'CameraCalibration2' => '50724', |
'ReductionMatrix1' => '50725', |
'ReductionMatrix2' => '50726', |
'AnalogBalance' => '50727', |
'AsShotNeutral' => '50728', |
'AsShotWhiteXY' => '50729', |
'BaselineExposure' => '50730', |
'BaselineNoise' => '50731', |
'BaselineSharpness' => '50732', |
'BayerGreenSplit' => '50733', |
'LinearResponseLimit' => '50734', |
'CameraSerialNumber' => '50735', |
'DNGLensInfo' => '50736', |
'ChromaBlurRadius' => '50737', |
'AntiAliasStrength' => '50738', |
'ShadowScale' => '50739', |
'SR2Private' => '50740', |
'MakerNoteSafety' => '50741', |
'RawImageSegmentation' => '50752', |
'CalibrationIlluminant1' => '50778', |
'CalibrationIlluminant2' => '50779', |
'BestQualityScale' => '50780', |
'RawDataUniqueID' => '50781', |
'AliasLayerMetadata' => '50784', |
'OriginalRawFileName' => '50827', |
'OriginalRawFileData' => '50828', |
'ActiveArea' => '50829', |
'MaskedAreas' => '50830', |
'AsShotICCProfile' => '50831', |
'AsShotPreProfileMatrix' => '50832', |
'CurrentICCProfile' => '50833', |
'CurrentPreProfileMatrix' => '50834', |
'ColorimetricReference' => '50879', |
'PanasonicTitle' => '50898', |
'PanasonicTitle2' => '50899', |
'CameraCalibrationSig' => '50931', |
'ProfileCalibrationSig' => '50932', |
'ProfileIFD' => '50933', |
'AsShotProfileName' => '50934', |
'NoiseReductionApplied' => '50935', |
'ProfileName' => '50936', |
'ProfileHueSatMapDims' => '50937', |
'ProfileHueSatMapData1' => '50938', |
'ProfileHueSatMapData2' => '50939', |
'ProfileToneCurve' => '50940', |
'ProfileEmbedPolicy' => '50941', |
'ProfileCopyright' => '50942', |
'ForwardMatrix1' => '50964', |
'ForwardMatrix2' => '50965', |
'PreviewApplicationName' => '50966', |
'PreviewApplicationVersion' => '50967', |
'PreviewSettingsName' => '50968', |
'PreviewSettingsDigest' => '50969', |
'PreviewColorSpace' => '50970', |
'PreviewDateTime' => '50971', |
'RawImageDigest' => '50972', |
'OriginalRawFileDigest' => '50973', |
'SubTileBlockSize' => '50974', |
'RowInterleaveFactor' => '50975', |
'ProfileLookTableDims' => '50981', |
'ProfileLookTableData' => '50982', |
'OpcodeList1' => '51008', |
'OpcodeList2' => '51009', |
'OpcodeList3' => '51022', |
'NoiseProfile' => '51041', |
'Padding' => '59932', |
'OffsetSchema' => '59933', |
'OwnerName' => '65000', |
'SerialNumber' => '65001', |
'Lens' => '65002', |
'KDC_IFD' => '65024', |
'RawFile' => '65100', |
'Converter' => '65101', |
'WhiteBalance' => '65102', |
'Exposure' => '65105', |
'Shadows' => '65106', |
'Brightness' => '65107', |
'Contrast' => '65108', |
'Saturation' => '65109', |
'Sharpness' => '65110', |
'Smoothness' => '65111', |
'MoireFilter' => '65112', |
); |
public function extraireMetadonnees($cheminImage) { |
if ($this->peutUtiliserExifTool()) { |
$this->meta = $this->decoderMetadonneesExifTool($cheminImage); |
} else { |
$this->meta = $this->decoderMetadonneesBasique($cheminImage); |
} |
$metadonnees = array(); |
$metadonnees['hauteur'] = $this->obtenirHauteur(); |
$metadonnees['largeur'] = $this->obtenirLargeur(); |
$metadonnees['date_prise_de_vue'] = $this->obtenirDatePriseDeVue(); |
$metadonnees['appareil_fabriquant'] = $this->obtenirAppareilFabricant(); |
$metadonnees['appareil_modele'] = $this->obtenirAppareilModele(); |
$metadonnees['meta_exif'] = $this->convertirMetaVersXML('EXIF'); |
$metadonnees['meta_iptc'] = $this->convertirMetaVersXML('IPTC'); |
$metadonnees['meta_xmp'] = $this->convertirMetaVersXML('XMP'); |
$metadonnees['meta_makernote'] = $this->convertirMetaVersXML('MAKERNOTE'); |
return $metadonnees; |
} |
private function peutUtiliserExifTool() { |
// TODO indiquer ceci dans un fichier de config |
return file_exists('/usr/bin/exiftool') && is_executable('/usr/bin/exiftool'); |
} |
private function decoderMetadonneesExifTool($cheminImage) { |
$metadata = array(); |
$res = exec('/usr/bin/exiftool -g -D '.$cheminImage, $metadata); |
$metadata_decodees = array(); |
$categorie = ''; |
foreach($metadata as &$data) { |
if ($this->estUnSeparateurCategorieExifTool($data)) { |
$categorie = trim(str_replace('----', '', $data)); |
} else { |
$data_decodee = $this->parserValeurMetadonneeExifTool($data); |
$cle_metadonnee = str_replace(' ', '', $data_decodee['cle']); |
$metadata_decodees[$categorie][$cle_metadonnee] = $data_decodee; |
} |
} |
return $metadata_decodees; |
} |
private function estUnSeparateurCategorieExifTool($data) { |
return preg_match('^---- (.)* ----^',$data); |
} |
private function parserValeurMetadonneeExifTool($data) { |
$cle_valeur = explode(':',$data,2); |
$valeur = ''; |
if(count($cle_valeur) == 2) { |
$valeur = trim($cle_valeur[1]); |
} |
$id_cle = explode(' ',trim($cle_valeur[0]),2); |
$id_cle[1] = str_replace(array('-','/'),'',$id_cle[1]); |
$cle_id_valeur = array('cle' => $id_cle[1], 'id' => str_replace('-','',$id_cle[0]), 'valeur' => $valeur); |
return $cle_id_valeur; |
} |
public function decoderMetadonneesBasique($chemin_fichier) { |
$exif = @exif_read_data($chemin_fichier, "EXIF,COMPUTED,IFD0,FILE,COMMENT", true, false); |
// tant pis pour les makernote et xmp, les décoder demande trop de librairies externes, autant installer exiftool alors |
$metadonnees = array(); |
$metadonnees['XMP'] = array(); |
unset($metadonnees['EXIF']['MakerNote']); |
$metadonnees['MAKERNOTE'] = array(); |
$metadonnees_non_formatees = array(); |
if(isset($exif['EXIF'])) { |
$metadonnees_non_formatees = array_merge($metadonnees_non_formatees, $exif['EXIF']); |
} |
if(isset($exif['IFD0'])) { |
$metadonnees_non_formatees = array_merge($metadonnees_non_formatees, $exif['IFD0']); |
} |
$metadonnees['EXIF'] = $this->formaterTableauExif(&$metadonnees_non_formatees); |
$metadonnees['IPTC'] = $this->extraireIptc($chemin_fichier); |
$metadonnees['File'] = array( |
'ImageWidth' => array('id' => '', 'valeur' => $exif['COMPUTED']['Width']), |
'ImageHeight' => array('id' => '', 'valeur' => $exif['COMPUTED']['Height'])); |
return $metadonnees ; |
} |
private function formaterTableauExif($tableau) { |
$tableau_exif_formate = array(); |
foreach ($tableau as $nom_tag => $valeur) { |
$id = ''; |
if (isset($this->tableau_ids_tags_exif[$nom_tag])) { |
$id = $this->tableau_ids_tags_exif[$nom_tag]; |
} |
$tableau_exif_formate[$nom_tag] = array('id' => $id, 'valeur' => $valeur); |
} |
return $tableau_exif_formate; |
} |
/** |
* Extraction des metadonnées iptc |
**/ |
public function extraireIptc($chemin_fichier) { |
$meta = array(); |
// getimagesize renvoie les infos iptc dans le tableau info |
$info = array(); |
$size = getimagesize($chemin_fichier, $info); |
// s'il existe |
if (isset($info["APP13"])) { |
// on parse les donnees |
$iptc = iptcparse($info["APP13"]); |
if ($iptc) { |
// et on les analyse |
foreach ($iptc as $marker => $section) { |
foreach ($section as $nom => $val) { |
// pour remplir le tableau de donnees |
$this->decoderValeurIptc($marker, $val, &$meta); |
} |
} |
} |
} |
return $meta; |
} |
/** |
* Stocke une valeur de metadonnées iptc dans le champ du tableau correspondant |
* @param String $nom nom de la valeur |
* @param String $val valeur |
* @param String $data référence vers le tableau où la donnée sera stockée |
**/ |
private function decoderValeurIptc($nom, $val, $data_tab) { |
switch ($nom) { |
case "2#005" :// mots cles iptc |
$data_tab['Category'] = array('id' => '5', 'valeur' => $val); |
break; |
case "2#080" :// champ by line |
$data_tab['By-Line'] = array('id' => '80', 'valeur' => $val); |
break ; |
case "2#085" :// champ by line titre |
$data_tab['By-LineTitle'] = array('id' => '85', 'valeur' => $val); |
break ; |
case "2#090" :// ville |
$data_tab['City'] = array('id' => '90', 'valeur' => $val); |
break ; |
case "2#092" :// sous location |
$data_tab['SubLocation'] = array('id' => '92', 'valeur' => $val); |
break ; |
case "2#095" :// etat (pour les us) |
$data_tab['ProvinceState'] = array('id' => '95', 'valeur' => $val); |
break ; |
case "2#100" :// code pays |
$data_tab['CountryPrimaryLocationCode'] = array('id' => '100', 'valeur' => $val); |
break ; |
case "2#101" :// code pays |
$data_tab['CountryName'] = array('id' => '101', 'valeur' => $val); |
break ; |
case "2#105" :// titre principal |
$data_tab['Headline'] = array('id' => '105', 'valeur' => $val); |
break ; |
case "2#110" :// credit |
$data_tab['Credit'] = array('id' => '110', 'valeur' => $val); |
break ; |
case "2#116" :// copyright |
$data_tab['CopyrightNotice'] = array('id' => '116', 'valeur' => $val); |
break ; |
case "2#118" :// contact |
$data_tab['Contact'] = array('id' => '118', 'valeur' => $val); |
break ; |
default: |
unset($data_tab['nom']); |
} |
} |
private function obtenirHauteur() { |
$hauteur = isset($this->meta['File']['ImageHeight']) ? $this->meta['File']['ImageHeight']['valeur'] : ''; |
return $hauteur; |
} |
private function obtenirLargeur() { |
$largeur = isset($this->meta['File']['ImageWidth']) ? $this->meta['File']['ImageWidth']['valeur'] : ''; |
return $largeur; |
} |
private function obtenirDatePriseDeVue() { |
$date = isset($this->meta['EXIF']['DateTimeOriginal']) ? $this->meta['EXIF']['DateTimeOriginal']['valeur'] : ''; |
return $date; |
} |
private function obtenirAppareilFabricant() { |
$fabriquant = isset($this->meta['EXIF']['Make']) ? $this->meta['EXIF']['Make']['valeur'] : ''; |
return $fabriquant; |
} |
private function obtenirAppareilModele() { |
$modele = isset($this->meta['EXIF']['CameraModelName']) ? $this->meta['EXIF']['CameraModelName']['valeur'] : ''; |
return $modele; |
} |
private function convertirMetaVersXML($type) { |
$xml = null; |
if (isset($this->meta[$type])) { |
$racine = strtolower($type); |
$xml = '<?xml version="1.0" encoding="UTF-8" ?>'."\n"; |
$xml .= "<$racine>"."\n"; |
foreach ($this->meta[$type] as $prop => &$valeur) { |
$xml .= '<'.$prop.' id="'.$valeur['id'].'">'.$valeur['valeur'].'</'.$prop.'>'."\n"; |
} |
$xml .= "</$racine>"; |
} |
return $xml; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/PDF.php |
---|
New file |
0,0 → 1,3001 |
<?php |
/** |
* File_PDF:: |
* |
* The File_PDF:: class provides a PHP-only implementation of a PDF library. |
* No external libs or PHP extensions are required. |
* |
* Based on the FPDF class by Olivier Plathey (http://www.fpdf.org). |
* |
* Copyright 2001-2003 Olivier Plathey <olivier@fpdf.org> |
* Copyright 2003-2007 The Horde Project (http://www.horde.org/) |
* |
* See the enclosed file COPYING for license information (LGPL). If you |
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. |
* |
* $Horde: framework/File_PDF/PDF.php,v 1.48 2007/01/05 13:12:21 jan Exp $ |
* |
* @author Olivier Plathey <olivier@fpdf.org> |
* @author Marko Djukic <marko@oblo.com> |
* @author Jan Schneider <jan@horde.org> |
* @package File_PDF |
* @category Fileformats |
*/ |
class File_PDF { |
/** |
* Current page number. |
* |
* @var integer |
*/ |
var $_page = 0; |
/** |
* Current object number. |
* |
* @var integer |
*/ |
var $_n = 2; |
/** |
* Array of object offsets. |
* |
* @var array |
*/ |
var $_offsets = array(); |
/** |
* Buffer holding in-memory PDF. |
* |
* @var string |
*/ |
var $_buffer = ''; |
/** |
* Array containing the pages. |
* |
* @var array |
*/ |
var $_pages = array(); |
/** |
* Current document state. |
* 0 - initial state |
* 1 - document opened |
* 2 - page opened |
* 3 - document closed |
* |
* @var integer |
*/ |
var $_state = 0; |
/** |
* Flag indicating if PDF file is to be compressed or not. |
* |
* @var boolean |
*/ |
var $_compress; |
/** |
* The default page orientation. |
* |
* @var string |
*/ |
var $_default_orientation; |
/** |
* The current page orientation. |
* |
* @var string |
*/ |
var $_current_orientation; |
/** |
* Array indicating orientation changes. |
* |
* @var array |
*/ |
var $_orientation_changes = array(); |
/** |
* Current width of page format in points. |
* |
* @var float |
*/ |
var $fwPt; |
/** |
* Current height of page format in points. |
* |
* @var float |
*/ |
var $fhPt; |
/** |
* Current width of page format in user units. |
* |
* @var float |
*/ |
var $fw; |
/** |
* Current height of page format in user units. |
* |
* @var float |
*/ |
var $fh; |
/** |
* Current width of page in points. |
* |
* @var float |
*/ |
var $wPt; |
/** |
* Current height of page in points. |
* |
* @var float |
*/ |
var $hPt; |
/** |
* Current width of page in user units |
* |
* @var float |
*/ |
var $w; |
/** |
* Current height of page in user units |
* |
* @var float |
*/ |
var $h; |
/** |
* Scale factor (number of points in user units). |
* |
* @var float |
*/ |
var $_scale; |
/** |
* Left page margin size. |
* |
* @var float |
*/ |
var $_left_margin; |
/** |
* Top page margin size. |
* |
* @var float |
*/ |
var $_top_margin; |
/** |
* Right page margin size. |
* |
* @var float |
*/ |
var $_right_margin; |
/** |
* Break page margin size, the bottom margin which triggers a page break. |
* |
* @var float |
*/ |
var $_break_margin; |
/** |
* Cell margin size. |
* |
* @var float |
*/ |
var $_cell_margin; |
/** |
* The current horizontal position for cell positioning. |
* Value is set in user units and is calculated from the top left corner |
* as origin. |
* |
* @var float |
*/ |
var $x; |
/** |
* The current vertical position for cell positioning. |
* Value is set in user units and is calculated from the top left corner |
* as origin. |
* |
* @var float |
*/ |
var $y; |
/** |
* The height of the last cell printed. |
* |
* @var float |
*/ |
var $_last_height; |
/** |
* Line width in user units. |
* |
* @var float |
*/ |
var $_line_width; |
/** |
* An array of standard font names. |
* |
* @var array |
*/ |
var $_core_fonts = array('courier' => 'Courier', |
'courierB' => 'Courier-Bold', |
'courierI' => 'Courier-Oblique', |
'courierBI' => 'Courier-BoldOblique', |
'helvetica' => 'Helvetica', |
'helveticaB' => 'Helvetica-Bold', |
'helveticaI' => 'Helvetica-Oblique', |
'helveticaBI' => 'Helvetica-BoldOblique', |
'times' => 'Times-Roman', |
'timesB' => 'Times-Bold', |
'timesI' => 'Times-Italic', |
'timesBI' => 'Times-BoldItalic', |
'symbol' => 'Symbol', |
'zapfdingbats' => 'ZapfDingbats'); |
/** |
* An array of used fonts. |
* |
* @var array |
*/ |
var $_fonts = array(); |
/** |
* An array of font files. |
* |
* @var array |
*/ |
var $_font_files = array(); |
/** |
* An array of encoding differences. |
* |
* @var array |
*/ |
var $_diffs = array(); |
/** |
* An array of used images. |
* |
* @var array |
*/ |
var $_images = array(); |
/** |
* An array of links in pages. |
* |
* @var array |
*/ |
var $_page_links; |
/** |
* An array of internal links. |
* |
* @var array |
*/ |
var $_links = array(); |
/** |
* Current font family. |
* |
* @var string |
*/ |
var $_font_family = ''; |
/** |
* Current font style. |
* |
* @var string |
*/ |
var $_font_style = ''; |
/** |
* Underlining flag. |
* |
* @var boolean |
*/ |
var $_underline = false; |
/** |
* An array containing current font info. |
* |
* @var array |
*/ |
var $_current_font; |
/** |
* Current font size in points. |
* |
* @var float |
*/ |
var $_font_size_pt = 12; |
/** |
* Current font size in user units. |
* |
* @var float |
*/ |
var $_font_size; |
/** |
* Commands for filling color. |
* |
* @var string |
*/ |
var $_fill_color = '0 g'; |
/** |
* Commands for text color. |
* |
* @var string |
*/ |
var $_text_color = '0 g'; |
/** |
* Whether text color is different from fill color. |
* |
* @var boolean |
*/ |
var $_color_flag = false; |
/** |
* Commands for drawing color. |
* |
* @var string |
*/ |
var $_draw_color = '0 G'; |
/** |
* Word spacing. |
* |
* @var integer |
*/ |
var $_word_spacing = 0; |
/** |
* Automatic page breaking. |
* |
* @var boolean |
*/ |
var $_auto_page_break; |
/** |
* Threshold used to trigger page breaks. |
* |
* @var float |
*/ |
var $_page_break_trigger; |
/** |
* Flag set when processing footer. |
* |
* @var boolean |
*/ |
var $_in_footer = false; |
/** |
* Zoom display mode. |
* |
* @var string |
*/ |
var $_zoom_mode; |
/** |
* Layout display mode. |
* |
* @var string |
*/ |
var $_layout_mode; |
/** |
* An array containing the document info, consisting of: |
* - title |
* - subject |
* - author |
* - keywords |
* - creator |
* |
* @var array |
*/ |
var $_info = array(); |
/** |
* Alias for total number of pages. |
* |
* @var string |
*/ |
var $_alias_nb_pages = '{nb}'; |
/** |
* Attempts to return a conrete PDF instance. It allows to set up the page |
* format, the orientation and the units of measurement used in all the |
* methods (except for the font sizes). |
* |
* Example:<pre> |
* $pdf = &File_PDF::factory(array('orientation' => 'P', |
* 'unit' => 'mm', |
* 'format' => 'A4'));</pre> |
* |
* @param array $params A hash with parameters for the created PDF object. |
* Possible parameters are: |
* orientation - Default page orientation. Possible |
* values are (case insensitive): |
* <pre> |
* - P or Portrait (default) |
* - L or Landscape |
* </pre> |
* unit - User measure units. Possible values values |
* are: |
* <pre> |
* - pt: point |
* - mm: millimeter (default) |
* - cm: centimeter |
* - in: inch |
* </pre> |
* A point equals 1/72 of inch, that is to say about |
* 0.35 mm (an inch being 2.54 cm). This is a very |
* common unit in typography; font sizes are |
* expressed in that unit. |
* format - The format used for pages. It can be |
* either one of the following values (case |
* insensitive): |
* <pre> |
* - A3 |
* - A4 (default) |
* - A5 |
* - Letter |
* - Legal |
* </pre> |
* or a custom format in the form of a two-element |
* array containing the width and the height |
* (expressed in the unit given by the unit |
* parameter). |
* @param string $class The concrete class name to return an instance of. |
* Defaults to File_PDF. |
*/ |
function &factory($params = array(), $class = 'File_PDF') |
{ |
/* Check for PHP locale-related bug. */ |
if (1.1 == 1) { |
$error = File_PDF::raiseError('Do not alter the locale before including the class file.'); |
return $error; |
} |
/* Default parameters. */ |
$defaults = array('orientation' => 'P', 'unit' => 'mm', 'format' => 'A4'); |
/* Backward compatibility with old method signature. */ |
/* Should be removed a few versions later. */ |
if (!is_array($params)) { |
$class = 'File_PDF'; |
$params = $defaults; |
$names = array_keys($defaults); |
for ($i = 0; $i < func_num_args(); $i++) { |
$params[$names[$i]] = func_get_arg($i); |
} |
} else { |
$params = array_merge($defaults, $params); |
} |
/* Create the PDF object. */ |
$pdf = &new $class(); |
/* Scale factor. */ |
if ($params['unit'] == 'pt') { |
$pdf->_scale = 1; |
} elseif ($params['unit'] == 'mm') { |
$pdf->_scale = 72 / 25.4; |
} elseif ($params['unit'] == 'cm') { |
$pdf->_scale = 72 / 2.54; |
} elseif ($params['unit'] == 'in') { |
$pdf->_scale = 72; |
} else { |
$error = File_PDF::raiseError(sprintf('Incorrect units: %s', $params['unit'])); |
return $error; |
} |
/* Page format. */ |
if (is_string($params['format'])) { |
$params['format'] = strtolower($params['format']); |
if ($params['format'] == 'a3') { |
$params['format'] = array(841.89, 1190.55); |
} elseif ($params['format'] == 'a4') { |
$params['format'] = array(595.28, 841.89); |
} elseif ($params['format'] == 'a5') { |
$params['format'] = array(420.94, 595.28); |
} elseif ($params['format'] == 'letter') { |
$params['format'] = array(612, 792); |
} elseif ($params['format'] == 'legal') { |
$params['format'] = array(612, 1008); |
} else { |
$error = File_PDF::raiseError(sprintf('Unknown page format: %s', $params['format'])); |
return $error; |
} |
$pdf->fwPt = $params['format'][0]; |
$pdf->fhPt = $params['format'][1]; |
} else { |
$pdf->fwPt = $params['format'][0] * $pdf->_scale; |
$pdf->fhPt = $params['format'][1] * $pdf->_scale; |
} |
$pdf->fw = $pdf->fwPt / $pdf->_scale; |
$pdf->fh = $pdf->fhPt / $pdf->_scale; |
/* Page orientation. */ |
$params['orientation'] = strtolower($params['orientation']); |
if ($params['orientation'] == 'p' || $params['orientation'] == 'portrait') { |
$pdf->_default_orientation = 'P'; |
$pdf->wPt = $pdf->fwPt; |
$pdf->hPt = $pdf->fhPt; |
} elseif ($params['orientation'] == 'l' || $params['orientation'] == 'landscape') { |
$pdf->_default_orientation = 'L'; |
$pdf->wPt = $pdf->fhPt; |
$pdf->hPt = $pdf->fwPt; |
} else { |
$error = File_PDF::raiseError(sprintf('Incorrect orientation: %s', $params['orientation'])); |
return $error; |
} |
$pdf->_current_orientation = $pdf->_default_orientation; |
$pdf->w = $pdf->wPt / $pdf->_scale; |
$pdf->h = $pdf->hPt / $pdf->_scale; |
/* Page margins (1 cm) */ |
$margin = 28.35 / $pdf->_scale; |
$pdf->setMargins($margin, $margin); |
/* Interior cell margin (1 mm) */ |
$pdf->_cell_margin = $margin / 10; |
/* Line width (0.2 mm) */ |
$pdf->_line_width = .567 / $pdf->_scale; |
/* Automatic page break */ |
$pdf->setAutoPageBreak(true, 2 * $margin); |
/* Full width display mode */ |
$pdf->setDisplayMode('fullwidth'); |
/* Compression */ |
$pdf->setCompression(true); |
return $pdf; |
} |
/** |
* Returns a PEAR_Error object. Wraps around PEAR::raiseError() to |
* avoid having to include PEAR.php unless an error occurs. |
* |
* @param mixed $error The error message. |
* |
* @return object PEAR_Error |
*/ |
function raiseError($error) |
{ |
require_once 'PEAR.php'; |
return PEAR::raiseError($error); |
} |
/** |
* Defines the left, top and right margins. By default, they equal 1 cm. |
* Call this method to change them. |
* |
* @param float $left Left margin. |
* @param float $top Top margin. |
* @param float $right Right margin. If not specified default to the value |
* of the left one. |
* |
* @see File_PDF::setAutoPageBreak |
* @see File_PDF::setLeftMargin |
* @see File_PDF::setRightMargin |
* @see File_PDF::setTopMargin |
*/ |
function setMargins($left, $top, $right = null) |
{ |
/* Set left and top margins. */ |
$this->_left_margin = $left; |
$this->_top_margin = $top; |
/* If no right margin set default to same as left. */ |
$this->_right_margin = (is_null($right) ? $left : $right); |
} |
/** |
* Defines the left margin. The method can be called before creating the |
* first page. |
* If the current abscissa gets out of page, it is brought back to the |
* margin. |
* |
* @param float $margin The margin. |
* |
* @see File_PDF::setAutoPageBreak |
* @see File_PDF::setMargins |
* @see File_PDF::setRightMargin |
* @see File_PDF::setTopMargin |
*/ |
function setLeftMargin($margin) |
{ |
$this->_left_margin = $margin; |
/* If there is a current page and the current X position is less than |
* margin set the X position to the margin value. */ |
if ($this->_page > 0 && $this->x < $margin) { |
$this->x = $margin; |
} |
} |
/** |
* Defines the top margin. The method can be called before creating the |
* first page. |
* |
* @param float $margin The margin. |
*/ |
function setTopMargin($margin) |
{ |
$this->_top_margin = $margin; |
} |
/** |
* Defines the right margin. The method can be called before creating the |
* first page. |
* |
* @param float $margin The margin. |
*/ |
function setRightMargin($margin) |
{ |
$this->_right_margin = $margin; |
} |
/** |
* Returns the actual page width. |
* |
* @since File_PDF 0.2.0 |
* @since Horde 3.2 |
* |
* @return float The page width. |
*/ |
function getPageWidth() |
{ |
return ($this->w - $this->_right_margin - $this->_left_margin); |
} |
/** |
* Returns the actual page height. |
* |
* @since File_PDF 0.2.0 |
* @since Horde 3.2 |
* |
* @return float The page height. |
*/ |
function getPageHeight() |
{ |
return ($this->h - $this->_top_margin - $this->_break_margin); |
} |
/** |
* Enables or disables the automatic page breaking mode. When enabling, |
* the second parameter is the distance from the bottom of the page that |
* defines the triggering limit. By default, the mode is on and the margin |
* is 2 cm. |
* |
* @param boolean auto Boolean indicating if mode should be on or off. |
* @param float $margin Distance from the bottom of the page. |
*/ |
function setAutoPageBreak($auto, $margin = 0) |
{ |
$this->_auto_page_break = $auto; |
$this->_break_margin = $margin; |
$this->_page_break_trigger = $this->h - $margin; |
} |
/** |
* Defines the way the document is to be displayed by the viewer. The zoom |
* level can be set: pages can be displayed entirely on screen, occupy the |
* full width of the window, use real size, be scaled by a specific |
* zooming factor or use viewer default (configured in the Preferences |
* menu of Acrobat). The page layout can be specified too: single at once, |
* continuous display, two columns or viewer default. |
* By default, documents use the full width mode with continuous display. |
* |
* @param mixed $zoom The zoom to use. It can be one of the |
* following string values: |
* - fullpage: entire page on screen |
* - fullwidth: maximum width of window |
* - real: uses real size (100% zoom) |
* - default: uses viewer default mode |
* or a number indicating the zooming factor. |
* @param string layout The page layout. Possible values are: |
* - single: one page at once |
* - continuous: pages in continuously |
* - two: two pages on two columns |
* - default: uses viewer default mode |
* Default value is continuous. |
*/ |
function setDisplayMode($zoom, $layout = 'continuous') |
{ |
$zoom = strtolower($zoom); |
if ($zoom == 'fullpage' || $zoom == 'fullwidth' || $zoom == 'real' |
|| $zoom == 'default' || !is_string($zoom)) { |
$this->_zoom_mode = $zoom; |
} elseif ($zoom == 'zoom') { |
$this->_zoom_mode = $layout; |
} else { |
return $this->raiseError(sprintf('Incorrect zoom display mode: %s', $zoom)); |
} |
$layout = strtolower($layout); |
if ($layout == 'single' || $layout == 'continuous' || $layout == 'two' |
|| $layout == 'default') { |
$this->_layout_mode = $layout; |
} elseif ($zoom != 'zoom') { |
return $this->raiseError(sprintf('Incorrect layout display mode: %s', $layout)); |
} |
} |
/** |
* Activates or deactivates page compression. When activated, the internal |
* representation of each page is compressed, which leads to a compression |
* ratio of about 2 for the resulting document. |
* Compression is on by default. |
* Note: the Zlib extension is required for this feature. If not present, |
* compression will be turned off. |
* |
* @param boolean $compress Boolean indicating if compression must be |
* enabled or not. |
*/ |
function setCompression($compress) |
{ |
/* If no gzcompress function is available then default to false. */ |
$this->_compress = (function_exists('gzcompress') ? $compress : false); |
} |
/** |
* Set the info to a document. Possible info settings are: |
* - title |
* - subject |
* - author |
* - keywords |
* - creator |
* |
* @param mixed $info If passed as an array then the complete hash |
* containing the info to be inserted into the |
* document. Otherwise the name of setting to be set. |
* @param string $value The value of the setting. |
*/ |
function setInfo($info, $value = '') |
{ |
if (is_array($info)) { |
$this->_info = $info; |
} else { |
$this->_info[$info] = $value; |
} |
} |
/** |
* Defines an alias for the total number of pages. It will be substituted |
* as the document is closed. |
* |
* Example: |
* class My_File_PDF extends File_PDF { |
* function footer() |
* { |
* // Go to 1.5 cm from bottom |
* $this->setY(-15); |
* // Select Arial italic 8 |
* $this->setFont('Arial', 'I', 8); |
* // Print current and total page numbers |
* $this->cell(0, 10, 'Page ' . $this->getPageNo() . '/{nb}', 0, |
* 0, 'C'); |
* } |
* } |
* $pdf = &My_File_PDF::factory(); |
* $pdf->aliasNbPages(); |
* |
* @param string $alias The alias. Default value: {nb}. |
* |
* @see File_PDF::getPageNo |
* @see File_PDF::footer |
*/ |
function aliasNbPages($alias = '{nb}') |
{ |
$this->_alias_nb_pages = $alias; |
} |
/** |
* This method begins the generation of the PDF document; it must be |
* called before any output commands. No page is created by this method, |
* therefore it is necessary to call File_PDF::addPage. |
* |
* @see File_PDF::addPage |
* @see File_PDF::close |
*/ |
function open() |
{ |
$this->_beginDoc(); |
} |
/** |
* Terminates the PDF document. It is not necessary to call this method |
* explicitly because File_PDF::output does it automatically. |
* If the document contains no page, File_PDF::addPage is called to prevent |
* from getting an invalid document. |
* |
* @see File_PDF::open |
* @see File_PDF::output |
*/ |
function close() |
{ |
/* Terminate document */ |
if ($this->_page == 0) { |
$this->addPage(); |
} |
/* Page footer */ |
$this->_in_footer = true; |
$this->footer(); |
$this->_in_footer = false; |
/* Close page */ |
$this->_endPage(); |
/* Close document */ |
$this->_endDoc(); |
} |
/** |
* Adds a new page to the document. If a page is already present, the |
* File_PDF::footer method is called first to output the footer. Then the |
* page is added, the current position set to the top-left corner according |
* to the left and top margins, and File_PDF::header is called to display |
* the header. |
* The font which was set before calling is automatically restored. There |
* is no need to call File_PDF::setFont again if you want to continue with |
* the same font. The same is true for colors and line width. |
* The origin of the coordinate system is at the top-left corner and |
* increasing ordinates go downwards. |
* |
* @param string $orientation Page orientation. Possible values |
* are (case insensitive): |
* - P or Portrait |
* - L or Landscape |
* The default value is the one passed to the |
* constructor. |
* |
* @see File_PDF::PDF |
* @see File_PDF::header |
* @see File_PDF::footer |
* @see File_PDF::setMargins |
*/ |
function addPage($orientation = '') |
{ |
/* For good measure make sure this is called. */ |
$this->_beginDoc(); |
/* Save style settings so that they are not overridden by footer(). */ |
$lw = $this->_line_width; |
$dc = $this->_draw_color; |
$fc = $this->_fill_color; |
$tc = $this->_text_color; |
$cf = $this->_color_flag; |
if ($this->_page > 0) { |
/* Page footer. */ |
$this->_in_footer = true; |
$this->footer(); |
$this->_in_footer = false; |
/* Close page. */ |
$this->_endPage(); |
} |
/* Start new page. */ |
$this->_beginPage($orientation); |
/* Set line cap style to square. */ |
$this->_out('2 J'); |
/* Set line width. */ |
$this->_line_width = $lw; |
$this->_out(sprintf('%.2f w', $lw * $this->_scale)); |
/* Set font for the beginning of the page. */ |
$font_family = null; |
if ($this->_font_family) { |
$font_family = $this->_font_family; |
$font_style = $this->_font_style . ($this->_underline ? 'U' : ''); |
$font_size = $this->_font_size_pt; |
$this->setFont($font_family, $font_style, $font_size); |
} |
/* Set colors. */ |
$this->_fill_color = $fc; |
/* Check if fill color has been set before this page. */ |
if ($this->_fill_color != '0 g') { |
$this->_out($this->_fill_color); |
} |
$this->_draw_color = $dc; |
/* Check if draw color has been set before this page. */ |
if ($this->_draw_color != '0 G') { |
$this->_out($this->_draw_color); |
} |
$this->_text_color = $tc; |
$this->_color_flag = $cf; |
/* Page header. */ |
$this->header(); |
/* Restore line width. */ |
if ($this->_line_width != $lw) { |
$this->_line_width = $lw; |
$this->_out(sprintf('%.2f w', $lw * $this->_scale)); |
} |
/* Make sure the font is set for this page as it was before the |
* header. */ |
if ($font_family) { |
$this->setFont($font_family, $font_style, $font_size, true); |
} |
/* Restore colors. */ |
if ($this->_draw_color != $dc) { |
$this->_draw_color = $dc; |
$this->_out($dc); |
} |
if ($this->_fill_color != $fc) { |
$this->_fill_color = $fc; |
$this->_out($fc); |
} |
$this->_text_color = $tc; |
$this->_color_flag = $cf; |
} |
/** |
* This method is used to render the page header. It is automatically |
* called by File_PDF::addPage and should not be called directly by the |
* application. The implementation in File_PDF:: is empty, so you have to |
* subclass it and override the method if you want a specific processing. |
* |
* Example: |
* |
* class My_File_PDF extends File_PDF { |
* function header() |
* { |
* // Select Arial bold 15 |
* $this->setFont('Arial', 'B', 15); |
* // Move to the right |
* $this->cell(80); |
* // Framed title |
* $this->cell(30, 10, 'Title', 1, 0, 'C'); |
* // Line break |
* $this->newLine(20); |
* } |
* } |
* |
* @see File_PDF::footer |
*/ |
function header() |
{ |
/* To be implemented in your own inherited class. */ |
} |
/** |
* This method is used to render the page footer. It is automatically |
* called by File_PDF::addPage and File_PDF::close and should not be called |
* directly by the application. The implementation in File_PDF:: is empty, |
* so you have to subclass it and override the method if you want a specific |
* processing. |
* |
* Example: |
* |
* class My_File_PDF extends File_PDF { |
* function footer() |
* { |
* // Go to 1.5 cm from bottom |
* $this->setY(-15); |
* // Select Arial italic 8 |
* $this->setFont('Arial', 'I', 8); |
* // Print centered page number |
* $this->cell(0, 10, 'Page ' . $this->getPageNo(), 0, 0, 'C'); |
* } |
* } |
* |
* @see File_PDF::header |
*/ |
function footer() |
{ |
/* To be implemented in your own inherited class. */ |
} |
/** |
* Returns the current page number. |
* |
* @return integer |
* |
* @see File_PDF::aliasNbPages |
*/ |
function getPageNo() |
{ |
return $this->_page; |
} |
/** |
* Sets the fill color. |
* |
* Depending on the colorspace called, the number of color component |
* parameters required can be either 1, 3 or 4. The method can be called |
* before the first page is created and the color is retained from page to |
* page. |
* |
* @param string $cs Indicates the colorspace which can be either 'rgb', |
* 'cmyk' or 'gray'. Defaults to 'rgb'. |
* @param float $c1 First color component, floating point value between 0 |
* and 1. Required for gray, rgb and cmyk. |
* @param float $c2 Second color component, floating point value between |
* 0 and 1. Required for rgb and cmyk. |
* @param float $c3 Third color component, floating point value between |
* 0 and 1. Required for rgb and cmyk. |
* @param float $c4 Fourth color component, floating point value between |
* 0 and 1. Required for cmyk. |
* |
* @see File_PDF::setTextColor |
* @see File_PDF::setDrawColor |
* @see File_PDF::rect |
* @see File_PDF::cell |
* @see File_PDF::multiCell |
*/ |
function setFillColor($cs = 'rgb', $c1, $c2 = 0, $c3 = 0, $c4 = 0) |
{ |
$cs = strtolower($cs); |
if ($cs == 'rgb') { |
$this->_fill_color = sprintf('%.3f %.3f %.3f rg', $c1, $c2, $c3); |
} elseif ($cs == 'cmyk') { |
$this->_fill_color = sprintf('%.3f %.3f %.3f %.3f k', $c1, $c2, $c3, $c4); |
} else { |
$this->_fill_color = sprintf('%.3f g', $c1); |
} |
if ($this->_page > 0) { |
$this->_out($this->_fill_color); |
} |
$this->_color_flag = $this->_fill_color != $this->_text_color; |
} |
/** |
* Sets the text color. |
* |
* Depending on the colorspace called, the number of color component |
* parameters required can be either 1, 3 or 4. The method can be called |
* before the first page is created and the color is retained from page to |
* page. |
* |
* @param string $cs Indicates the colorspace which can be either 'rgb', |
* 'cmyk' or 'gray'. Defaults to 'rgb'. |
* @param float $c1 First color component, floating point value between 0 |
* and 1. Required for gray, rgb and cmyk. |
* @param float $c2 Second color component, floating point value between |
* 0 and 1. Required for rgb and cmyk. |
* @param float $c3 Third color component, floating point value between |
* 0 and 1. Required for rgb and cmyk. |
* @param float $c4 Fourth color component, floating point value between |
* 0 and 1. Required for cmyk. |
* |
* @since File_PDF 0.2.0 |
* @since Horde 3.2 |
* @see File_PDF::setFillColor |
* @see File_PDF::setDrawColor |
* @see File_PDF::rect |
* @see File_PDF::cell |
* @see File_PDF::multiCell |
*/ |
function setTextColor($cs = 'rgb', $c1, $c2 = 0, $c3 = 0, $c4 = 0) |
{ |
$cs = strtolower($cs); |
if ($cs == 'rgb') { |
$this->_text_color = sprintf('%.3f %.3f %.3f rg', $c1, $c2, $c3); |
} elseif ($cs == 'cmyk') { |
$this->_text_color = sprintf('%.3f %.3f %.3f %.3f k', $c1, $c2, $c3, $c4); |
} else { |
$this->_text_color = sprintf('%.3f g', $c1); |
} |
if ($this->_page > 0) { |
$this->_out($this->_text_color); |
} |
$this->_color_flag = $this->_fill_color != $this->_text_color; |
} |
/** |
* Sets the draw color, used when drawing lines. Depending on the |
* colorspace called, the number of color component parameters required |
* can be either 1, 3 or 4. The method can be called before the first page |
* is created and the color is retained from page to page. |
* |
* @param string $cs Indicates the colorspace which can be either 'rgb', |
* 'cmyk' or 'gray'. Defaults to 'rgb'. |
* @param float $c1 First color component, floating point value between 0 |
* and 1. Required for gray, rgb and cmyk. |
* @param float $c2 Second color component, floating point value between |
* 0 and 1. Required for rgb and cmyk. |
* @param float $c3 Third color component, floating point value between 0 |
* and 1. Required for rgb and cmyk. |
* @param float $c4 Fourth color component, floating point value between |
* 0 and 1. Required for cmyk. |
* |
* @see File_PDF::setFillColor |
* @see File_PDF::line |
* @see File_PDF::rect |
* @see File_PDF::cell |
* @see File_PDF::multiCell |
*/ |
function setDrawColor($cs = 'rgb', $c1, $c2 = 0, $c3 = 0, $c4 = 0) |
{ |
$cs = strtolower($cs); |
if ($cs == 'rgb') { |
$this->_draw_color = sprintf('%.3f %.3f %.3f RG', $c1, $c2, $c3); |
} elseif ($cs == 'cmyk') { |
$this->_draw_color = sprintf('%.3f %.3f %.3f %.3f K', $c1, $c2, $c3, $c4); |
} else { |
$this->_draw_color = sprintf('%.3f G', $c1); |
} |
if ($this->_page > 0) { |
$this->_out($this->_draw_color); |
} |
} |
/** |
* Returns the length of a text string. A font must be selected. |
* |
* @param string $text The text whose length is to be computed. |
* @param boolean $pt Boolean to indicate if the width should be returned |
* in points or user units. Default is 'false'. |
* |
* @return float |
*/ |
function getStringWidth($text, $pt = false) |
{ |
$text = (string)$text; |
$width = 0; |
$length = strlen($text); |
for ($i = 0; $i < $length; $i++) { |
$width += $this->_current_font['cw'][$text{$i}]; |
} |
/* Adjust for word spacing. */ |
$width += $this->_word_spacing * substr_count($text, ' ') * $this->_current_font['cw'][' ']; |
if ($pt) { |
return $width * $this->_font_size_pt / 1000; |
} else { |
return $width * $this->_font_size / 1000; |
} |
} |
/** |
* Defines the line width. By default, the value equals 0.2 mm. The method |
* can be called before the first page is created and the value is |
* retained from page to page. |
* |
* @param float $width The width. |
* |
* @see File_PDF::line |
* @see File_PDF::rect |
* @see File_PDF::cell |
* @see File_PDF::multiCell |
*/ |
function setLineWidth($width) |
{ |
$this->_line_width = $width; |
if ($this->_page > 0) { |
$this->_out(sprintf('%.2f w', $width * $this->_scale)); |
} |
} |
/** |
* Draws a line between two points. |
* |
* All coordinates can be negative to provide values from the right or |
* bottom edge of the page (since File_PDF 0.2.0, Horde 3.2). |
* |
* @param float $x1 Abscissa of first point. |
* @param float $y1 Ordinate of first point. |
* @param float $x2 Abscissa of second point. |
* @param float $y2 Ordinate of second point. |
* |
* @see File_PDF::setLineWidth |
* @see File_PDF::setDrawColor. |
*/ |
function line($x1, $y1, $x2, $y2) |
{ |
if ($x1 < 0) { |
$x1 += $this->w; |
} |
if ($y1 < 0) { |
$y1 += $this->h; |
} |
if ($x2 < 0) { |
$x2 += $this->w; |
} |
if ($y2 < 0) { |
$y2 += $this->h; |
} |
$this->_out(sprintf('%.2f %.2f m %.2f %.2f l S', $x1 * $this->_scale, ($this->h - $y1) * $this->_scale, $x2 * $this->_scale, ($this->h - $y2) * $this->_scale)); |
} |
/** |
* Outputs a rectangle. It can be drawn (border only), filled (with no |
* border) or both. |
* |
* All coordinates can be negative to provide values from the right or |
* bottom edge of the page (since File_PDF 0.2.0, Horde 3.2). |
* |
* @param float $x Abscissa of upper-left corner. |
* @param float $y Ordinate of upper-left corner. |
* @param float $width Width. |
* @param float $height Height. |
* @param float $style Style of rendering. Possible values are: |
* - D or empty string: draw (default) |
* - F: fill |
* - DF or FD: draw and fill |
* |
* @see File_PDF::setLineWidth |
* @see File_PDF::setDrawColor |
* @see File_PDF::setFillColor |
*/ |
function rect($x, $y, $width, $height, $style = '') |
{ |
if ($x < 0) { |
$x += $this->w; |
} |
if ($y < 0) { |
$y += $this->h; |
} |
$style = strtoupper($style); |
if ($style == 'F') { |
$op = 'f'; |
} elseif ($style == 'FD' || $style == 'DF') { |
$op = 'B'; |
} else { |
$op = 'S'; |
} |
$x = $this->_toPt($x); |
$y = $this->_toPt($y); |
$width = $this->_toPt($width); |
$height = $this->_toPt($height); |
$this->_out(sprintf('%.2f %.2f %.2f %.2f re %s', $x, $this->hPt - $y, $width, -$height, $op)); |
} |
/** |
* Outputs a circle. It can be drawn (border only), filled (with no |
* border) or both. |
* |
* All coordinates can be negative to provide values from the right or |
* bottom edge of the page (since File_PDF 0.2.0, Horde 3.2). |
* |
* @param float $x Abscissa of the center of the circle. |
* @param float $y Ordinate of the center of the circle. |
* @param float $r Circle radius. |
* @param string $style Style of rendering. Possible values are: |
* - D or empty string: draw (default) |
* - F: fill |
* - DF or FD: draw and fill |
*/ |
function circle($x, $y, $r, $style = '') |
{ |
if ($x < 0) { |
$x += $this->w; |
} |
if ($y < 0) { |
$y += $this->h; |
} |
$style = strtolower($style); |
if ($style == 'f') { |
$op = 'f'; // Style is fill only. |
} elseif ($style == 'fd' || $style == 'df') { |
$op = 'B'; // Style is fill and stroke. |
} else { |
$op = 'S'; // Style is stroke only. |
} |
$x = $this->_toPt($x); |
$y = $this->_toPt($y); |
$r = $this->_toPt($r); |
/* Invert the y scale. */ |
$y = $this->hPt - $y; |
/* Length of the Bezier control. */ |
$b = $r * 0.552; |
/* Move from the given origin and set the current point |
* to the start of the first Bezier curve. */ |
$c = sprintf('%.2f %.2f m', $x - $r, $y); |
$x = $x - $r; |
/* First circle quarter. */ |
$c .= sprintf(' %.2f %.2f %.2f %.2f %.2f %.2f c', |
$x, $y + $b, // First control point. |
$x + $r - $b, $y + $r, // Second control point. |
$x + $r, $y + $r); // Final point. |
/* Set x/y to the final point. */ |
$x = $x + $r; |
$y = $y + $r; |
/* Second circle quarter. */ |
$c .= sprintf(' %.2f %.2f %.2f %.2f %.2f %.2f c', |
$x + $b, $y, |
$x + $r, $y - $r + $b, |
$x + $r, $y - $r); |
/* Set x/y to the final point. */ |
$x = $x + $r; |
$y = $y - $r; |
/* Third circle quarter. */ |
$c .= sprintf(' %.2f %.2f %.2f %.2f %.2f %.2f c', |
$x, $y - $b, |
$x - $r + $b, $y - $r, |
$x - $r, $y - $r); |
/* Set x/y to the final point. */ |
$x = $x - $r; |
$y = $y - $r; |
/* Fourth circle quarter. */ |
$c .= sprintf(' %.2f %.2f %.2f %.2f %.2f %.2f c %s', |
$x - $b, $y, |
$x - $r, $y + $r - $b, |
$x - $r, $y + $r, |
$op); |
/* Output the whole string. */ |
$this->_out($c); |
} |
/** |
* Imports a TrueType or Type1 font and makes it available. It is |
* necessary to generate a font definition file first with the |
* makefont.php utility. |
* The location of the definition file (and the font file itself when |
* embedding) must be found at the full path name included. |
* |
* Example: |
* $pdf->addFont('Comic', 'I'); |
* is equivalent to: |
* $pdf->addFont('Comic', 'I', 'comici.php'); |
* |
* @param string $family Font family. The name can be chosen arbitrarily. |
* If it is a standard family name, it will |
* override the corresponding font. |
* @param string $style Font style. Possible values are (case |
* insensitive): |
* - empty string: regular (default) |
* - B: bold |
* - I: italic |
* - BI or IB: bold italic |
* @param string $file The font definition file. By default, the name is |
* built from the family and style, in lower case |
* with no space. |
* |
* @see File_PDF::setFont |
*/ |
function addFont($family, $style = '', $file = '') |
{ |
$family = strtolower($family); |
if ($family == 'arial') { |
$family = 'helvetica'; |
} |
$style = strtoupper($style); |
if ($style == 'IB') { |
$style = 'BI'; |
} |
if (isset($this->_fonts[$family . $style])) { |
return $this->raiseError(sprintf('Font already added: %s %s', $family, $style)); |
} |
if ($file == '') { |
$file = str_replace(' ', '', $family) . strtolower($style) . '.php'; |
} |
include($file); |
if (!isset($name)) { |
return $this->raiseError('Could not include font definition file.'); |
} |
$i = count($this->_fonts) + 1; |
$this->_fonts[$family . $style] = array('i' => $i, 'type' => $type, 'name' => $name, 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'enc' => $enc, 'file' => $file); |
if ($diff) { |
/* Search existing encodings. */ |
$d = 0; |
$nb = count($this->_diffs); |
for ($i = 1; $i <= $nb; $i++) { |
if ($this->_diffs[$i] == $diff) { |
$d = $i; |
break; |
} |
} |
if ($d == 0) { |
$d = $nb + 1; |
$this->_diffs[$d] = $diff; |
} |
$this->_fonts[$family.$style]['diff'] = $d; |
} |
if ($file) { |
if ($type == 'TrueType') { |
$this->_font_files[$file] = array('length1' => $originalsize); |
} else { |
$this->_font_files[$file] = array('length1' => $size1, 'length2' => $size2); |
} |
} |
} |
/** |
* Sets the font used to print character strings. It is mandatory to call |
* this method at least once before printing text or the resulting |
* document would not be valid. The font can be either a standard one or a |
* font added via the File_PDF::addFont method. Standard fonts use Windows |
* encoding cp1252 (Western Europe). |
* The method can be called before the first page is created and the font |
* is retained from page to page. |
* If you just wish to change the current font size, it is simpler to call |
* File_PDF::setFontSize. |
* |
* @param string $family Family font. It can be either a name defined by |
* File_PDF::addFont or one of the standard families |
* (case insensitive): |
* - Courier (fixed-width) |
* - Helvetica or Arial (sans serif) |
* - Times (serif) |
* - Symbol (symbolic) |
* - ZapfDingbats (symbolic) |
* It is also possible to pass an empty string. In |
* that case, the current family is retained. |
* @param string $style Font style. Possible values are (case |
* insensitive): |
* - empty string: regular |
* - B: bold |
* - I: italic |
* - U: underline |
* or any combination. The default value is regular. |
* Bold and italic styles do not apply to Symbol and |
* ZapfDingbats. |
* @param integer $size Font size in points. The default value is the |
* current size. If no size has been specified since |
* the beginning of the document, the value taken |
* is 12. |
* @param boolean $force Force the setting of the font. Each new page will |
* require a new call to File_PDF::setFont and |
* settings this to true will make sure that the |
* checks for same font calls will be skipped. |
* |
* @see File_PDF::addFont |
* @see File_PDF::setFontSize |
* @see File_PDF::cell |
* @see File_PDF::multiCell |
* @see File_PDF::Write |
*/ |
function setFont($family, $style = '', $size = null, $force = false) |
{ |
$family = strtolower($family); |
if ($family == 'arial') { |
/* Use helvetica instead of arial. */ |
$family = 'helvetica'; |
} elseif ($family == 'symbol' || $family == 'zapfdingbats') { |
/* These two fonts do not have styles available. */ |
$style = ''; |
} |
$style = strtoupper($style); |
/* Underline is handled separately, if specified in the style var |
* remove it from the style and set the underline flag. */ |
if (strpos($style, 'U') !== false) { |
$this->_underline = true; |
$style = str_replace('U', '', $style); |
} else { |
$this->_underline = false; |
} |
if ($style == 'IB') { |
$style = 'BI'; |
} |
/* If no size specified, use current size. */ |
if (is_null($size)) { |
$size = $this->_font_size_pt; |
} |
/* If font requested is already the current font and no force setting |
* of the font is requested (eg. when adding a new page) don't bother |
* with the rest of the function and simply return. */ |
if ($this->_font_family == $family && $this->_font_style == $style && |
$this->_font_size_pt == $size && !$force) { |
return; |
} |
/* Set the font key. */ |
$fontkey = $family . $style; |
/* Test if already cached. */ |
if (!isset($this->_fonts[$fontkey])) { |
/* Get the character width definition file. */ |
$font_widths = &File_PDF::_getFontFile($fontkey); |
if (is_a($font_widths, 'PEAR_Error')) { |
return $font_widths; |
} |
$i = count($this->_fonts) + 1; |
$this->_fonts[$fontkey] = array( |
'i' => $i, |
'type' => 'core', |
'name' => $this->_core_fonts[$fontkey], |
'up' => -100, |
'ut' => 50, |
'cw' => $font_widths[$fontkey]); |
} |
/* Store font information as current font. */ |
$this->_font_family = $family; |
$this->_font_style = $style; |
$this->_font_size_pt = $size; |
$this->_font_size = $size / $this->_scale; |
$this->_current_font = &$this->_fonts[$fontkey]; |
/* Output font information if at least one page has been defined. */ |
if ($this->_page > 0) { |
$this->_out(sprintf('BT /F%d %.2f Tf ET', $this->_current_font['i'], $this->_font_size_pt)); |
} |
} |
/** |
* Defines the size of the current font. |
* |
* @param float $size The size (in points). |
* |
* @see File_PDF::setFont |
*/ |
function setFontSize($size) |
{ |
/* If the font size is already the current font size, just return. */ |
if ($this->_font_size_pt == $size) { |
return; |
} |
/* Set the current font size, both in points and scaled to user |
* units. */ |
$this->_font_size_pt = $size; |
$this->_font_size = $size / $this->_scale; |
/* Output font information if at least one page has been defined. */ |
if ($this->_page > 0) { |
$this->_out(sprintf('BT /F%d %.2f Tf ET', $this->_current_font['i'], $this->_font_size_pt)); |
} |
} |
/** |
* Defines the style of the current font. |
* |
* @param string $style The font style. |
* |
* @see File_PDF::setFont |
* @since File_PDF 0.2.0 |
* @since Horde 3.2 |
*/ |
function setFontStyle($style) |
{ |
$this->setFont($this->_font_family, $style); |
} |
/** |
* Creates a new internal link and returns its identifier. An internal |
* link is a clickable area which directs to another place within the |
* document. |
* The identifier can then be passed to File_PDF::cell, File_PDF::write, |
* File_PDF::image or File_PDF::link. The destination is defined with |
* File_PDF::setLink. |
* |
* @see File_PDF::cell |
* @see File_PDF::Write |
* @see File_PDF::image |
* @see File_PDF::Link |
* @see File_PDF::SetLink |
*/ |
function addLink() |
{ |
$n = count($this->_links) + 1; |
$this->_links[$n] = array(0, 0); |
return $n; |
} |
/** |
* Defines the page and position a link points to. |
* |
* @param integer $link The link identifier returned by File_PDF::addLink. |
* @param float $y Ordinate of target position; -1 indicates the |
* current position. The default value is 0 (top of |
* page). |
* @param integer $page Number of target page; -1 indicates the current |
* page. This is the default value. |
* |
* @see File_PDF::addLink |
*/ |
function setLink($link, $y = 0, $page = -1) |
{ |
if ($y == -1) { |
$y = $this->y; |
} |
if ($page == -1) { |
$page = $this->_page; |
} |
$this->_links[$link] = array($page, $y); |
} |
/** |
* Puts a link on a rectangular area of the page. Text or image links are |
* generally put via File_PDF::cell, File_PDF::Write or File_PDF::image, |
* but this method can be useful for instance to define a clickable area |
* inside an image. |
* |
* All coordinates can be negative to provide values from the right or |
* bottom edge of the page (since File_PDF 0.2.0, Horde 3.2). |
* |
* @param float $x Abscissa of the upper-left corner of the rectangle. |
* @param float $y Ordinate of the upper-left corner of the rectangle. |
* @param float $width Width of the rectangle. |
* @param float $height Height of the rectangle. |
* @param mixed $link URL or identifier returned by File_PDF::addLink. |
* |
* @see File_PDF::addLink |
* @see File_PDF::cell |
* @see File_PDF::Write |
* @see File_PDF::image |
*/ |
function link($x, $y, $width, $height, $link) |
{ |
if ($x < 0) { |
$x += $this->w; |
} |
if ($y < 0) { |
$y += $this->h; |
} |
/* Set up the coordinates with correct scaling in pt. */ |
$x = $this->_toPt($x); |
$y = $this->hPt - $this->_toPt($y); |
$width = $this->_toPt($width); |
$height = $this->_toPt($height); |
/* Save link to page links array. */ |
$this->_link($x, $y, $width, $height, $link); |
} |
/** |
* Prints a character string. The origin is on the left of the first |
* character, on the baseline. This method allows to place a string |
* precisely on the page, but it is usually easier to use File_PDF::cell, |
* File_PDF::multiCell or File_PDF::Write which are the standard methods to |
* print text. |
* |
* All coordinates can be negative to provide values from the right or |
* bottom edge of the page (since File_PDF 0.2.0, Horde 3.2). |
* |
* @param float $x Abscissa of the origin. |
* @param float $y Ordinate of the origin. |
* @param string $text String to print. |
* |
* @see File_PDF::setFont |
* @see File_PDF::cell |
* @see File_PDF::multiCell |
* @see File_PDF::Write |
*/ |
function text($x, $y, $text) |
{ |
if ($x < 0) { |
$x += $this->w; |
} |
if ($y < 0) { |
$y += $this->h; |
} |
/* Scale coordinates into points and set correct Y position. */ |
$x = $this->_toPt($x); |
$y = $this->hPt - $this->_toPt($y); |
/* Escape any potentially harmful characters. */ |
$text = $this->_escape($text); |
$out = sprintf('BT %.2f %.2f Td (%s) Tj ET', $x, $y, $text); |
if ($this->_underline && $text != '') { |
$out .= ' ' . $this->_doUnderline($x, $y, $text); |
} |
if ($this->_color_flag) { |
$out = sprintf('q %s %s Q', $this->_text_color, $out); |
} |
$this->_out($out); |
} |
/** |
* Whenever a page break condition is met, the method is called, and the |
* break is issued or not depending on the returned value. The default |
* implementation returns a value according to the mode selected by |
* File_PDF:setAutoPageBreak. |
* This method is called automatically and should not be called directly |
* by the application. |
* |
* @return boolean |
* |
* @see File_PDF::setAutoPageBreak. |
*/ |
function acceptPageBreak() |
{ |
return $this->_auto_page_break; |
} |
/** |
* Prints a cell (rectangular area) with optional borders, background |
* color and character string. The upper-left corner of the cell |
* corresponds to the current position. The text can be aligned or |
* centered. After the call, the current position moves to the right or to |
* the next line. It is possible to put a link on the text. |
* If automatic page breaking is enabled and the cell goes beyond the |
* limit, a page break is done before outputting. |
* |
* @param float $width Cell width. If 0, the cell extends up to the right |
* margin. |
* @param float $height Cell height. Default value: 0. |
* @param string $text String to print. Default value: empty. |
* @param mixed $border Indicates if borders must be drawn around the |
* cell. The value can be either a number: |
* - 0: no border (default) |
* - 1: frame |
* or a string containing some or all of the |
* following characters (in any order): |
* - L: left |
* - T: top |
* - R: right |
* - B: bottom |
* @param integer $ln Indicates where the current position should go |
* after the call. Possible values are: |
* - 0: to the right (default) |
* - 1: to the beginning of the next line |
* - 2: below |
* Putting 1 is equivalent to putting 0 and calling |
* File_PDF::newLine just after. |
* @param string $align Allows to center or align the text. Possible |
* values are: |
* - L or empty string: left (default) |
* - C: center |
* - R: right |
* @param integer $fill Indicates if the cell fill type. Possible values |
* are: |
* - 0: transparent (default) |
* - 1: painted |
* @param string $link URL or identifier returned by |
* File_PDF:addLink. |
* |
* @see File_PDF::setFont |
* @see File_PDF::setDrawColor |
* @see File_PDF::setFillColor |
* @see File_PDF::setLineWidth |
* @see File_PDF::addLink |
* @see File_PDF::newLine |
* @see File_PDF::multiCell |
* @see File_PDF::Write |
* @see File_PDF::setAutoPageBreak |
*/ |
function cell($width, $height = 0, $text = '', $border = 0, $ln = 0, |
$align = '', $fill = 0, $link = '') |
{ |
$k = $this->_scale; |
if ($this->y + $height > $this->_page_break_trigger && |
!$this->_in_footer && $this->AcceptPageBreak()) { |
$x = $this->x; |
$ws = $this->_word_spacing; |
if ($ws > 0) { |
$this->_word_spacing = 0; |
$this->_out('0 Tw'); |
} |
$this->addPage($this->_current_orientation); |
$this->x = $x; |
if ($ws > 0) { |
$this->_word_spacing = $ws; |
$this->_out(sprintf('%.3f Tw', $ws * $k)); |
} |
} |
if ($width == 0) { |
$width = $this->w - $this->_right_margin - $this->x; |
} |
$s = ''; |
if ($fill == 1 || $border == 1) { |
if ($fill == 1) { |
$op = ($border == 1) ? 'B' : 'f'; |
} else { |
$op = 'S'; |
} |
$s = sprintf('%.2f %.2f %.2f %.2f re %s ', $this->x * $k, ($this->h - $this->y) * $k, $width * $k, -$height * $k, $op); |
} |
if (is_string($border)) { |
if (strpos($border, 'L') !== false) { |
$s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $this->x * $k, ($this->h - $this->y) * $k, $this->x * $k, ($this->h - ($this->y + $height)) * $k); |
} |
if (strpos($border, 'T') !== false) { |
$s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $this->x * $k, ($this->h - $this->y) * $k, ($this->x + $width) * $k, ($this->h - $this->y) * $k); |
} |
if (strpos($border, 'R') !== false) { |
$s .= sprintf('%.2f %.2f m %.2f %.2f l S ', ($this->x + $width) * $k, ($this->h - $this->y) * $k, ($this->x + $width) * $k, ($this->h - ($this->y + $height)) * $k); |
} |
if (strpos($border, 'B') !== false) { |
$s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $this->x * $k, ($this->h - ($this->y + $height)) * $k, ($this->x + $width) * $k, ($this->h - ($this->y + $height)) * $k); |
} |
} |
if ($text != '') { |
if ($align == 'R') { |
$dx = $width - $this->_cell_margin - $this->getStringWidth($text); |
} elseif ($align == 'C') { |
$dx = ($width - $this->getStringWidth($text)) / 2; |
} else { |
$dx = $this->_cell_margin; |
} |
if ($this->_color_flag) { |
$s .= 'q ' . $this->_text_color . ' '; |
} |
$text = str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $text))); |
$test2 = ((.5 * $height) + (.3 * $this->_font_size)); |
$test1 = $this->fhPt - (($this->y + $test2) * $k); |
$s .= sprintf('BT %.2f %.2f Td (%s) Tj ET', ($this->x + $dx) * $k, ($this->h - ($this->y + .5 * $height + .3 * $this->_font_size)) * $k, $text); |
if ($this->_underline) { |
$s .= ' ' . $this->_doUnderline($this->x + $dx, $this->y + .5 * $height + .3 * $this->_font_size, $text); |
} |
if ($this->_color_flag) { |
$s .= ' Q'; |
} |
if ($link) { |
$this->link($this->x + $dx, $this->y + .5 * $height-.5 * $this->_font_size, $this->getStringWidth($text), $this->_font_size, $link); |
} |
} |
if ($s) { |
$this->_out($s); |
} |
$this->_last_height = $height; |
if ($ln > 0) { |
/* Go to next line. */ |
$this->y += $height; |
if ($ln == 1) { |
$this->x = $this->_left_margin; |
} |
} else { |
$this->x += $width; |
} |
} |
/** |
* This method allows printing text with line breaks. They can be |
* automatic (as soon as the text reaches the right border of the cell) or |
* explicit (via the \n character). As many cells as necessary are output, |
* one below the other. |
* Text can be aligned, centered or justified. The cell block can be |
* framed and the background painted. |
* |
* @param float $width Width of cells. If 0, they extend up to the right |
* margin of the page. |
* @param float $height Height of cells. |
* @param string $text String to print. |
* @param mixed $border Indicates if borders must be drawn around the cell |
* block. The value can be either a number: |
* - 0: no border (default) |
* - 1: frame |
* or a string containing some or all of the |
* following characters (in any order): |
* - L: left |
* - T: top |
* - R: right |
* - B: bottom |
* @param string $align Sets the text alignment. Possible values are: |
* - L: left alignment |
* - C: center |
* - R: right alignment |
* - J: justification (default value) |
* @param integer $fill Indicates if the cell background must: |
* - 0: transparent (default) |
* - 1: painted |
* |
* @see File_PDF::setFont |
* @see File_PDF::setDrawColor |
* @see File_PDF::setFillColor |
* @see File_PDF::setLineWidth |
* @see File_PDF::cell |
* @see File_PDF::write |
* @see File_PDF::setAutoPageBreak |
*/ |
function multiCell($width, $height, $text, $border = 0, $align = 'J', |
$fill = 0) |
{ |
$cw = &$this->_current_font['cw']; |
if ($width == 0) { |
$width = $this->w - $this->_right_margin - $this->x; |
} |
$wmax = ($width-2 * $this->_cell_margin) * 1000 / $this->_font_size; |
$s = str_replace("\r", '', $text); |
$nb = strlen($s); |
if ($nb > 0 && $s[$nb-1] == "\n") { |
$nb--; |
} |
$b = 0; |
if ($border) { |
if ($border == 1) { |
$border = 'LTRB'; |
$b = 'LRT'; |
$b2 = 'LR'; |
} else { |
$b2 = ''; |
if (strpos($border, 'L') !== false) { |
$b2 .= 'L'; |
} |
if (strpos($border, 'R') !== false) { |
$b2 .= 'R'; |
} |
$b = (strpos($border, 'T') !== false) ? $b2 . 'T' : $b2; |
} |
} |
$sep = -1; |
$i = 0; |
$j = 0; |
$l = 0; |
$ns = 0; |
$nl = 1; |
while ($i < $nb) { |
/* Get next character. */ |
$c = $s[$i]; |
if ($c == "\n") { |
/* Explicit line break. */ |
if ($this->_word_spacing > 0) { |
$this->_word_spacing = 0; |
$this->_out('0 Tw'); |
} |
$this->cell($width, $height, substr($s, $j, $i-$j), $b, 2, $align, $fill); |
$i++; |
$sep = -1; |
$j = $i; |
$l = 0; |
$ns = 0; |
$nl++; |
if ($border && $nl == 2) { |
$b = $b2; |
} |
continue; |
} |
if ($c == ' ') { |
$sep = $i; |
$ls = $l; |
$ns++; |
} |
$l += $cw[$c]; |
if ($l > $wmax) { |
/* Automatic line break. */ |
if ($sep == -1) { |
if ($i == $j) { |
$i++; |
} |
if ($this->_word_spacing > 0) { |
$this->_word_spacing = 0; |
$this->_out('0 Tw'); |
} |
$this->cell($width, $height, substr($s, $j, $i - $j), $b, 2, $align, $fill); |
} else { |
if ($align == 'J') { |
$this->_word_spacing = ($ns>1) ? ($wmax - $ls)/1000 * $this->_font_size / ($ns - 1) : 0; |
$this->_out(sprintf('%.3f Tw', $this->_word_spacing * $this->_scale)); |
} |
$this->cell($width, $height, substr($s, $j, $sep - $j), $b, 2, $align, $fill); |
$i = $sep + 1; |
} |
$sep = -1; |
$j = $i; |
$l = 0; |
$ns = 0; |
$nl++; |
if ($border && $nl == 2) { |
$b = $b2; |
} |
} else { |
$i++; |
} |
} |
/* Last chunk. */ |
if ($this->_word_spacing > 0) { |
$this->_word_spacing = 0; |
$this->_out('0 Tw'); |
} |
if ($border && strpos($border, 'B') !== false) { |
$b .= 'B'; |
} |
$this->cell($width, $height, substr($s, $j, $i), $b, 2, $align, $fill); |
$this->x = $this->_left_margin; |
} |
/** |
* This method prints text from the current position. When the right |
* margin is reached (or the \n character is met) a line break occurs and |
* text continues from the left margin. Upon method exit, the current |
* position is left just at the end of the text. |
* It is possible to put a link on the text. |
* |
* Example: |
* //Begin with regular font |
* $pdf->setFont('Arial','',14); |
* $pdf->write(5,'Visit '); |
* //Then put a blue underlined link |
* $pdf->setTextColor(0,0,255); |
* $pdf->setFont('','U'); |
* $pdf->write(5,'www.fpdf.org','http://www.fpdf.org'); |
* |
* @param float $height Line height. |
* @param string $text String to print. |
* @param mixed $link URL or identifier returned by AddLink(). |
* |
* @see File_PDF::setFont |
* @see File_PDF::addLink |
* @see File_PDF::multiCell |
* @see File_PDF::setAutoPageBreak |
*/ |
function write($height, $text, $link = '') |
{ |
$cw = &$this->_current_font['cw']; |
$width = $this->w - $this->_right_margin - $this->x; |
$wmax = ($width - 2 * $this->_cell_margin) * 1000 / $this->_font_size; |
$s = str_replace("\r", '', $text); |
$nb = strlen($s); |
$sep = -1; |
$i = 0; |
$j = 0; |
$l = 0; |
$nl = 1; |
while ($i < $nb) { |
/* Get next character. */ |
$c = $s{$i}; |
if ($c == "\n") { |
/* Explicit line break. */ |
$this->cell($width, $height, substr($s, $j, $i - $j), 0, 2, '', 0, $link); |
$i++; |
$sep = -1; |
$j = $i; |
$l = 0; |
if ($nl == 1) { |
$this->x = $this->_left_margin; |
$width = $this->w - $this->_right_margin - $this->x; |
$wmax = ($width - 2 * $this->_cell_margin) * 1000 / $this->_font_size; |
} |
$nl++; |
continue; |
} |
if ($c == ' ') { |
$sep = $i; |
$ls = $l; |
} |
$l += (isset($cw[$c]) ? $cw[$c] : 0); |
if ($l > $wmax) { |
/* Automatic line break. */ |
if ($sep == -1) { |
if ($this->x > $this->_left_margin) { |
/* Move to next line. */ |
$this->x = $this->_left_margin; |
$this->y += $height; |
$width = $this->w - $this->_right_margin - $this->x; |
$wmax = ($width - 2 * $this->_cell_margin) * 1000 / $this->_font_size; |
$i++; |
$nl++; |
continue; |
} |
if ($i == $j) { |
$i++; |
} |
$this->cell($width, $height, substr($s, $j, $i - $j), 0, 2, '', 0, $link); |
} else { |
$this->cell($width, $height, substr($s, $j, $sep - $j), 0, 2, '', 0, $link); |
$i = $sep + 1; |
} |
$sep = -1; |
$j = $i; |
$l = 0; |
if ($nl == 1) { |
$this->x = $this->_left_margin; |
$width = $this->w - $this->_right_margin - $this->x; |
$wmax = ($width - 2 * $this->_cell_margin) * 1000 / $this->_font_size; |
} |
$nl++; |
} else { |
$i++; |
} |
} |
/* Last chunk. */ |
if ($i != $j) { |
$this->cell($l / 1000 * $this->_font_size, $height, substr($s, $j, $i), 0, 0, '', 0, $link); |
} |
} |
/** |
* Writes text at an angle. |
* |
* All coordinates can be negative to provide values from the right or |
* bottom edge of the page (since File_PDF 0.2.0, Horde 3.2). |
* |
* @param integer $x X coordinate. |
* @param integer $y Y coordinate. |
* @param string $text Text to write. |
* @param float $text_angle Angle to rotate (Eg. 90 = bottom to top). |
* @param float $font_angle Rotate characters as well as text. |
* |
* @see File_PDF::setFont |
*/ |
function writeRotated($x, $y, $text, $text_angle, $font_angle = 0) |
{ |
if ($x < 0) { |
$x += $this->w; |
} |
if ($y < 0) { |
$y += $this->h; |
} |
/* Escape text. */ |
$text = $this->_escape($text); |
$font_angle += 90 + $text_angle; |
$text_angle *= M_PI / 180; |
$font_angle *= M_PI / 180; |
$text_dx = cos($text_angle); |
$text_dy = sin($text_angle); |
$font_dx = cos($font_angle); |
$font_dy = sin($font_angle); |
$s= sprintf('BT %.2f %.2f %.2f %.2f %.2f %.2f Tm (%s) Tj ET', |
$text_dx, $text_dy, $font_dx, $font_dy, |
$x * $this->_scale, ($this->h-$y) * $this->_scale, $text); |
if ($this->_draw_color) { |
$s = 'q ' . $this->_draw_color . ' ' . $s . ' Q'; |
} |
$this->_out($s); |
} |
/** |
* Prints an image in the page. The upper-left corner and at least one of |
* the dimensions must be specified; the height or the width can be |
* calculated automatically in order to keep the image proportions. |
* Supported formats are JPEG and PNG. |
* |
* All coordinates can be negative to provide values from the right or |
* bottom edge of the page (since File_PDF 0.2.0, Horde 3.2). |
* |
* For JPEG, all flavors are allowed: |
* - gray scales |
* - true colors (24 bits) |
* - CMYK (32 bits) |
* |
* For PNG, are allowed: |
* - gray scales on at most 8 bits (256 levels) |
* - indexed colors |
* - true colors (24 bits) |
* but are not supported: |
* - Interlacing |
* - Alpha channel |
* |
* If a transparent color is defined, it will be taken into account (but |
* will be only interpreted by Acrobat 4 and above). |
* The format can be specified explicitly or inferred from the file |
* extension. |
* It is possible to put a link on the image. |
* |
* Remark: if an image is used several times, only one copy will be |
* embedded in the file. |
* |
* @param string $file Name of the file containing the image. |
* @param float $x Abscissa of the upper-left corner. |
* @param float $y Ordinate of the upper-left corner. |
* @param float $width Width of the image in the page. If equal to zero, |
* it is automatically calculated to keep the |
* original proportions. |
* @param float $height Height of the image in the page. If not specified |
* or equal to zero, it is automatically calculated |
* to keep the original proportions. |
* @param string $type Image format. Possible values are (case |
* insensitive) : JPG, JPEG, PNG. If not specified, |
* the type is inferred from the file extension. |
* @param mixed $link URL or identifier returned by File_PDF::addLink. |
* |
* @see File_PDF::addLink |
*/ |
function image($file, $x, $y, $width = 0, $height = 0, $type = '', |
$link = '') |
{ |
if ($x < 0) { |
$x += $this->w; |
} |
if ($y < 0) { |
$y += $this->h; |
} |
if (!isset($this->_images[$file])) { |
/* First use of image, get some file info. */ |
if ($type == '') { |
$pos = strrpos($file, '.'); |
if ($pos === false) { |
return $this->raiseError(sprintf('Image file has no extension and no type was specified: %s', $file)); |
} |
$type = substr($file, $pos + 1); |
} |
$type = strtolower($type); |
$mqr = get_magic_quotes_runtime(); |
set_magic_quotes_runtime(0); |
if ($type == 'jpg' || $type == 'jpeg') { |
$info = $this->_parseJPG($file); |
} elseif ($type == 'png') { |
$info = $this->_parsePNG($file); |
} else { |
return $this->raiseError(sprintf('Unsupported image file type: %s', $type)); |
} |
if (is_a($info, 'PEAR_Error')) { |
return $info; |
} |
set_magic_quotes_runtime($mqr); |
$info['i'] = count($this->_images) + 1; |
$this->_images[$file] = $info; |
} else { |
$info = $this->_images[$file]; |
} |
/* Make sure all vars are converted to pt scale. */ |
$x = $this->_toPt($x); |
$y = $this->_toPt($y); |
$width = $this->_toPt($width); |
$height = $this->_toPt($height); |
/* If not specified do automatic width and height calculations. */ |
if (empty($width) && empty($height)) { |
$width = $info['w']; |
$height = $info['h']; |
} elseif (empty($width)) { |
$width = $height * $info['w'] / $info['h']; |
} elseif (empty($height)) { |
$height = $width * $info['h'] / $info['w']; |
} |
$this->_out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q', $width, $height, $x, $this->hPt - ($y + $height), $info['i'])); |
/* Set any link if requested. */ |
if ($link) { |
$this->_link($x, $y, $width, $height, $link); |
} |
} |
/** |
* Performs a line break. The current abscissa goes back to the left |
* margin and the ordinate increases by the amount passed in parameter. |
* |
* @param float $height The height of the break. By default, the value |
* equals the height of the last printed cell. |
* |
* @see File_PDF::cell |
*/ |
function newLine($height = '') |
{ |
$this->x = $this->_left_margin; |
if (is_string($height)) { |
$this->y += $this->_last_height; |
} else { |
$this->y += $height; |
} |
} |
/** |
* Returns the abscissa of the current position in user units. |
* |
* @return float |
* |
* @see File_PDF::setX |
* @see File_PDF::getY |
* @see File_PDF::setY |
*/ |
function getX() |
{ |
return $this->x; |
} |
/** |
* Defines the abscissa of the current position. If the passed value is |
* negative, it is relative to the right of the page. |
* |
* @param float $x The value of the abscissa. |
* |
* @see File_PDF::getX |
* @see File_PDF::getY |
* @see File_PDF::setY |
* @see File_PDF::setXY |
*/ |
function setX($x) |
{ |
if ($x >= 0) { |
/* Absolute value. */ |
$this->x = $x; |
} else { |
/* Negative, so relative to right edge of the page. */ |
$this->x = $this->w + $x; |
} |
} |
/** |
* Returns the ordinate of the current position in user units. |
* |
* @return float |
* |
* @see File_PDF::setY |
* @see File_PDF::getX |
* @see File_PDF::setX |
*/ |
function getY() |
{ |
return $this->y; |
} |
/** |
* Defines the ordinate of the current position. If the passed value is |
* negative, it is relative to the bottom of the page. |
* |
* @param float $y The value of the ordinate. |
* |
* @see File_PDF::getX |
* @see File_PDF::getY |
* @see File_PDF::setY |
* @see File_PDF::setXY |
*/ |
function setY($y) |
{ |
if ($y >= 0) { |
/* Absolute value. */ |
$this->y = $y; |
} else { |
/* Negative, so relative to bottom edge of the page. */ |
$this->y = $this->h + $y; |
} |
} |
/** |
* Defines the abscissa and ordinate of the current position. If the |
* passed values are negative, they are relative respectively to the right |
* and bottom of the page. |
* |
* @param float $x The value of the abscissa. |
* @param float $y The value of the ordinate. |
* |
* @see File_PDF::setX |
* @see File_PDF::setY |
*/ |
function setXY($x, $y) |
{ |
$this->setY($y); |
$this->setX($x); |
} |
/** |
* Returns the raw PDF file. |
* |
* @see File_PDF::output |
*/ |
function getOutput() |
{ |
/* Check whether file has been closed. */ |
if ($this->_state < 3) { |
$this->close(); |
} |
return $this->_buffer; |
} |
/** |
* Function to output the buffered data to the browser. |
* |
* @param string $filename The filename for the output file. |
* @param boolean $inline True if inline, false if attachment. |
*/ |
function output($filename = 'unknown.pdf', $inline = false) |
{ |
/* Check whether file has been closed. */ |
if ($this->_state < 3) { |
$this->close(); |
} |
/* Check if headers have been sent. */ |
if (headers_sent()) { |
return $this->raiseError('Unable to send PDF file, some data has already been output to browser.'); |
} |
/* If HTTP_Download is not available return a PEAR_Error. */ |
if (!include_once 'HTTP/Download.php') { |
return $this->raiseError('Missing PEAR package HTTP_Download.'); |
} |
/* Params for the output. */ |
$disposition = !$inline ? HTTP_DOWNLOAD_ATTACHMENT : HTTP_DOWNLOAD_INLINE; |
$params = array('data' => $this->_buffer, |
'contenttype' => 'application/pdf', |
'contentdisposition' => array($disposition, $filename)); |
/* Output the file. */ |
return HTTP_Download::staticSend($params); |
} |
/** |
* Function to save the PDF file somewhere local to the server. |
* |
* @param string $filename The filename for the output file. |
*/ |
function save($filename = 'unknown.pdf') |
{ |
/* Check whether file has been closed. */ |
if ($this->_state < 3) { |
$this->close(); |
} |
$f = fopen($filename, 'wb'); |
if (!$f) { |
return $this->raiseError(sprintf('Unable to save PDF file: %s', $filename)); |
} |
fwrite($f, $this->_buffer, strlen($this->_buffer)); |
fclose($f); |
} |
function _toPt($val) |
{ |
return $val * $this->_scale; |
} |
function &_getFontFile($fontkey, $path = '') |
{ |
static $font_widths; |
if (!isset($font_widths[$fontkey])) { |
if (!empty($path)) { |
$file = $path . strtolower($fontkey) . '.php'; |
} else { |
$file = 'File/PDF/fonts/' . strtolower($fontkey) . '.php'; |
} |
include $file; |
if (!isset($font_widths[$fontkey])) { |
return $this->raiseError(sprintf('Could not include font metric file: %s', $file)); |
} |
} |
return $font_widths; |
} |
function _link($x, $y, $width, $height, $link) |
{ |
/* Save link to page links array. */ |
$this->_page_links[$this->_page][] = array($x, $y, $width, $height, $link); |
} |
function _beginDoc() |
{ |
/* Start document, but only if not yet started. */ |
if ($this->_state < 1) { |
$this->_state = 1; |
$this->_out('%PDF-1.3'); |
} |
} |
function _putPages() |
{ |
$nb = $this->_page; |
if (!empty($this->_alias_nb_pages)) { |
/* Replace number of pages. */ |
for ($n = 1; $n <= $nb; $n++) { |
$this->_pages[$n] = str_replace($this->_alias_nb_pages, $nb, $this->_pages[$n]); |
} |
} |
if ($this->_default_orientation == 'P') { |
$wPt = $this->fwPt; |
$hPt = $this->fhPt; |
} else { |
$wPt = $this->fhPt; |
$hPt = $this->fwPt; |
} |
$filter = ($this->_compress) ? '/Filter /FlateDecode ' : ''; |
for ($n = 1; $n <= $nb; $n++) { |
/* Page */ |
$this->_newobj(); |
$this->_out('<</Type /Page'); |
$this->_out('/Parent 1 0 R'); |
if (isset($this->_orientation_changes[$n])) { |
$this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]', $hPt, $wPt)); |
} |
$this->_out('/Resources 2 0 R'); |
if (isset($this->_page_links[$n])) { |
/* Links */ |
$annots = '/Annots ['; |
foreach ($this->_page_links[$n] as $pl) { |
$rect = sprintf('%.2f %.2f %.2f %.2f', $pl[0], $pl[1], $pl[0] + $pl[2], $pl[1] - $pl[3]); |
$annots .= '<</Type /Annot /Subtype /Link /Rect [' . $rect . '] /Border [0 0 0] '; |
if (is_string($pl[4])) { |
$annots .= '/A <</S /URI /URI ' . $this->_textString($pl[4]) . '>>>>'; |
} else { |
$l = $this->_links[$pl[4]]; |
$height = isset($this->_orientation_changes[$l[0]]) ? $wPt : $hPt; |
$annots .= sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>', 1 + 2 * $l[0], $height - $l[1] * $this->_scale); |
} |
} |
$this->_out($annots.']'); |
} |
$this->_out('/Contents ' . ($this->_n + 1) . ' 0 R>>'); |
$this->_out('endobj'); |
/* Page content */ |
$p = ($this->_compress) ? gzcompress($this->_pages[$n]) : $this->_pages[$n]; |
$this->_newobj(); |
$this->_out('<<' . $filter . '/Length ' . strlen($p) . '>>'); |
$this->_putStream($p); |
$this->_out('endobj'); |
} |
/* Pages root */ |
$this->_offsets[1] = strlen($this->_buffer); |
$this->_out('1 0 obj'); |
$this->_out('<</Type /Pages'); |
$kids = '/Kids ['; |
for ($i = 0; $i < $nb; $i++) { |
$kids .= (3 + 2 * $i) . ' 0 R '; |
} |
$this->_out($kids . ']'); |
$this->_out('/Count ' . $nb); |
$this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]', $wPt, $hPt)); |
$this->_out('>>'); |
$this->_out('endobj'); |
} |
function _putFonts() |
{ |
$nf = $this->_n; |
foreach ($this->_diffs as $diff) { |
/* Encodings */ |
$this->_newobj(); |
$this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [' . $diff . ']>>'); |
$this->_out('endobj'); |
} |
$mqr = get_magic_quotes_runtime(); |
set_magic_quotes_runtime(0); |
foreach ($this->_font_files as $file => $info) { |
/* Font file embedding. */ |
$this->_newobj(); |
$this->_font_files[$file]['n'] = $this->_n; |
$size = filesize($file); |
if (!$size) { |
return $this->raiseError('Font file not found.'); |
} |
$this->_out('<</Length ' . $size); |
if (substr($file, -2) == '.z') { |
$this->_out('/Filter /FlateDecode'); |
} |
$this->_out('/Length1 ' . $info['length1']); |
if (isset($info['length2'])) { |
$this->_out('/Length2 ' . $info['length2'] . ' /Length3 0'); |
} |
$this->_out('>>'); |
$f = fopen($file, 'rb'); |
$this->_putStream(fread($f, $size)); |
fclose($f); |
$this->_out('endobj'); |
} |
set_magic_quotes_runtime($mqr); |
foreach ($this->_fonts as $k => $font) { |
/* Font objects */ |
$this->_newobj(); |
$this->_fonts[$k]['n'] = $this->_n; |
$name = $font['name']; |
$this->_out('<</Type /Font'); |
$this->_out('/BaseFont /' . $name); |
if ($font['type'] == 'core') { |
/* Standard font. */ |
$this->_out('/Subtype /Type1'); |
if ($name != 'Symbol' && $name != 'ZapfDingbats') { |
$this->_out('/Encoding /WinAnsiEncoding'); |
} |
} else { |
/* Additional font. */ |
$this->_out('/Subtype /' . $font['type']); |
$this->_out('/FirstChar 32'); |
$this->_out('/LastChar 255'); |
$this->_out('/Widths ' . ($this->_n + 1) . ' 0 R'); |
$this->_out('/FontDescriptor ' . ($this->_n + 2) . ' 0 R'); |
if ($font['enc']) { |
if (isset($font['diff'])) { |
$this->_out('/Encoding ' . ($nf + $font['diff']).' 0 R'); |
} else { |
$this->_out('/Encoding /WinAnsiEncoding'); |
} |
} |
} |
$this->_out('>>'); |
$this->_out('endobj'); |
if ($font['type'] != 'core') { |
/* Widths. */ |
$this->_newobj(); |
$cw = &$font['cw']; |
$s = '['; |
for ($i = 32; $i <= 255; $i++) { |
$s .= $cw[chr($i)] . ' '; |
} |
$this->_out($s . ']'); |
$this->_out('endobj'); |
/* Descriptor. */ |
$this->_newobj(); |
$s = '<</Type /FontDescriptor /FontName /' . $name; |
foreach ($font['desc'] as $k => $v) { |
$s .= ' /' . $k . ' ' . $v; |
} |
$file = $font['file']; |
if ($file) { |
$s .= ' /FontFile' . ($font['type'] == 'Type1' ? '' : '2') . ' ' . $this->_font_files[$file]['n'] . ' 0 R'; |
} |
$this->_out($s . '>>'); |
$this->_out('endobj'); |
} |
} |
} |
function _putImages() |
{ |
$filter = ($this->_compress) ? '/Filter /FlateDecode ' : ''; |
foreach ($this->_images as $file => $info) { |
$this->_newobj(); |
$this->_images[$file]['n'] = $this->_n; |
$this->_out('<</Type /XObject'); |
$this->_out('/Subtype /Image'); |
$this->_out('/Width ' . $info['w']); |
$this->_out('/Height ' . $info['h']); |
if ($info['cs'] == 'Indexed') { |
$this->_out('/ColorSpace [/Indexed /DeviceRGB ' . (strlen($info['pal'])/3 - 1) . ' ' . ($this->_n + 1).' 0 R]'); |
} else { |
$this->_out('/ColorSpace /' . $info['cs']); |
if ($info['cs'] == 'DeviceCMYK') { |
$this->_out('/Decode [1 0 1 0 1 0 1 0]'); |
} |
} |
$this->_out('/BitsPerComponent ' . $info['bpc']); |
$this->_out('/Filter /' . $info['f']); |
if (isset($info['parms'])) { |
$this->_out($info['parms']); |
} |
if (isset($info['trns']) && is_array($info['trns'])) { |
$trns = ''; |
$i_max = count($info['trns']); |
for ($i = 0; $i < $i_max; $i++) { |
$trns .= $info['trns'][$i] . ' ' . $info['trns'][$i].' '; |
} |
$this->_out('/Mask [' . $trns . ']'); |
} |
$this->_out('/Length ' . strlen($info['data']) . '>>'); |
$this->_putStream($info['data']); |
$this->_out('endobj'); |
/* Palette. */ |
if ($info['cs'] == 'Indexed') { |
$this->_newobj(); |
$pal = ($this->_compress) ? gzcompress($info['pal']) : $info['pal']; |
$this->_out('<<' . $filter . '/Length ' . strlen($pal) . '>>'); |
$this->_putStream($pal); |
$this->_out('endobj'); |
} |
} |
} |
function _putResources() |
{ |
$this->_putFonts(); |
$this->_putImages(); |
/* Resource dictionary */ |
$this->_offsets[2] = strlen($this->_buffer); |
$this->_out('2 0 obj'); |
$this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); |
$this->_out('/Font <<'); |
foreach ($this->_fonts as $font) { |
$this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); |
} |
$this->_out('>>'); |
if (count($this->_images)) { |
$this->_out('/XObject <<'); |
foreach ($this->_images as $image) { |
$this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); |
} |
$this->_out('>>'); |
} |
$this->_out('>>'); |
$this->_out('endobj'); |
} |
function _putInfo() |
{ |
$this->_out('/Producer ' . $this->_textString('Horde PDF')); |
if (!empty($this->_info['title'])) { |
$this->_out('/Title ' . $this->_textString($this->_info['title'])); |
} |
if (!empty($this->_info['subject'])) { |
$this->_out('/Subject ' . $this->_textString($this->_info['subject'])); |
} |
if (!empty($this->_info['author'])) { |
$this->_out('/Author ' . $this->_textString($this->_info['author'])); |
} |
if (!empty($this->keywords)) { |
$this->_out('/Keywords ' . $this->_textString($this->keywords)); |
} |
if (!empty($this->creator)) { |
$this->_out('/Creator ' . $this->_textString($this->creator)); |
} |
$this->_out('/CreationDate ' . $this->_textString('D:' . date('YmdHis'))); |
} |
function _putCatalog() |
{ |
$this->_out('/Type /Catalog'); |
$this->_out('/Pages 1 0 R'); |
if ($this->_zoom_mode == 'fullpage') { |
$this->_out('/OpenAction [3 0 R /Fit]'); |
} elseif ($this->_zoom_mode == 'fullwidth') { |
$this->_out('/OpenAction [3 0 R /FitH null]'); |
} elseif ($this->_zoom_mode == 'real') { |
$this->_out('/OpenAction [3 0 R /XYZ null null 1]'); |
} elseif (!is_string($this->_zoom_mode)) { |
$this->_out('/OpenAction [3 0 R /XYZ null null ' . ($this->_zoom_mode / 100).']'); |
} |
if ($this->_layout_mode == 'single') { |
$this->_out('/PageLayout /SinglePage'); |
} elseif ($this->_layout_mode == 'continuous') { |
$this->_out('/PageLayout /OneColumn'); |
} elseif ($this->_layout_mode == 'two') { |
$this->_out('/PageLayout /TwoColumnLeft'); |
} |
} |
function _putTrailer() |
{ |
$this->_out('/Size ' . ($this->_n + 1)); |
$this->_out('/Root ' . $this->_n . ' 0 R'); |
$this->_out('/Info ' . ($this->_n - 1) . ' 0 R'); |
} |
function _endDoc() |
{ |
$this->_putPages(); |
$this->_putResources(); |
/* Info */ |
$this->_newobj(); |
$this->_out('<<'); |
$this->_putInfo(); |
$this->_out('>>'); |
$this->_out('endobj'); |
/* Catalog */ |
$this->_newobj(); |
$this->_out('<<'); |
$this->_putCatalog(); |
$this->_out('>>'); |
$this->_out('endobj'); |
/* Cross-ref */ |
$o = strlen($this->_buffer); |
$this->_out('xref'); |
$this->_out('0 ' . ($this->_n + 1)); |
$this->_out('0000000000 65535 f '); |
for ($i = 1; $i <= $this->_n; $i++) { |
$this->_out(sprintf('%010d 00000 n ', $this->_offsets[$i])); |
} |
/* Trailer */ |
$this->_out('trailer'); |
$this->_out('<<'); |
$this->_putTrailer(); |
$this->_out('>>'); |
$this->_out('startxref'); |
$this->_out($o); |
$this->_out('%%EOF'); |
$this->_state = 3; |
} |
function _beginPage($orientation) |
{ |
$this->_page++; |
$this->_pages[$this->_page] = ''; |
$this->_state = 2; |
$this->x = $this->_left_margin; |
$this->y = $this->_top_margin; |
$this->_last_height = 0; |
/* Page orientation */ |
if (!$orientation) { |
$orientation = $this->_default_orientation; |
} else { |
$orientation = strtoupper($orientation[0]); |
if ($orientation != $this->_default_orientation) { |
$this->_orientation_changes[$this->_page] = true; |
} |
} |
if ($orientation != $this->_current_orientation) { |
/* Change orientation */ |
if ($orientation == 'P') { |
$this->wPt = $this->fwPt; |
$this->hPt = $this->fhPt; |
$this->w = $this->fw; |
$this->h = $this->fh; |
} else { |
$this->wPt = $this->fhPt; |
$this->hPt = $this->fwPt; |
$this->w = $this->fh; |
$this->h = $this->fw; |
} |
$this->_page_break_trigger = $this->h - $this->_break_margin; |
$this->_current_orientation = $orientation; |
} |
} |
function _endPage() |
{ |
/* End of page contents */ |
$this->_state = 1; |
} |
function _newobj() |
{ |
/* Begin a new object */ |
$this->_n++; |
$this->_offsets[$this->_n] = strlen($this->_buffer); |
$this->_out($this->_n . ' 0 obj'); |
} |
function _doUnderline($x, $y, $text) |
{ |
/* Set the rectangle width according to text width. */ |
$width = $this->getStringWidth($text, true); |
/* Set rectangle position and height, using underline position and |
* thickness settings scaled by the font size. */ |
$y = $y + ($this->_current_font['up'] * $this->_font_size_pt / 1000); |
$height = -$this->_current_font['ut'] * $this->_font_size_pt / 1000; |
return sprintf('%.2f %.2f %.2f %.2f re f', $x, $y, $width, $height); |
} |
function _parseJPG($file) |
{ |
/* Extract info from a JPEG file. */ |
$img = @getimagesize($file); |
if (!$img) { |
return $this->raiseError(sprintf('Missing or incorrect image file: %s', $file)); |
} |
if ($img[2] != 2) { |
return $this->raiseError(sprintf('Not a JPEG file: %s', $file)); |
} |
if (!isset($img['channels']) || $img['channels'] == 3) { |
$colspace = 'DeviceRGB'; |
} elseif ($img['channels'] == 4) { |
$colspace = 'DeviceCMYK'; |
} else { |
$colspace = 'DeviceGray'; |
} |
$bpc = isset($img['bits']) ? $img['bits'] : 8; |
/* Read whole file. */ |
$f = fopen($file, 'rb'); |
$data = fread($f, filesize($file)); |
fclose($f); |
return array('w' => $img[0], 'h' => $img[1], 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'DCTDecode', 'data' => $data); |
} |
function _parsePNG($file) |
{ |
/* Extract info from a PNG file. */ |
$f = fopen($file, 'rb'); |
if (!$f) { |
return $this->raiseError(sprintf('Unable to open image file: %s', $file)); |
} |
/* Check signature. */ |
if (fread($f, 8) != chr(137) . 'PNG' . chr(13) . chr(10) . chr(26) . chr(10)) { |
return $this->raiseError(sprintf('Not a PNG file: %s', $file)); |
} |
/* Read header chunk. */ |
fread($f, 4); |
if (fread($f, 4) != 'IHDR') { |
return $this->raiseError(sprintf('Incorrect PNG file: %s', $file)); |
} |
$width = $this->_freadInt($f); |
$height = $this->_freadInt($f); |
$bpc = ord(fread($f, 1)); |
if ($bpc > 8) { |
return $this->raiseError(sprintf('16-bit depth not supported: %s', $file)); |
} |
$ct = ord(fread($f, 1)); |
if ($ct == 0) { |
$colspace = 'DeviceGray'; |
} elseif ($ct == 2) { |
$colspace = 'DeviceRGB'; |
} elseif ($ct == 3) { |
$colspace = 'Indexed'; |
} else { |
return $this->raiseError(sprintf('Alpha channel not supported: %s', $file)); |
} |
if (ord(fread($f, 1)) != 0) { |
return $this->raiseError(sprintf('Unknown compression method: %s', $file)); |
} |
if (ord(fread($f, 1)) != 0) { |
return $this->raiseError(sprintf('Unknown filter method: %s', $file)); |
} |
if (ord(fread($f, 1)) != 0) { |
return $this->raiseError(sprintf('Interlacing not supported: %s', $file)); |
} |
fread($f, 4); |
$parms = '/DecodeParms <</Predictor 15 /Colors ' . ($ct == 2 ? 3 : 1).' /BitsPerComponent ' . $bpc . ' /Columns ' . $width.'>>'; |
/* Scan chunks looking for palette, transparency and image data. */ |
$pal = ''; |
$trns = ''; |
$data = ''; |
do { |
$n = $this->_freadInt($f); |
$type = fread($f, 4); |
if ($type == 'PLTE') { |
/* Read palette */ |
$pal = fread($f, $n); |
fread($f, 4); |
} elseif ($type == 'tRNS') { |
/* Read transparency info */ |
$t = fread($f, $n); |
if ($ct == 0) { |
$trns = array(ord(substr($t, 1, 1))); |
} elseif ($ct == 2) { |
$trns = array(ord(substr($t, 1, 1)), ord(substr($t, 3, 1)), ord(substr($t, 5, 1))); |
} else { |
$pos = strpos($t, chr(0)); |
if (is_int($pos)) { |
$trns = array($pos); |
} |
} |
fread($f, 4); |
} elseif ($type == 'IDAT') { |
/* Read image data block */ |
$data .= fread($f, $n); |
fread($f, 4); |
} elseif ($type == 'IEND') { |
break; |
} else { |
fread($f, $n + 4); |
} |
} while ($n); |
if ($colspace == 'Indexed' && empty($pal)) { |
return $this->raiseError(sprintf('Missing palette in: %s', $file)); |
} |
fclose($f); |
return array('w' => $width, 'h' => $height, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'FlateDecode', 'parms' => $parms, 'pal' => $pal, 'trns' => $trns, 'data' => $data); |
} |
function _freadInt($f) |
{ |
/* Read a 4-byte integer from file. */ |
$i = ord(fread($f, 1)) << 24; |
$i += ord(fread($f, 1)) << 16; |
$i += ord(fread($f, 1)) << 8; |
$i += ord(fread($f, 1)); |
return $i; |
} |
function _textString($s) |
{ |
/* Format a text string */ |
return '(' . $this->_escape($s) . ')'; |
} |
function _escape($s) |
{ |
/* Add \ before \, ( and ) */ |
return str_replace(array(')','(','\\'), |
array('\\)','\\(','\\\\'), |
$s); |
} |
function _putStream($s) |
{ |
$this->_out('stream'); |
$this->_out($s); |
$this->_out('endstream'); |
} |
function _out($s) |
{ |
/* Add a line to the document. */ |
if ($this->_state == 2) { |
$this->_pages[$this->_page] .= $s . "\n"; |
} else { |
$this->_buffer .= $s . "\n"; |
} |
} |
} |
/branches/v1.6-croc/jrest/lib/JSON.php |
---|
New file |
0,0 → 1,806 |
<?php |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
/** |
* Converts to and from JSON format. |
* |
* JSON (JavaScript Object Notation) is a lightweight data-interchange |
* format. It is easy for humans to read and write. It is easy for machines |
* to parse and generate. It is based on a subset of the JavaScript |
* Programming Language, Standard ECMA-262 3rd Edition - December 1999. |
* This feature can also be found in Python. JSON is a text format that is |
* completely language independent but uses conventions that are familiar |
* to programmers of the C-family of languages, including C, C++, C#, Java, |
* JavaScript, Perl, TCL, and many others. These properties make JSON an |
* ideal data-interchange language. |
* |
* This package provides a simple encoder and decoder for JSON notation. It |
* is intended for use with client-side Javascript applications that make |
* use of HTTPRequest to perform server communication functions - data can |
* be encoded into JSON notation for use in a client-side javascript, or |
* decoded from incoming Javascript requests. JSON format is native to |
* Javascript, and can be directly eval()'ed with no further parsing |
* overhead |
* |
* All strings should be in ASCII or UTF-8 format! |
* |
* LICENSE: Redistribution and use in source and binary forms, with or |
* without modification, are permitted provided that the following |
* conditions are met: Redistributions of source code must retain the |
* above copyright notice, this list of conditions and the following |
* disclaimer. 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. |
* |
* THIS SOFTWARE IS PROVIDED ``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 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. |
* |
* @category |
* @package Services_JSON |
* @author Michal Migurski <mike-json@teczno.com> |
* @author Matt Knapp <mdknapp[at]gmail[dot]com> |
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com> |
* @copyright 2005 Michal Migurski |
* @version CVS: $Id$ |
* @license http://www.opensource.org/licenses/bsd-license.php |
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 |
*/ |
/** |
* Marker constant for Services_JSON::decode(), used to flag stack state |
*/ |
define('SERVICES_JSON_SLICE', 1); |
/** |
* Marker constant for Services_JSON::decode(), used to flag stack state |
*/ |
define('SERVICES_JSON_IN_STR', 2); |
/** |
* Marker constant for Services_JSON::decode(), used to flag stack state |
*/ |
define('SERVICES_JSON_IN_ARR', 3); |
/** |
* Marker constant for Services_JSON::decode(), used to flag stack state |
*/ |
define('SERVICES_JSON_IN_OBJ', 4); |
/** |
* Marker constant for Services_JSON::decode(), used to flag stack state |
*/ |
define('SERVICES_JSON_IN_CMT', 5); |
/** |
* Behavior switch for Services_JSON::decode() |
*/ |
define('SERVICES_JSON_LOOSE_TYPE', 16); |
/** |
* Behavior switch for Services_JSON::decode() |
*/ |
define('SERVICES_JSON_SUPPRESS_ERRORS', 32); |
/** |
* Converts to and from JSON format. |
* |
* Brief example of use: |
* |
* <code> |
* // create a new instance of Services_JSON |
* $json = new Services_JSON(); |
* |
* // convert a complexe value to JSON notation, and send it to the browser |
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); |
* $output = $json->encode($value); |
* |
* print($output); |
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] |
* |
* // accept incoming POST data, assumed to be in JSON notation |
* $input = file_get_contents('php://input', 1000000); |
* $value = $json->decode($input); |
* </code> |
*/ |
class Services_JSON |
{ |
/** |
* constructs a new JSON instance |
* |
* @param int $use object behavior flags; combine with boolean-OR |
* |
* possible values: |
* - SERVICES_JSON_LOOSE_TYPE: loose typing. |
* "{...}" syntax creates associative arrays |
* instead of objects in decode(). |
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. |
* Values which can't be encoded (e.g. resources) |
* appear as NULL instead of throwing errors. |
* By default, a deeply-nested resource will |
* bubble up with an error, so all return values |
* from encode() should be checked with isError() |
*/ |
function Services_JSON($use = 0) |
{ |
$this->use = $use; |
} |
/** |
* convert a string from one UTF-16 char to one UTF-8 char |
* |
* Normally should be handled by mb_convert_encoding, but |
* provides a slower PHP-only method for installations |
* that lack the multibye string extension. |
* |
* @param string $utf16 UTF-16 character |
* @return string UTF-8 character |
* @access private |
*/ |
function utf162utf8($utf16) |
{ |
// oh please oh please oh please oh please oh please |
if(function_exists('mb_convert_encoding')) { |
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); |
} |
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); |
switch(true) { |
case ((0x7F & $bytes) == $bytes): |
// this case should never be reached, because we are in ASCII range |
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
return chr(0x7F & $bytes); |
case (0x07FF & $bytes) == $bytes: |
// return a 2-byte UTF-8 character |
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
return chr(0xC0 | (($bytes >> 6) & 0x1F)) |
. chr(0x80 | ($bytes & 0x3F)); |
case (0xFFFF & $bytes) == $bytes: |
// return a 3-byte UTF-8 character |
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
return chr(0xE0 | (($bytes >> 12) & 0x0F)) |
. chr(0x80 | (($bytes >> 6) & 0x3F)) |
. chr(0x80 | ($bytes & 0x3F)); |
} |
// ignoring UTF-32 for now, sorry |
return ''; |
} |
/** |
* convert a string from one UTF-8 char to one UTF-16 char |
* |
* Normally should be handled by mb_convert_encoding, but |
* provides a slower PHP-only method for installations |
* that lack the multibye string extension. |
* |
* @param string $utf8 UTF-8 character |
* @return string UTF-16 character |
* @access private |
*/ |
function utf82utf16($utf8) |
{ |
// oh please oh please oh please oh please oh please |
if(function_exists('mb_convert_encoding')) { |
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); |
} |
switch(strlen($utf8)) { |
case 1: |
// this case should never be reached, because we are in ASCII range |
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
return $utf8; |
case 2: |
// return a UTF-16 character from a 2-byte UTF-8 char |
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
return chr(0x07 & (ord($utf8{0}) >> 2)) |
. chr((0xC0 & (ord($utf8{0}) << 6)) |
| (0x3F & ord($utf8{1}))); |
case 3: |
// return a UTF-16 character from a 3-byte UTF-8 char |
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
return chr((0xF0 & (ord($utf8{0}) << 4)) |
| (0x0F & (ord($utf8{1}) >> 2))) |
. chr((0xC0 & (ord($utf8{1}) << 6)) |
| (0x7F & ord($utf8{2}))); |
} |
// ignoring UTF-32 for now, sorry |
return ''; |
} |
/** |
* encodes an arbitrary variable into JSON format |
* |
* @param mixed $var any number, boolean, string, array, or object to be encoded. |
* see argument 1 to Services_JSON() above for array-parsing behavior. |
* if var is a strng, note that encode() always expects it |
* to be in ASCII or UTF-8 format! |
* |
* @return mixed JSON string representation of input var or an error if a problem occurs |
* @access public |
*/ |
function encode($var) |
{ |
switch (gettype($var)) { |
case 'boolean': |
return $var ? 'true' : 'false'; |
case 'NULL': |
return 'null'; |
case 'integer': |
return (int) $var; |
case 'double': |
case 'float': |
return (float) $var; |
case 'string': |
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT |
$ascii = ''; |
$strlen_var = strlen($var); |
/* |
* Iterate over every character in the string, |
* escaping with a slash or encoding to UTF-8 where necessary |
*/ |
for ($c = 0; $c < $strlen_var; ++$c) { |
$ord_var_c = ord($var{$c}); |
switch (true) { |
case $ord_var_c == 0x08: |
$ascii .= '\b'; |
break; |
case $ord_var_c == 0x09: |
$ascii .= '\t'; |
break; |
case $ord_var_c == 0x0A: |
$ascii .= '\n'; |
break; |
case $ord_var_c == 0x0C: |
$ascii .= '\f'; |
break; |
case $ord_var_c == 0x0D: |
$ascii .= '\r'; |
break; |
case $ord_var_c == 0x22: |
case $ord_var_c == 0x2F: |
case $ord_var_c == 0x5C: |
// double quote, slash, slosh |
$ascii .= '\\'.$var{$c}; |
break; |
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): |
// characters U-00000000 - U-0000007F (same as ASCII) |
$ascii .= $var{$c}; |
break; |
case (($ord_var_c & 0xE0) == 0xC0): |
// characters U-00000080 - U-000007FF, mask 110XXXXX |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
$char = pack('C*', $ord_var_c, ord($var{$c + 1})); |
$c += 1; |
$utf16 = $this->utf82utf16($char); |
$ascii .= sprintf('\u%04s', bin2hex($utf16)); |
break; |
case (($ord_var_c & 0xF0) == 0xE0): |
// characters U-00000800 - U-0000FFFF, mask 1110XXXX |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
$char = pack('C*', $ord_var_c, |
ord($var{$c + 1}), |
ord($var{$c + 2})); |
$c += 2; |
$utf16 = $this->utf82utf16($char); |
$ascii .= sprintf('\u%04s', bin2hex($utf16)); |
break; |
case (($ord_var_c & 0xF8) == 0xF0): |
// characters U-00010000 - U-001FFFFF, mask 11110XXX |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
$char = pack('C*', $ord_var_c, |
ord($var{$c + 1}), |
ord($var{$c + 2}), |
ord($var{$c + 3})); |
$c += 3; |
$utf16 = $this->utf82utf16($char); |
$ascii .= sprintf('\u%04s', bin2hex($utf16)); |
break; |
case (($ord_var_c & 0xFC) == 0xF8): |
// characters U-00200000 - U-03FFFFFF, mask 111110XX |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
$char = pack('C*', $ord_var_c, |
ord($var{$c + 1}), |
ord($var{$c + 2}), |
ord($var{$c + 3}), |
ord($var{$c + 4})); |
$c += 4; |
$utf16 = $this->utf82utf16($char); |
$ascii .= sprintf('\u%04s', bin2hex($utf16)); |
break; |
case (($ord_var_c & 0xFE) == 0xFC): |
// characters U-04000000 - U-7FFFFFFF, mask 1111110X |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
$char = pack('C*', $ord_var_c, |
ord($var{$c + 1}), |
ord($var{$c + 2}), |
ord($var{$c + 3}), |
ord($var{$c + 4}), |
ord($var{$c + 5})); |
$c += 5; |
$utf16 = $this->utf82utf16($char); |
$ascii .= sprintf('\u%04s', bin2hex($utf16)); |
break; |
} |
} |
return '"'.$ascii.'"'; |
case 'array': |
/* |
* As per JSON spec if any array key is not an integer |
* we must treat the the whole array as an object. We |
* also try to catch a sparsely populated associative |
* array with numeric keys here because some JS engines |
* will create an array with empty indexes up to |
* max_index which can cause memory issues and because |
* the keys, which may be relevant, will be remapped |
* otherwise. |
* |
* As per the ECMA and JSON specification an object may |
* have any string as a property. Unfortunately due to |
* a hole in the ECMA specification if the key is a |
* ECMA reserved word or starts with a digit the |
* parameter is only accessible using ECMAScript's |
* bracket notation. |
*/ |
// treat as a JSON object |
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { |
$properties = array_map(array($this, 'name_value'), |
array_keys($var), |
array_values($var)); |
foreach($properties as $property) { |
if(Services_JSON::isError($property)) { |
return $property; |
} |
} |
return '{' . join(',', $properties) . '}'; |
} |
// treat it like a regular array |
$elements = array_map(array($this, 'encode'), $var); |
foreach($elements as $element) { |
if(Services_JSON::isError($element)) { |
return $element; |
} |
} |
return '[' . join(',', $elements) . ']'; |
case 'object': |
$vars = get_object_vars($var); |
$properties = array_map(array($this, 'name_value'), |
array_keys($vars), |
array_values($vars)); |
foreach($properties as $property) { |
if(Services_JSON::isError($property)) { |
return $property; |
} |
} |
return '{' . join(',', $properties) . '}'; |
default: |
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) |
? 'null' |
: new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); |
} |
} |
/** |
* array-walking function for use in generating JSON-formatted name-value pairs |
* |
* @param string $name name of key to use |
* @param mixed $value reference to an array element to be encoded |
* |
* @return string JSON-formatted name-value pair, like '"name":value' |
* @access private |
*/ |
function name_value($name, $value) |
{ |
$encoded_value = $this->encode($value); |
if(Services_JSON::isError($encoded_value)) { |
return $encoded_value; |
} |
return $this->encode(strval($name)) . ':' . $encoded_value; |
} |
/** |
* reduce a string by removing leading and trailing comments and whitespace |
* |
* @param $str string string value to strip of comments and whitespace |
* |
* @return string string value stripped of comments and whitespace |
* @access private |
*/ |
function reduce_string($str) |
{ |
$str = preg_replace(array( |
// eliminate single line comments in '// ...' form |
'#^\s*//(.+)$#m', |
// eliminate multi-line comments in '/* ... */' form, at start of string |
'#^\s*/\*(.+)\*/#Us', |
// eliminate multi-line comments in '/* ... */' form, at end of string |
'#/\*(.+)\*/\s*$#Us' |
), '', $str); |
// eliminate extraneous space |
return trim($str); |
} |
/** |
* decodes a JSON string into appropriate variable |
* |
* @param string $str JSON-formatted string |
* |
* @return mixed number, boolean, string, array, or object |
* corresponding to given JSON input string. |
* See argument 1 to Services_JSON() above for object-output behavior. |
* Note that decode() always returns strings |
* in ASCII or UTF-8 format! |
* @access public |
*/ |
function decode($str) |
{ |
$str = $this->reduce_string($str); |
switch (strtolower($str)) { |
case 'true': |
return true; |
case 'false': |
return false; |
case 'null': |
return null; |
default: |
$m = array(); |
if (is_numeric($str)) { |
// Lookie-loo, it's a number |
// This would work on its own, but I'm trying to be |
// good about returning integers where appropriate: |
// return (float)$str; |
// Return float or int, as appropriate |
return ((float)$str == (integer)$str) |
? (integer)$str |
: (float)$str; |
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { |
// STRINGS RETURNED IN UTF-8 FORMAT |
$delim = substr($str, 0, 1); |
$chrs = substr($str, 1, -1); |
$utf8 = ''; |
$strlen_chrs = strlen($chrs); |
for ($c = 0; $c < $strlen_chrs; ++$c) { |
$substr_chrs_c_2 = substr($chrs, $c, 2); |
$ord_chrs_c = ord($chrs{$c}); |
switch (true) { |
case $substr_chrs_c_2 == '\b': |
$utf8 .= chr(0x08); |
++$c; |
break; |
case $substr_chrs_c_2 == '\t': |
$utf8 .= chr(0x09); |
++$c; |
break; |
case $substr_chrs_c_2 == '\n': |
$utf8 .= chr(0x0A); |
++$c; |
break; |
case $substr_chrs_c_2 == '\f': |
$utf8 .= chr(0x0C); |
++$c; |
break; |
case $substr_chrs_c_2 == '\r': |
$utf8 .= chr(0x0D); |
++$c; |
break; |
case $substr_chrs_c_2 == '\\"': |
case $substr_chrs_c_2 == '\\\'': |
case $substr_chrs_c_2 == '\\\\': |
case $substr_chrs_c_2 == '\\/': |
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || |
($delim == "'" && $substr_chrs_c_2 != '\\"')) { |
$utf8 .= $chrs{++$c}; |
} |
break; |
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): |
// single, escaped unicode character |
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) |
. chr(hexdec(substr($chrs, ($c + 4), 2))); |
$utf8 .= $this->utf162utf8($utf16); |
$c += 5; |
break; |
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): |
$utf8 .= $chrs{$c}; |
break; |
case ($ord_chrs_c & 0xE0) == 0xC0: |
// characters U-00000080 - U-000007FF, mask 110XXXXX |
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
$utf8 .= substr($chrs, $c, 2); |
++$c; |
break; |
case ($ord_chrs_c & 0xF0) == 0xE0: |
// characters U-00000800 - U-0000FFFF, mask 1110XXXX |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
$utf8 .= substr($chrs, $c, 3); |
$c += 2; |
break; |
case ($ord_chrs_c & 0xF8) == 0xF0: |
// characters U-00010000 - U-001FFFFF, mask 11110XXX |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
$utf8 .= substr($chrs, $c, 4); |
$c += 3; |
break; |
case ($ord_chrs_c & 0xFC) == 0xF8: |
// characters U-00200000 - U-03FFFFFF, mask 111110XX |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
$utf8 .= substr($chrs, $c, 5); |
$c += 4; |
break; |
case ($ord_chrs_c & 0xFE) == 0xFC: |
// characters U-04000000 - U-7FFFFFFF, mask 1111110X |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 |
$utf8 .= substr($chrs, $c, 6); |
$c += 5; |
break; |
} |
} |
return $utf8; |
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { |
// array, or object notation |
if ($str{0} == '[') { |
$stk = array(SERVICES_JSON_IN_ARR); |
$arr = array(); |
} else { |
if ($this->use & SERVICES_JSON_LOOSE_TYPE) { |
$stk = array(SERVICES_JSON_IN_OBJ); |
$obj = array(); |
} else { |
$stk = array(SERVICES_JSON_IN_OBJ); |
$obj = new stdClass(); |
} |
} |
array_push($stk, array('what' => SERVICES_JSON_SLICE, |
'where' => 0, |
'delim' => false)); |
$chrs = substr($str, 1, -1); |
$chrs = $this->reduce_string($chrs); |
if ($chrs == '') { |
if (reset($stk) == SERVICES_JSON_IN_ARR) { |
return $arr; |
} else { |
return $obj; |
} |
} |
//print("\nparsing {$chrs}\n"); |
$strlen_chrs = strlen($chrs); |
for ($c = 0; $c <= $strlen_chrs; ++$c) { |
$top = end($stk); |
$substr_chrs_c_2 = substr($chrs, $c, 2); |
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { |
// found a comma that is not inside a string, array, etc., |
// OR we've reached the end of the character list |
$slice = substr($chrs, $top['where'], ($c - $top['where'])); |
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); |
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); |
if (reset($stk) == SERVICES_JSON_IN_ARR) { |
// we are in an array, so just push an element onto the stack |
array_push($arr, $this->decode($slice)); |
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { |
// we are in an object, so figure |
// out the property name and set an |
// element in an associative array, |
// for now |
$parts = array(); |
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { |
// "name":value pair |
$key = $this->decode($parts[1]); |
$val = $this->decode($parts[2]); |
if ($this->use & SERVICES_JSON_LOOSE_TYPE) { |
$obj[$key] = $val; |
} else { |
$obj->$key = $val; |
} |
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { |
// name:value pair, where name is unquoted |
$key = $parts[1]; |
$val = $this->decode($parts[2]); |
if ($this->use & SERVICES_JSON_LOOSE_TYPE) { |
$obj[$key] = $val; |
} else { |
$obj->$key = $val; |
} |
} |
} |
} elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { |
// found a quote, and we are not inside a string |
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); |
//print("Found start of string at {$c}\n"); |
} elseif (($chrs{$c} == $top['delim']) && |
($top['what'] == SERVICES_JSON_IN_STR) && |
((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { |
// found a quote, we're in a string, and it's not escaped |
// we know that it's not escaped becase there is _not_ an |
// odd number of backslashes at the end of the string so far |
array_pop($stk); |
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); |
} elseif (($chrs{$c} == '[') && |
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { |
// found a left-bracket, and we are in an array, object, or slice |
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); |
//print("Found start of array at {$c}\n"); |
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { |
// found a right-bracket, and we're in an array |
array_pop($stk); |
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); |
} elseif (($chrs{$c} == '{') && |
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { |
// found a left-brace, and we are in an array, object, or slice |
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); |
//print("Found start of object at {$c}\n"); |
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { |
// found a right-brace, and we're in an object |
array_pop($stk); |
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); |
} elseif (($substr_chrs_c_2 == '/*') && |
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { |
// found a comment start, and we are in an array, object, or slice |
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); |
$c++; |
//print("Found start of comment at {$c}\n"); |
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { |
// found a comment end, and we're in one now |
array_pop($stk); |
$c++; |
for ($i = $top['where']; $i <= $c; ++$i) |
$chrs = substr_replace($chrs, ' ', $i, 1); |
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); |
} |
} |
if (reset($stk) == SERVICES_JSON_IN_ARR) { |
return $arr; |
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { |
return $obj; |
} |
} |
} |
} |
/** |
* @todo Ultimately, this should just call PEAR::isError() |
*/ |
function isError($data, $code = null) |
{ |
if (class_exists('pear')) { |
return PEAR::isError($data, $code); |
} elseif (is_object($data) && (get_class($data) == 'services_json_error' || |
is_subclass_of($data, 'services_json_error'))) { |
return true; |
} |
return false; |
} |
} |
if (class_exists('PEAR_Error')) { |
class Services_JSON_Error extends PEAR_Error |
{ |
function Services_JSON_Error($message = 'unknown error', $code = null, |
$mode = null, $options = null, $userinfo = null) |
{ |
parent::PEAR_Error($message, $code, $mode, $options, $userinfo); |
} |
} |
} else { |
/** |
* @todo Ultimately, this class shall be descended from PEAR_Error |
*/ |
class Services_JSON_Error |
{ |
function Services_JSON_Error($message = 'unknown error', $code = null, |
$mode = null, $options = null, $userinfo = null) |
{ |
} |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/PDFProductor.php |
---|
New file |
0,0 → 1,14 |
<?php |
Class PDFProductor { |
function initPDF() { |
require_once("PDF.php"); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/GestionImage.php |
---|
New file |
0,0 → 1,309 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurelien Peronnet <aurelien@tela-botanica.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* Classe de gestion de l'ajout, modification et suppression des images |
* |
* in=utf8 |
* out=utf8 |
* |
*/ |
class GestionImage extends Cel { |
/** |
* Ajoute une image dans la base de données et stocke le fichier en fabriquant les miniatures, |
* renvoie le nouvel id d'image en cas de succès |
* |
* @param int $id_utilisateur identifiant de l'utilisateur |
* @param array $infos_fichier les infos sur le fichier à traiter, de la même forme que les |
* élements du tableau $_FILES de php |
*/ |
public function ajouterImage($id_utilisateur, $infos_fichier) { |
$nouvel_ordre = $this->obtenirNouvelOrdrePourUtilisateur($id_utilisateur); |
if (!$nouvel_ordre) { |
$message = 'Erreur lors du calcul du nouvel ordre de l\'image'; |
$this->logger($message); |
} |
$extracteur_metadonnees = new ExtracteurMetadonnees(); |
$informations_image = $extracteur_metadonnees->extraireMetadonnees($infos_fichier['tmp_name']) ; |
if(!$informations_image) { |
$message = 'Erreur lors de l\'extraction des metadonnées'; |
$this->logger($message); |
} |
// ajout de quelques informations supplémentaire, en sus |
// des metadonnées dejà extraites |
$informations_image['ordre'] = $nouvel_ordre ; |
$informations_image['publiable_eflore'] = 'false' ; |
$informations_image['nom_original'] = $infos_fichier['name'] ; |
// le md5 du fichier sert à repérer les images en doublons |
$informations_image['md5'] = md5_file($infos_fichier['tmp_name']) ; |
$informations_image['ce_utilisateur'] = $id_utilisateur ; |
$infos_utilisateur = $this->getInfosComplementairesUtilisateur($id_utilisateur); |
$informations_image['courriel_utilisateur'] = $infos_utilisateur['courriel']; |
$informations_image['nom_utilisateur'] = $infos_utilisateur['nom']; |
$informations_image['prenom_utilisateur'] = $infos_utilisateur['prenom']; |
$requete_insertion_infos_image = $this->construireRequeteInsertionImage($informations_image); |
// important ! ne pas utiliser la fonction executerRequete qui renvoie une erreur si la requete contient des | (pipes) |
// ce qui est fréquent dans les métadonnées |
// TODO: corriger la fonction ou bien continuer à utiliser executerRequeteSimple |
$resultat_insertion_infos_image = $this->executerRequeteSimple($requete_insertion_infos_image); |
if (!$resultat_insertion_infos_image) { |
$message = "Echec de l'insertion dans la base de donnees : " ; |
$this->logger($message); |
} |
$id_nouvelle_image = $this->obtenirIdImagePourIdentifiantEtOrdre($id_utilisateur, $nouvel_ordre); |
if (!$id_nouvelle_image) |
{ |
$message = 'Impossible d\'obtenir le nouvel identifiant de l\'image' ; |
$this->logger($message); |
} |
$manipulateur_image = new ImageRecreation($this->config); |
$fichier_stocke = $manipulateur_image->stockerFichierEtCreerMiniatures($infos_fichier,$id_nouvelle_image); |
if (!$fichier_stocke) { |
$message = 'Erreur lors du stockage du fichier' ; |
$this->logger($message); |
} |
return $id_nouvelle_image; |
} |
private function obtenirNouvelOrdrePourUtilisateur($id_utilisateur) { |
$nouvel_ordre = 0 ; |
$requete_selection_ordre_max ='SELECT MAX(ordre) as max_ordre FROM cel_images WHERE ce_utilisateur = '.$this->proteger($id_utilisateur) ; |
$resultat_requete_ordre_max = $this->executerRequete($requete_selection_ordre_max); |
if($resultat_requete_ordre_max !== false) { |
$nouvel_ordre = $resultat_requete_ordre_max[0]['max_ordre']; |
$nouvel_ordre++; |
} |
return $nouvel_ordre; |
} |
private function obtenirIdImagePourIdentifiantEtOrdre($id_utilisateur, $ordre) { |
$id_image = false; |
$requete_id_image ='SELECT id_image FROM cel_images WHERE ce_utilisateur = '.$this->proteger($id_utilisateur).' AND ordre = '.$ordre ; |
$resultat_id_image = $this->executerRequete($requete_id_image); |
if (count($resultat_id_image) > 0) |
{ |
$id_image = $resultat_id_image[0]['id_image']; |
} |
return $id_image; |
} |
private function construireRequeteInsertionImage($informations_image) { |
$requete_insertion_image = "INSERT INTO cel_images "; |
$champs_a_inserer = '' ; |
$valeurs_a_inserer = '' ; |
foreach ($informations_image as $champ => $valeur) |
{ |
$champs_a_inserer .= $champ.',' ; |
if (is_null($valeur)) |
{ |
$valeurs_a_inserer .= 'NULL,' ; |
} |
else |
{ |
$valeurs_a_inserer .= $this->proteger($valeur).',' ; |
} |
} |
$champs_a_inserer .= 'date_modification,' ; |
$valeurs_a_inserer .= '"0000-00-00 00:00:00",' ; |
$champs_a_inserer .= 'date_creation' ; |
$valeurs_a_inserer .= 'CURRENT_TIMESTAMP()' ; |
$requete_insertion_image .= "(".$champs_a_inserer.") VALUES (".$valeurs_a_inserer.")" ; |
return $requete_insertion_image; |
} |
/** |
* Modifie les champs de metadonnées d'une image |
* |
* @param array $utilisateur identifiant utilisateur |
* @param array $id id de l'image |
* @param array $parametres un taleau contenant des valeurs indexées par les noms de champs de la bdd |
* |
* @return boolean true ou false suivant le succès de l'opération |
* |
*/ |
public function modifierImage($utilisateur, $id_image, $parametres) { |
$requete_mise_a_jour_image = 'UPDATE cel_images SET ' ; |
$champs_a_mettre_a_jour = $this->construireRequeteMajMetaDonnees($parametres); |
$requete_mise_a_jour_image .= $champs_a_mettre_a_jour; |
$requete_mise_a_jour_image .= ' WHERE id_image = '.$this->proteger($id_image). |
' AND ce_utilisateur = '.$this->proteger($utilisateur); |
$resultat_mise_a_jour = $this->executerRequeteSimple($requete_mise_a_jour_image); |
return ($resultat_mise_a_jour !== false); |
} |
/** |
* Assemble la requete de mise à jour des champs de metadonnées |
* |
* @param array $valeurs_metadonnees un taleau contenant des valeurs indexées par les noms de champs de la bdd |
* |
* @return string une sous chaine sql utilisable dans une requete de type UPPDATE table SET valeur1=champ1 ... |
* |
*/ |
private function construireRequeteMajMetaDonnees($valeurs_metadonnees) { |
$requete_maj_champs = ''; |
$champs_a_ignorer = array('id_image'); |
foreach ($valeurs_metadonnees as $champ => $valeur) |
{ |
if (!in_array($champ,$champs_a_ignorer)) { |
if ($champ == 'date_prise_de_vue') { |
$date_tab = explode('/',$valeur) ; |
$date = $date_tab[2].'-'.$date_tab[1].'-'.$date_tab[0] ; |
$requete_maj_champs .= $champ.' = '.$this->proteger($date).' , ' ; |
} |
else { |
$requete_maj_champs .= $champ.' = '.$this->proteger($valeur).' , ' ; |
} |
} |
} |
$requete_maj_champs = rtrim($requete_maj_champs,' , ') ; |
return $requete_maj_champs; |
} |
public function supprimerImageParOrdre($id_utilisateur, $ordre_image_ou_tableau) { |
if(is_array($ordre_image_ou_tableau)) { |
$id_image_ou_tableau = array_map(array($this,'proteger'),$ordre_image_ou_tableau); |
$ids_images = implode(',',$ordre_image_ou_tableau); |
} else { |
$ids_images = $this->proteger($ordre_image_ou_tableau); |
} |
$requete_selection_ids_images = 'SELECT id_image FROM cel_images WHERE '. |
'ce_utilisateur = '.$this->proteger($id_utilisateur).' '. |
'AND ordre IN ('.$ids_images.') '; |
$tableau_ids_images = $this->executerRequete($requete_selection_ids_images); |
$chaine_ids_images = ''; |
foreach($tableau_ids_images as $id_image) { |
$chaine_ids_images .= $id_image['id_image']; |
} |
$chaine_ids_images = rtrim($chaine_ids_images,','); |
return $this->supprimerImage($id_utilisateur, $ordre_image_ou_tableau); |
} |
public function supprimerImage($id_utilisateur, $id_image_ou_tableau) { |
if(is_array($id_image_ou_tableau)) { |
$id_image_ou_tableau = array_map(array($this,'proteger'),$id_image_ou_tableau); |
$chaine_ids_images = implode(',',$id_image_ou_tableau); |
} else { |
$chaine_ids_images = $this->proteger($id_image_ou_tableau); |
} |
$requete_suppression_images = "DELETE FROM cel_images WHERE id_image in (".$chaine_ids_images.")"; |
$requete_suppression_lien_images_obs = "DELETE FROM cel_obs_images WHERE id_image in (".$chaine_ids_images.")"; |
$requete_suppression_lien_images_mots_cles = "DELETE FROM cel_images_mots_cles WHERE id_image in (".$chaine_ids_images.")"; |
$resultat_suppression_image = $this->executerRequeteSimple($requete_suppression_images); |
$resultat_suppression_lien_images_obs = $this->executerRequeteSimple($requete_suppression_lien_images_obs); |
$resultat_suppression_lien_images_mots_cles = $this->executerRequeteSimple($requete_suppression_lien_images_mots_cles); |
if ($resultat_suppression_image === false) { |
$message = 'Erreur lors de la suppression de l\'image' ; |
$this->logger($message); |
} |
if ($resultat_suppression_lien_images_obs === false) { |
$message = 'Erreur lors de la suppression des observations associées à l\'image' ; |
$this->logger($message); |
} |
if (!$resultat_suppression_lien_images_mots_cles === false) { |
$message = 'Erreur lors de la suppression des mots cles associés à l\'image' ; |
$this->logger($message); |
} |
$manipulateur_image = new ImageRecreation($this->config); |
$tableau_ids_image = explode(',',$ids_images); |
foreach($tableau_ids_image as $id_image_a_detruire) { |
$destruction_fichier_image = $manipulateur_image->detruireImageSurDisque($id_image_a_detruire); |
} |
return $destruction_fichier_image; |
} |
/** |
* Fonction utilisée pour importer les anciennes images saisies dans les widget dans un compte identifié |
* Dans ce cas là, le widget remplit la case id_utilisateur par le mail indiqué lors de la saisie |
* @param string $mail_utilisateur |
* @param string $id_utilisateur |
*/ |
public function migrerImagesMailVersId($mail_utilisateur, $infos_utilisateur) { |
// ATTENTION : cette fonction suppose que l'utilisateur n'ai pas déjà d'images dans le CEL |
// avec l'identifiant $id_utilisateur ce qui est normalement le cas |
$requete_migration_releve = 'UPDATE cel_images SET '. |
'ce_utilisateur = '.$this->proteger($infos_utilisateur['id_utilisateur']).', '. |
'prenom_utilisateur = '.$this->proteger($infos_utilisateur['prenom']).', '. |
'nom_utilisateur = '.$this->proteger($infos_utilisateur['nom']).', '. |
'courriel_utilisateur = '.$this->proteger($infos_utilisateur['courriel']).' '. |
'WHERE ce_utilisateur = '.$this->proteger($mail_utilisateur).' '; |
$migration_releve = $this->executerRequeteSimple($requete_migration_releve); |
return $migration_releve; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Writer.php |
---|
New file |
0,0 → 1,104 |
<?php |
/* |
* Module written/ported by Xavier Noguer <xnoguer@rezebra.com> |
* |
* PERL Spreadsheet::WriteExcel module. |
* |
* The author of the Spreadsheet::WriteExcel module is John McNamara |
* <jmcnamara@cpan.org> |
* |
* I _DO_ maintain this code, and John McNamara has nothing to do with the |
* porting of this code to PHP. Any questions directly related to this |
* class library should be directed to me. |
* |
* License Information: |
* |
* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets |
* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
* License as published by the Free Software Foundation; either |
* version 2.1 of the License, or (at your option) any later version. |
* |
* This library is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Lesser General Public License for more details. |
* |
* You should have received a copy of the GNU Lesser General Public |
* License along with this library; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
require_once 'PEAR.php'; |
require_once 'Spreadsheet/Excel/Writer/Workbook.php'; |
/** |
* Class for writing Excel Spreadsheets. This class should change COMPLETELY. |
* |
* @author Xavier Noguer <xnoguer@rezebra.com> |
* @category FileFormats |
* @package Spreadsheet_Excel_Writer |
*/ |
class Spreadsheet_Excel_Writer extends Spreadsheet_Excel_Writer_Workbook |
{ |
/** |
* The constructor. It just creates a Workbook |
* |
* @param string $filename The optional filename for the Workbook. |
* @return Spreadsheet_Excel_Writer_Workbook The Workbook created |
*/ |
function Spreadsheet_Excel_Writer($filename = '') |
{ |
$this->_filename = $filename; |
$this->Spreadsheet_Excel_Writer_Workbook($filename); |
} |
/** |
* Send HTTP headers for the Excel file. |
* |
* @param string $filename The filename to use for HTTP headers |
* @access public |
*/ |
function send($filename) |
{ |
header("Content-type: application/vnd.ms-excel"); |
header("Content-Disposition: attachment; filename=\"$filename\""); |
header("Expires: 0"); |
header("Cache-Control: must-revalidate, post-check=0,pre-check=0"); |
header("Pragma: public"); |
} |
/** |
* Utility function for writing formulas |
* Converts a cell's coordinates to the A1 format. |
* |
* @access public |
* @static |
* @param integer $row Row for the cell to convert (0-indexed). |
* @param integer $col Column for the cell to convert (0-indexed). |
* @return string The cell identifier in A1 format |
*/ |
function rowcolToCell($row, $col) |
{ |
if ($col > 255) { //maximum column value exceeded |
return new PEAR_Error("Maximum column value exceeded: $col"); |
} |
$int = (int)($col / 26); |
$frac = $col % 26; |
$chr1 = ''; |
if ($int > 0) { |
$chr1 = chr(ord('A') + $int - 1); |
} |
$chr2 = chr(ord('A') + $frac); |
$row++; |
return $chr1 . $chr2 . $row; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/ExcelReader.php |
---|
New file |
0,0 → 1,8 |
<?php |
//TODO: voir si cette classe sert encore à quelque chose |
Class ExcelReader { |
function initExcelReader() { |
require_once("ExcelReader/excel_reader2.php"); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/RechercheImage.php |
---|
New file |
0,0 → 1,363 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author Aurélien Peronnet <aurelien@tela-botania.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* in : utf8 |
* out : utf8 |
* |
* Librairie recherche d'images a partir de divers critères |
* |
*/ |
class RechercheImage extends Cel { |
function rechercherImagesEtObservationAssociees($id_utilisateur = null, $criteres = array(), $debut = 0, $limite = 50) |
{ |
$images_trouvees = $this->rechercherImages($id_utilisateur, $criteres, $debut, $limite); |
$retour = array(); |
foreach($images_trouvees as $image) |
{ |
$image['id_observation'] = $this->obtenirInformationsObservationsAssociees($image['ce_utilisateur'],$image['id_image']); |
$retour[] = $image ; |
} |
return $retour; |
} |
public function rechercherImages($id_utilisateur = null, $criteres = array(), $debut = 0 , $limite = 50) { |
$ordre = (isset($criteres['tri']) && $criteres['tri']) ? $criteres['tri'] : 'ci.ordre'; |
unset($criteres['tri']); |
$direction = (isset($criteres['dir']) && $criteres['dir']) ? $criteres['dir'] : 'ASC'; |
unset($criteres['dir']); |
$debut = ($debut < 0) ? 0 : $debut; |
$requete_recherche_images = 'SELECT * '; |
if ($this->doitJoindreTableObs($criteres)) { |
$requete_recherche_images .= $this->fabriquerRequeteJointureObs(); |
$requete_recherche_images .= ($id_utilisateur != null) ? 'AND ci.ce_utilisateur = '.$this->proteger($id_utilisateur) : ''; |
} else { |
$requete_recherche_images .= 'FROM cel_images ci '; |
$requete_recherche_images .= ($id_utilisateur != null) ? 'WHERE ci.ce_utilisateur = '.$this->proteger($id_utilisateur) : ''; |
} |
$sous_requete_recherche = $this->fabriquerSousRequeteRecherche($id_utilisateur, $criteres); |
$requete_recherche_images .= $sous_requete_recherche; |
$requete_recherche_images .= ' ORDER BY '.$ordre.' '.$direction.' LIMIT '.$debut.','.$limite ; |
$resultats_images = array(); |
$resultats_images = $this->executerRequete($requete_recherche_images); |
return $resultats_images; |
} |
public function compterImages($id_utilisateur = null, $criteres = array()) { |
$ordre = (isset($criteres['tri']) && $criteres['tri']) ? $criteres['tri'] : 'ci.ordre'; |
unset($criteres['tri']); |
$direction = (isset($criteres['dir']) && $criteres['dir']) ? $criteres['dir'] : 'ASC'; |
unset($criteres['dir']); |
$requete_recherche_images = 'SELECT COUNT(*) as nb_images '; |
if ($this->doitJoindreTableObs($criteres)) { |
$requete_recherche_images .= $this->fabriquerRequeteJointureObs(); |
$requete_recherche_images .= ($id_utilisateur != null) ? 'AND ci.ce_utilisateur = '.$this->proteger($id_utilisateur) : ''; |
} else { |
$requete_recherche_images .= 'FROM cel_images ci '; |
$requete_recherche_images .= ($id_utilisateur != null) ? 'WHERE ci.ce_utilisateur = '.$this->proteger($id_utilisateur) : ''; |
} |
$sous_requete_recherche = $this->fabriquerSousRequeteRecherche($id_utilisateur, $criteres); |
$requete_recherche_images .= $sous_requete_recherche; |
$nb_images = 0; |
$resultat_requete_nombre_images = $this->executerRequete($requete_recherche_images); |
if($resultat_requete_nombre_images && is_array($resultat_requete_nombre_images) && count($resultat_requete_nombre_images) > 0) { |
$nb_images = $resultat_requete_nombre_images[0]['nb_images']; |
} |
return $nb_images; |
} |
private function doitJoindreTableObs($criteres = array()) { |
$criteres_obs = array('zone_geo','ce_zone_geo','taxon','transmission','recherche'); |
return count(array_intersect(array_keys($criteres),$criteres_obs)) > 0; |
} |
private function fabriquerRequeteJointureObs() { |
$requete_jointure_observations = 'FROM cel_obs_images coi '. |
'INNER JOIN cel_obs co '. |
'ON coi.id_observation = co.id_observation '. |
'INNER JOIN cel_images ci '. |
'ON coi.id_image = ci.id_image '. |
'WHERE co.ce_utilisateur = ci.ce_utilisateur '; |
return $requete_jointure_observations; |
} |
public function obtenirInformationsObservationsAssociees($id_utilisateur, $id_image) { |
$requete_table_liaison = 'SELECT id_observation FROM cel_obs_images WHERE id_image = '.$id_image; |
$resultats_liaisons_images = $this->executerRequete($requete_table_liaison); |
$ids_obs = ''; |
foreach($resultats_liaisons_images as $liaison) { |
$ids_obs .= $liaison['id_observation'].","; |
} |
$ids_obs = rtrim($ids_obs,','); |
$infos_obs = ''; |
if(trim($ids_obs) != '') { |
$requete_obs_liees = 'SELECT * FROM cel_obs WHERE id_observation IN ('.$ids_obs.') AND ce_utilisateur ="'.$id_utilisateur.'"'; |
$resultat_obs_liees = $this->executerRequete($requete_obs_liees); |
foreach($resultat_obs_liees as $obs_liee) |
{ |
$infos_obs .= $obs_liee['ordre'].'#'.$obs_liee['nom_sel'].'#'.$obs_liee['transmission'].';;' ; |
} |
} |
return $infos_obs; |
} |
private function fabriquerSousRequeteRecherche($id_utilisateur, $criteres) { |
$sous_requete = ' AND '; |
foreach($criteres as $nom => $valeur) |
{ |
if($valeur == null || trim($nom) == "" || trim($valeur) == "") { |
continue; |
} |
switch($nom) { |
case "mots_cles"; |
$sous_requete .= $this->creerSousRequeteMotsCles($valeur); |
break; |
case "id_mots_cles"; |
$liste_mc = '"'.str_replace(';','","',$valeur).'"'; |
$sous_requete .= '' ; |
$sous_requete .= 'id_image IN (SELECT id_image FROM cel_images_mots_cles WHERE id_mot_cle_image IN ('.$liste_mc.'))'; |
$sous_requete .= ' AND ' ; |
break; |
case "commentaire": |
$mots_comment_liste = explode(" " , $valeur) ; |
foreach($mots_comment_liste as $mot_comment) |
{ |
$mot_comment = trim($mot_comment) ; |
$sous_requete .= 'ci.'.$nom.' LIKE '.$this->proteger('%'.$mot_comment.'%') ; |
$sous_requete .= ' AND ' ; |
} |
break; |
case "annee": |
case "mois": |
case "jour": |
$sous_requete .= $this->fabriquerSousRequeteRechercheDate($nom, $valeur) ; |
$sous_requete .= ' AND ' ; |
break; |
case "tampon": |
$ids_tampon = rtrim($valeur, ',') ; |
$sous_requete .= 'ci.id_images IN ( '.$this->proteger($ids_tampon).')' ; |
break; |
case "recherche": |
$sous_requete .= $this->fabriquerSousRequeteRechercheGenerale($id_utilisateur, $valeur); |
$sous_requete .= ' AND '; |
break; |
case "transmission": |
$sous_requete .= 'co.transmission = '.$this->proteger($valeur) ; |
$sous_requete .= ' AND '; |
break; |
case "taxon": |
$valeur = str_replace('indetermine','null',$valeur); |
$sous_requete .= ' ('; |
$sous_requete .= 'co.nom_ret LIKE '.$this->proteger($valeur.'%') ; |
$sous_requete .= ' OR ' ; |
$sous_requete .= 'co.nom_sel LIKE '.$this->proteger($valeur.'%') ; |
$sous_requete .= ') AND ' ; |
break; |
case "auteur": |
$sous_requete .= '(ci.ce_utilisateur LIKE '.$this->proteger($valeur.'%').' OR '. |
'ci.courriel_utilisateur LIKE '.$this->proteger($valeur.'%').' OR '. |
'ci.nom_utilisateur LIKE '.$this->proteger($valeur.'%').' OR '. |
'ci.prenom_utilisateur LIKE '.$this->proteger($valeur.'%'). |
') AND '; |
break; |
case "ce_zone_geo": |
if($valeur == "NULL") { |
$sous_requete .= "(co.ce_zone_geo IS NULL OR co.ce_zone_geo = '')"; |
} else { |
$sous_requete .= '(co.ce_zone_geo LIKE '.(is_numeric($valeur) ? $this->proteger('INSEE-C:'.$valeur.'%') : $this->proteger($valeur)).') '; |
} |
break; |
case "zone_geo": |
if($valeur == "NULL") { |
$sous_requete .= "(co.zone_geo IS NULL OR co.zone_geo = '')"; |
} else { |
$sous_requete .= '(co.zone_geo = '.$this->proteger($valeur).') '; |
} |
break; |
case "famille": |
$sous_requete .= 'co.famille = '.$this->proteger($valeur) ; |
$sous_requete .= ' AND ' ; |
break; |
default: |
$sous_requete .= 'ci.'.$nom.' = '.$this->proteger($valeur) ; |
$sous_requete .= ' AND ' ; |
break; |
} |
} |
$sous_requete = rtrim($sous_requete,' AND '); |
return $sous_requete; |
} |
private function fabriquerSousRequeteRechercheGenerale($id_utilisateur, $chaine_recherche) { |
if(trim($chaine_recherche) == '') { |
return ''; |
} |
$chaine_recherche = strtolower($chaine_recherche); |
$chaine_recherche = str_replace(' ','_',$chaine_recherche); |
$requete = ' ('. |
'ci.nom_original LIKE '.$this->proteger($chaine_recherche.'%').' OR '. |
'co.nom_ret LIKE '.$this->proteger($chaine_recherche.'%').' OR '. |
'co.nom_sel LIKE '.$this->proteger($chaine_recherche.'%').' OR '. |
'co.zone_geo LIKE '.$this->proteger($chaine_recherche.'%').' OR '. |
'co.ce_zone_geo LIKE '.$this->proteger('%'.$chaine_recherche.'%').' OR '. |
//TODO: recherche multicriteres sur mots clés texte ne fonctionne pas à cause de la jointure |
//'ci.mots_cles_texte LIKE '.$this->proteger('%'.$chaine_recherche.'%').' OR '. |
'ci.ce_utilisateur LIKE '.$this->proteger($chaine_recherche.'%').' OR '. |
'ci.courriel_utilisateur LIKE '.$this->proteger($chaine_recherche.'%').' OR '. |
'ci.nom_utilisateur LIKE '.$this->proteger($chaine_recherche.'%').' OR '. |
'ci.prenom_utilisateur LIKE '.$this->proteger($chaine_recherche.'%').' '. |
') '; |
return $requete; |
} |
private function fabriquerSousRequeteRechercheDate($intervalle, $valeur) { |
$correspondance_champ = array('annee' => 'YEAR','mois' => 'MONTH','jour' => 'DAY'); |
$requete_recherche_date = ''; |
if(is_numeric($valeur) && $valeur != "00") { |
$requete_recherche_date = '('.$correspondance_champ[$intervalle].'(ci.date_prise_de_vue) = '.$this->proteger($valeur).') '; |
} else { |
$requete_recherche_date = '(ci.date_prise_de_vue IS NULL OR ci.date_prise_de_vue = "0000-00-00")'; |
} |
return $requete_recherche_date; |
} |
private function creerSousRequeteMotsCles($mot_cle) { |
$requete = ''; |
if (preg_match('/.*OU.*/', $mot_cle)) { |
$mots_cles_tab = explode('OU',$mot_cle); |
foreach($mots_cles_tab as $mot_cle_item) { |
$requete .= '(ci.mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') OR '; |
} |
$requete = '('.rtrim($requete,'OR ').')'; |
} else if (preg_match('/.*ET.*/', $mot_cle)) { |
$mots_cles_tab = explode('ET',$mot_cle); |
foreach($mots_cles_tab as $mot_cle_item) { |
$requete .= '(ci.mots_cles_texte LIKE '.$this->proteger('%'.$mot_cle_item.'%').') AND '; |
} |
$requete = '('.rtrim($requete, 'AND ').') '; |
} else { |
$requete = "(ci.mots_cles_texte LIKE ".$this->proteger('%'.$mot_cle.'%').') '; |
} |
$requete .= ' AND '; |
return $requete; |
} |
public function formaterPourEnvoiCel($tableau_images) { |
foreach($tableau_images as &$image) { |
$ids_mots_cles = $this->getIdsMotsClesImage($image['id_image']); |
$mots_cles_chaine = ''; |
foreach($ids_mots_cles as $id_mot_cle) { |
$mots_cles_chaine .= $id_mot_cle['id_mot_cle_image'].','; |
} |
$mots_cles_chaine = rtrim($mots_cles_chaine,','); |
$image['mots_cles'] = $mots_cles_chaine; |
} |
return $tableau_images; |
} |
public function obtenirCourrielUtilisateurPourIdImage($id_image) { |
$requete = 'SELECT courriel_utilisateur FROM cel_images WHERE '. |
'id_image = '.$this->proteger($id_image); |
$utilisateur_courriel = $this->executerRequete($requete); |
$retour = false; |
if(!empty($utilisateur_courriel) && isset($utilisateur_courriel[0]['courriel_utilisateur'])) { |
$retour = $utilisateur_courriel[0]['courriel_utilisateur']; |
} |
return $retour; |
} |
private function getIdsMotsClesImage($id_image) { |
$requete_selection_mots_cles = 'SELECT DISTINCT id_mot_cle_image '. |
'FROM cel_images_mots_cles '. |
'WHERE id_image = '.$id_image; |
return $this->executerRequete($requete_selection_mots_cles); |
} |
// TODO: fonction temporaire |
private function formaterDateSqlVersDateAvecSlash($date_sql) { |
$date_formatee = ''; |
$date = explode("-",$date_sql) ; |
if(count($date) > 2) |
{ |
$image['date_prise_de_vue'] = $date[2].'/'.$date[1].'/'.$date[0] ; |
} |
return $date_formatee; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/NameParser.php |
---|
New file |
0,0 → 1,358 |
<?php |
/** |
* Taxamatch-Webservice PHP v1.0.0 |
* @author Michael Giddens |
* @link http://www.silverbiology.com |
*/ |
/* Adapation par David Delon Decembre 2010 : gestion sous espece |
*/ |
/** |
* Class NameParser |
* Used to convert a string to a standarized format. |
*/ |
class NameParser { |
/** |
* Whether to debug or nor |
* @var bool|integer |
*/ |
public $debug_flag; |
/** |
* Constructor |
*/ |
public function __construct( ) { |
} |
/** |
* Sets value to the method property |
* @param mixed $name class property name |
* @param mixed $value class property value |
*/ |
public function set($name,$value) { |
$this->$name = $value; |
} |
/** |
* Reduce Spaces |
* This will reduce the string to only allow once space between characters |
* @param string $str : string to reduce space |
* @return string : string with only once space between characters |
*/ |
private function reduce_spaces( $str ) { |
$str = preg_replace("/ {2,}/", ' ', $str ); |
$str = trim( $str ); |
return( $str ); |
} |
/** |
* Function: parse_auth |
* Purpose: Produce a parsed version of authority of a taxon name |
* @author Tony Rees (Tony.Rees@csiro.au) |
* Date created: March 2008 |
* Inputs: authority string as str |
* Remarks: |
* (1) Performs authority expension of known abbreviated authornames using |
* table "auth_abbrev_test1" (must be available and populated with relevant content) |
* (2) Recognises "and", "et", "&" as equivalents (special case for "et al.") - all parsed to ampersand |
* (3) Recognises (e.g.) "Smith 1980" and "Smith, 1980" as equivalents - comma is removed in these cases |
* (4) Recognises (e.g.) "F. J. R. Taylor, 1980" and "F.J.R. Taylor, 1980" as equivalents - |
* extra space after full stops is ignored in these cases |
* (5) Returns uppercase string, diacritical marks intact |
* |
* @param string $str : authority string |
* @param integer $upcase : convert to uppercase if $upcase = 1 |
* @return string : parsed author string |
*/ |
public function parse_auth( $str, $upcase=1 ) { |
$this->debug['parse_auth'][] = "1"; |
$temp = $str = trim($str); |
if ( ($str == NULL) || ($str == '') ) { |
$this->debug['parse_auth'][] = "1a"; |
return ''; |
} |
if ( ( $temp == null ) || ( $temp == '') ) { |
$this->debug['parse_auth'][] = "2a"; |
return(''); |
} else { |
$this->debug['parse_auth'][] = "2b"; |
// add space after full stops, except at end (NB, will also add spece before some close brackets) |
$temp = rtrim( str_replace('.', '. ', $temp) ); |
$this->debug['parse_auth'][] = "4 (temp:$temp)"; |
//normalise "et", "and" to ampersand (et al. is a special case) |
// if ( $temp like '% et al%' ) { |
if ( preg_match('/ et al/', $temp) ) { |
$temp = str_replace(' et al','zzzzz', $temp); |
$this->debug['parse_auth'][] = "4a (temp:$temp)"; |
} |
$temp = str_replace(' et ',' & ', $temp ); |
$temp = str_replace(' and ',' & ', $temp ); |
$temp = str_replace('zzzzz',' et al', $temp); |
$this->debug['parse_auth'][] = "5 (temp:$temp)"; |
//remove commas before dates (only) |
// like '%, 17%' |
if ( preg_match('/, 17/', $temp) ) { |
$temp = str_replace(', 17',' 17', $temp); |
$this->debug['parse_auth'][] = "5a (temp:$temp)"; |
} |
// like '%, 18%' |
if ( preg_match('/, 18/', $temp) ) { |
$temp = str_replace(', 18',' 18', $temp); |
$this->debug['parse_auth'][] = "5b (temp:$temp)"; |
} |
// like '%, 19%' |
if ( preg_match('/, 19/', $temp) ) { |
$temp = str_replace(', 19',' 19', $temp); |
$this->debug['parse_auth'][] = "5c (temp:$temp)"; |
} |
// like '%, 20%' |
if ( preg_match('/, 20/', $temp) ) { |
$temp = str_replace(', 20',' 20', $temp); |
$this->debug['parse_auth'][] = "5d (temp:$temp)"; |
} |
// reduce multiple internal spaces to single space |
$temp = $this->reduce_spaces( $temp ); |
// like '% -%' |
$temp = str_replace(' -', '-', $temp); |
$this->debug['parse_auth'][] = "6 (temp:$temp)"; |
foreach( explode(' ', $temp) as $this_word ) { |
//$this->debug['parse_auth'][] = "7 (this_word:$this_word)"; |
$elapsed_chars = ''; |
// like '(%' |
if ( preg_match('/^\(/', $this_word) ) { |
$elapsed_chars .= '('; |
$this_word = substr( $this_word, 1 ); |
//$this->debug['parse_auth'][] = "7a (this_word:$this_word) (elapsed_chars:$elapsed_chars)"; |
} |
// Add back the word to the final translation |
$elapsed_chars .= $this_word . ' '; |
//$this->debug['parse_auth'][] = "7c (this_word:$this_word) (elapsed_chars:$elapsed_chars)"; |
} |
$elapsed_chars = $this->reduce_spaces( str_replace(' )', ')', $elapsed_chars) ); |
return trim( $elapsed_chars ) ; |
} |
} |
/** |
* Function: parse |
* Purpose: Produces parsed version of an input string (scientific name components) |
* @author Tony Rees (Tony.Rees@csiro.au) |
* Date created: June 2007-November 2008 |
* Inputs: input string as str (this version presumes genus, genus+species, or |
* genus+species+authority) |
* Outputs: parsed version of input string, for match purposes |
* Remarks: |
* (1) Removes known text elements e.g. |
* 'aff.', 'cf.', 'subsp.', subgenera if enclosed in brackets, etc. as desired |
* (2) Removes accented and non A-Z characters other than full stops |
* (in scientific name portions) |
* (3) Returns uppercase scientific name (genus + species only) |
* plus unaltered (presumed) authority |
* examples; |
* Anabaena cf. flos-aquae Ralfs ex Born. et Flah. => ANABAENA FLOSAQUAE Ralfs |
* ex Born. et Flah. |
* Abisara lemÈe-pauli => ABISARA LEMEEPAULI |
* Fuc/us Vesiculos2us => FUCUS VESICULOSUS |
* Buffo ignicolor LacÈpËde, 1788 => BUFFO IGNICOLOR LacÈpËde, 1788 |
* Barbatia (Mesocibota) bistrigata (Dunker, 1866) => BARBATIA BISTRIGATA (Dunker, 1866) |
* (4) Thus version does not handle genus+author, or genus+species+infraspecies |
* (second" good" term is presumed to be species epithet, anything after is |
* considered to be start of the authority), however could be adapted further as required |
* and actually it was done in this version for Tela Botanica |
* (5) There is a separate function "parse_auth" for normalizing authorities when required |
* (e.g. for authority comparisons) |
* |
* @param string $str : input string ( genus, genus+species, or genus+species+authority ) |
* @return string : parsed string |
*/ |
public function parse( $str = NULL ) { |
unset($this->debug['parse']); |
$temp = ''; |
$first_str_part = NULL; |
$second_str_part = NULL; |
$temp_genus = ''; |
$temp_species = ''; |
$temp_genus_species = ''; |
$temp_authority = ''; |
$temp_infra = ''; |
//$this->debug['parse'][] = "1"; |
if ( ($str == NULL) || ( trim($str) == '') ) { |
//$this->debug[] = "N1a<br>"; |
return ''; |
} else { |
// trim any leading, trailing spaces or line feeds |
$temp = trim( $str ); |
//$this->debug['parse'][] = "1b"; |
} |
if ( $temp == NULL || $temp == '') { |
//$this->debug['parse'][] = "2a"; |
return ''; |
} else { |
//$this->debug['parse'][] = "2b"; |
// replace any HTML ampersands |
$set = array('%', '&', 'amp;%', 'AMP;%'); |
$temp = str_replace( $set, '&', $temp ); |
//$this->debug['parse'][] = "2b1 (temp:$temp)"; |
// remove any content in angle brackets (e.g. html tags - <i>, </i>, etc.) |
$html_pattern = "(\<(/?[^\>]+)\>)"; |
//? This should not just handle html tags but all <*> |
$temp = preg_replace( $html_pattern, '', $temp); |
//$this->debug['parse'][] = "2b2 (temp:$temp)"; |
// if second term (only) is in round brackets, presume it is a subgenus or a comment and remove it |
// examples: Barbatia (Mesocibota) bistrigata (Dunker, 1866) => Barbatia bistrigata (Dunker, 1866) |
// Barbatia (?) bistrigata (Dunker, 1866) => Barbatia bistrigata (Dunker, 1866) |
// (obviously this will not suit genus + author alone, where first part of authorname is in brackets, |
// however this is very rare?? and in any case we are not supporting genus+authority in this version) |
//if ( $temp like '% (%)%' |
$temp = preg_replace( "/ \(\w*\W*\)/", '', $temp, 1 ); |
//? Not sure if this will catch if |
//$this->debug['parse'][] = "2b3 (temp:$temp)"; |
// if second term (only) is in square brackets, presume it is a comment and remove it |
// example: Aphis [?] ficus Theobald, [1918] => Aphis ficus Theobald, [1918] |
//if ( $temp like '% [%]%' |
$temp = preg_replace( "/ \[\w*\W*\]/", '', $temp, 1 ); |
//? Not sure if this will catch if |
//$this->debug['parse'][] = "2b4 (temp:$temp)"; |
// drop indicators of questionable id's - presume all are lowercase for now (could extend as needed) |
$temp = preg_replace( "/ cf /", " ", $temp ); |
$temp = preg_replace( "/ cf\. /", " ", $temp ); |
$temp = preg_replace( "/ near /", " ", $temp ); |
$temp = preg_replace( "/ aff\. /", " ", $temp ); |
$temp = preg_replace( "/ sp\. /", " ", $temp ); |
$temp = preg_replace( "/ spp\. /", " ", $temp ); |
$temp = preg_replace( "/ spp /", " ", $temp ); |
//$this->debug['parse'][] = "2b5 (temp:$temp)"; |
// eliminate or close up any stray spaces introduced by the above |
$temp = $this->reduce_spaces( $temp ); |
//$this->debug['parse'][] = "2b6 (temp:$temp)"; |
// now presume first element is genus, second (if present) is species, remainder |
// (if present) is authority |
// look for genus name |
$ar = explode( " ", $temp, 2); |
if ( count( $ar ) ) { |
$temp_genus = $ar[0]; |
$temp = @$ar[1]; |
} else { |
$temp_genus = $temp; |
$temp = ''; |
} |
//$this->debug['parse'][] = "2b7 (temp_genus:$temp_genus) (temp:$temp)"; |
// look for species epithet and authority |
$ar = explode( " ", $temp, 2); |
if ( count( $ar ) ) { |
$temp_species = $ar[0]; |
$temp_authority = @$ar[1]; |
} else { |
$temp_species = $temp; |
$temp_authority = ''; |
} |
// look for subspecies |
$infras =array('subsp.','var.'); |
$temp_authority = preg_replace( "/ssp./", "subsp.", $temp_authority); |
$temp_authority = preg_replace( "/ssp /", "subsp.", $temp_authority); |
$temp_authority = preg_replace( "/subsp /", "subsp.", $temp_authority); |
$temp_authority = preg_replace( "/var /", "var.", $temp_authority); |
$temp_infra_authority = ''; |
$temp_infra_type = ''; |
foreach ($infras as $infra) { |
$pos = strpos($temp_authority, $infra); |
if ($pos === false) { |
continue; |
} else { |
$temp_infra=substr($temp_authority,$pos+strlen($infra)); |
$temp_authority=substr($temp_authority,0,$pos); |
$temp_infra=trim($temp_infra); |
$temp_infra_type=$infra; |
// look for infra epithet and authority |
$ar = explode(" ", $temp_infra, 2); |
if ( count( $ar ) ) { |
$temp_infra = $ar[0]; |
$temp_infra_authority = @$ar[1]; |
} |
break; // on s'arrete au premier trouve |
} |
} |
//$this->debug['parse'][] = "2b8 (temp_genus:$temp_genus) (temp_species:$temp_species) (temp_authority:$temp_authority) (temp_infra:$temp_infra) (temp_infra_authority:$temp_infra_authority) (temp:$temp)"; |
// replace selected ligatures here (Genus names can contain Æ, OE ligature) |
$temp_genus = str_replace( 'Æ', 'AE', $temp_genus); |
$temp_species = str_replace( 'Æ', 'AE', $temp_species); |
$temp_infra = str_replace( 'Æ', 'AE', $temp_infra ); |
//$this->debug['parse'][] = "2b9 (temp_genus:$temp_genus) (temp_species:$temp_species) (temp_authority:$temp_authority) (temp_infra:$temp_infra) (temp_infra_authority:$temp_infra_authority) (temp:$temp)"; |
$temp_genus= trim($temp_genus); |
$temp_species= trim($temp_species); |
$temp_infra= trim($temp_infra ); |
// reduce any new multiple internal spaces to single space, if present |
$temp_genus= $this->reduce_spaces( $temp_genus ); |
$temp_species= $this->reduce_spaces( $temp_species ); |
$temp_infra= $this->reduce_spaces( $temp_infra ); |
//$this->debug['parse'][] = "2b10 (temp_genus:$temp_genus) (temp_species:$temp_species) (temp_authority:$temp_authority) (temp_infra:$temp_infra) (temp_infra_authority:$temp_infra_authority) (temp:$temp)"; |
if (isset($temp_authority) && ($temp_authority!='') ) { |
$temp_authority=$this->parse_auth($temp_authority); |
} |
if (isset($temp_infra_authority) && ($temp_infra_authority!='') ) { |
$temp_infra_authority=$this->parse_auth($temp_infra_authority); |
} |
//$this->debug['parse'][] = "2b11 (temp_genus:$temp_genus) (temp_species:$temp_species) (temp_authority:$temp_authority) (temp_infra:$temp_infra) (temp_infra_authority:$temp_infra_authority) (temp:$temp)"; |
return array("genus"=>$temp_genus, "species"=>$temp_species, "authority"=>$temp_authority, "infra"=>$temp_infra, "infra_authority"=>$temp_infra_authority, "infra_type"=>$temp_infra_type); |
} |
} // End NameParser |
} // End Class |
?> |
/branches/v1.6-croc/jrest/lib/RechercheInfosTaxonBeta.php |
---|
New file |
0,0 → 1,264 |
<?php |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david@tela-botania.org> |
* @author Aurélien Peronnet <aurelien@tela-botania.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* |
* La classe appelle les web service d'eflore pour éviter que le code client |
* ne soit dépendant de la version d'eflore |
*/ |
class RechercheInfosTaxonBeta extends Cel { |
private $url_service_nom = null; |
private $url_service_taxon = null; |
private $url_service_chorologie = null; |
private $masque_recherche = null; |
private $code_referentiel = 'bdtfx'; |
public function RechercheInfosTaxonBeta($config, $code_referentiel = 'bdtfx') { |
parent::__construct($config); |
$this->code_referentiel = $code_referentiel; |
$this->formaterUrlsServices($config); |
} |
private function formaterUrlsServices($config) { |
$this->url_service_nom = str_replace('{referentiel}', $this->code_referentiel ,$config['eflore']['url_service_nom']); |
$this->url_service_taxon = str_replace('{referentiel}', $this->code_referentiel ,$config['eflore']['url_service_taxon']); |
$this->url_service_chorologie_obs = $config['eflore']['url_service_chorologie_obs']; |
} |
public function rechercherGenreEspeceSurPrefixe($genre = null, $espece = null) { |
$liste_genre_espece = array(); |
$this->masque_recherche = trim(trim($genre).' '.trim($espece,' *')); |
$masque = urlencode($this->masque_recherche); |
$requete = @file_get_contents($this->url_service_nom.'?masque='.$masque.'&recherche=etendue&retour.format=min&navigation.limite=50&ns.structure=au'); |
if($requete != '') { |
$requete = json_decode($requete); |
if(is_object($requete) && isset($requete->resultat)) { |
foreach ($requete->resultat as $id => $res) { |
$retenu = ($res->retenu == "true") ? '3' : '4'; |
$liste_genre_espece[] = array($res->nom_sci_complet, $id, $retenu); |
} |
} |
usort($liste_genre_espece, array($this, 'comparerParRetenuPuisNom')); |
} |
return $liste_genre_espece; |
} |
function comparerParRetenuPuisNom($a, $b) { |
if($a[2] == 3 && $b[2] != 3) { |
return -1; |
} elseif($a[2] != 3 && $b[2] == 3) { |
return 1; |
} else { |
return levenshtein($this->masque_recherche, $a[0]) >= levenshtein($this->masque_recherche, $b[0]); |
} |
} |
public function effectuerRequeteInfosComplementairesEtFormaterNom($numNom) { |
$resultat_infos_complementaires = (array)$this->effectuerRequeteInfosComplementairesSurNumNom($numNom); |
$retour_infos_complementaires = array(); |
if (isset($resultat_infos_complementaires['nom_retenu_complet']) && $resultat_infos_complementaires['nom_retenu_complet'] != '') { |
$retour_infos_complementaires=array(($this->supprimerBiblio($resultat_infos_complementaires['nom_retenu_complet']))); |
} |
return $retour_infos_complementaires; |
} |
public function rechercherInformationsComplementairesSurNom($nom_saisi) { |
$nom_saisi = trim($nom_saisi); |
// Essai de recherche sur le nom saisi tel quel |
$liste_genre_espece = $this->effectuerRequeteUrlRecherche($nom_saisi, true); |
if(empty($liste_genre_espece)) { |
// Essai de recherche stricte en tentant de supprimer le nom d'auteur |
$nom_saisi_sans_auteur = $this->supprimerAuteur($nom_saisi); |
$liste_genre_espece = $this->effectuerRequeteUrlRecherche($nom_saisi_sans_auteur, true); |
if(empty($liste_genre_espece)) { |
// Dernière tentative : essai de recherche étendue |
$liste_genre_espece = $this->effectuerRequeteUrlRecherche($nom_saisi, false); |
} |
} |
return $liste_genre_espece; |
} |
private function effectuerRequeteUrlRecherche($nom_saisi, $stricte = true) { |
$url_recherche = $this->getUrlRechercheInfosComplementaires($nom_saisi, $stricte); |
$resultat = @file_get_contents($url_recherche); |
$liste_genre_espece = array(); |
if($resultat != '') { |
$liste_genre_espece = $this->parserResultatRechercheTaxon($resultat); |
} |
return $liste_genre_espece; |
} |
private function getUrlRechercheInfosComplementaires($nom_saisi, $stricte = true) { |
$type_recherche = $stricte ? 'stricte' : 'etendue'; |
return $url_recherche_etendue = $this->url_service_nom.'?masque='.urlencode($nom_saisi).'&recherche='.$type_recherche.'&ns.format=txt&retour.champs=nom_sci,auteur,nom_retenu.id&navigation.limite=1'; |
} |
private function supprimerAuteur($nom_saisi) { |
// Attention le parseur de nom n'est pas fiable à 100% |
// mais ça marche dans la plupart des cas |
// à part les formules d'hybridité saisies avec un auteur |
// TODO: gérer les hybrides |
$nameparser = new NameParser(); |
if($this->estUnHybride($nom_saisi) || $this->estUneFormuleHybridite($nom_saisi)) { |
$nom_decoupe = explode(' ', $nom_saisi); |
$derniere_position_hybride = end(array_keys($nom_decoupe, 'x')); |
$nom_saisi_sans_auteur = implode(' ',array_slice($nom_decoupe, 0, $derniere_position_hybride + 2)); |
} else { |
$auteur = $nameparser->parse_auth($nom_saisi); |
$nom_saisi_sans_auteur = str_replace($auteur, '', $nom_saisi); |
} |
$nom_saisi_sans_auteur = trim($nom_saisi_sans_auteur); |
return $nom_saisi_sans_auteur; |
} |
private function estUneFormuleHybridite($nom_saisi) { |
return strpos($nom_saisi,' x ') !== false; |
} |
private function estUnHybride($nom_saisi) { |
return strpos($nom_saisi,'x ') === 0; |
} |
private function parserResultatRechercheTaxon($resultat) { |
$liste_genre_espece = array(); |
$resultat = json_decode($resultat); |
if(is_object($resultat) && isset($resultat->resultat)) { |
foreach ($resultat->resultat as $id => $res) { |
$nom_complet = $res->{'nom_sci'}.' '.$res->auteur; |
$liste_genre_espece[] = array($id,$nom_complet); |
} |
} |
return $liste_genre_espece; |
} |
public function rechercherInformationsComplementairesSurNumNom($num_nom) { |
$infos_formatees = array(); |
$infos = $this->effectuerRequeteInfosComplementairesSurNumNom($num_nom); |
if(is_object($infos)) { |
$infos_formatees = $this->formaterInfosComplementairesSurNumNom($infos); |
} |
return $infos_formatees; |
} |
public function effectuerRequeteInfosComplementairesSurNumNom($num_nom) { |
$infos = array(); |
$url = $this->url_service_nom.'/'.$num_nom.'?retour.champs=nom_sci,auteur,id,nom_retenu_complet,nom_retenu.id,num_taxonomique,famille'; |
$resultat = @file_get_contents($url); |
if($resultat != '') { |
$infos = json_decode($resultat); |
} |
return $infos; |
} |
private function formaterInfosComplementairesSurNumNom($infos) { |
$infos = (array)$infos; |
return $infos_formatees = array( |
'Nom_Retenu' => $this->supprimerBiblio($infos['nom_retenu_complet']), |
'Num_Nom_Retenu' => $infos['nom_retenu.id'], |
'Num_Taxon' => $infos['num_taxonomique'], |
'Famille' => $infos['famille'] |
); |
return $infos_formatees; |
} |
private function supprimerBiblio($nom) { |
return preg_replace('/ \[.*\]/','',$nom); |
} |
public function rechercherNumTaxSurNumNom($num_nom) { |
$nt = null; |
$url = $this->url_service_nom."/".$num_nom.'?retour.champs=num_taxonomique'; |
$resultat = @file_get_contents($url); |
if($resultat != '') { |
$infos = json_decode($resultat); |
$nt = $infos->num_taxonomique; |
} |
return $nt; |
} |
public function taxonEstPresentDansDepartement($num_taxon,$code_departement) { |
$presence_taxon = false; |
$url = $this->url_service_chorologie_obs.'?masque.departement='.$code_departement.'&masque.determination.nt='.$num_taxon.'&navigation.limite=1'; |
$resultat = @file_get_contents($url); |
if($resultat != '') { |
$resultat = json_decode($resultat); |
if(is_object($resultat) && isset($resultat->resultat) && count($resultat->resultat) > 0) { |
$presence_taxon = true; |
} |
} |
return $presence_taxon; |
} |
public function effectuerRequeteInfosComplementairesSurNumTax($numTax) { |
$infos = array(); |
//TODO: retourner moins de champs grâce au paramètre retour.champs |
$url = $this->url_service_taxon."/nt:".$numTax; |
$resultat = @file_get_contents($url); |
if($resultat != '') { |
$infos = json_decode($resultat); |
} |
return $infos; |
} |
function rechercherInfosSurTexteCodeOuNumTax($identifiant_espece) { |
// texte libre, nom scientifique, |
// ou code nomenclatural (format BDNFFnn999999) |
// ou code taxonomique (format BDNFFnt999999) |
$identifiant_espece=trim($identifiant_espece); |
$identifiant_espece=utf8_encode($identifiant_espece); |
$retour = array(); |
//TODO: voir ce qu'on fait pour l'import de différent référentiels |
preg_match('/BDNFFnn([0-9][0-9]*)/',$identifiant_espece, $elements); |
if (isset($elements[1])) { |
// Numero nomenclatural |
$infos_taxon = $this->rechercherInformationsComplementairesSurNumNom($elements[1]); |
$retour = array("nom_sel" => $infos_taxon['Nom_Retenu'], "en_id_nom" => $elements[1]); |
} else { |
// Numero taxonomique ou nom scientifique |
preg_match('/BDNFFnt([0-9][0-9]*)/', $identifiant_espece, $elements); |
if (isset($elements[1])) { |
// Numero taxonomique |
$infos_taxon = (array)$this->effectuerRequeteInfosComplementairesSurNumTax($elements[1]); |
if(isset($infos_taxon['nom_retenu.libelle']) && isset($infos_taxon['id'])) { |
$nom = $infos_taxon['nom_retenu.libelle']; |
$nom .= (isset($infos_taxon['auteur'])) ? ' '.$infos_taxon['auteur'] : ''; |
$retour = array("nom_sel" => $nom, |
"en_id_nom" => $infos_taxon['id']); |
} |
} else { |
// Nom scientifique |
$id_nom = $this->rechercherInformationsComplementairesSurNom($identifiant_espece); |
// Recherche du nom associe |
$retour = array("nom_sel" => $identifiant_espece); |
if(is_array($id_nom) && count($id_nom) > 0 && isset($id_nom[0][0]) && isset($id_nom[0][1])) { |
$nn = $id_nom[0][0]; |
$retour = array("nom_sel" => $id_nom[0][1], "en_id_nom" => $id_nom[0][0]); |
} |
} |
} |
return $retour; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/ExcelReader/excel_reader2.php |
---|
New file |
0,0 → 1,1740 |
<?php |
/** |
* A class for reading Microsoft Excel (97/2003) Spreadsheets. |
* |
* Version 2.21 |
* |
* Enhanced and maintained by Matt Kruse < http://mattkruse.com > |
* Maintained at http://code.google.com/p/php-excel-reader/ |
* |
* Format parsing and MUCH more contributed by: |
* Matt Roxburgh < http://www.roxburgh.me.uk > |
* |
* DOCUMENTATION |
* ============= |
* http://code.google.com/p/php-excel-reader/wiki/Documentation |
* |
* CHANGE LOG |
* ========== |
* http://code.google.com/p/php-excel-reader/wiki/ChangeHistory |
* |
* DISCUSSION/SUPPORT |
* ================== |
* http://groups.google.com/group/php-excel-reader-discuss/topics |
* |
* -------------------------------------------------------------------------- |
* |
* Originally developed by Vadim Tkachenko under the name PHPExcelReader. |
* (http://sourceforge.net/projects/phpexcelreader) |
* Based on the Java version by Andy Khan (http://www.andykhan.com). Now |
* maintained by David Sanders. Reads only Biff 7 and Biff 8 formats. |
* |
* PHP versions 4 and 5 |
* |
* LICENSE: This source file is subject to version 3.0 of the PHP license |
* that is available through the world-wide-web at the following URI: |
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
* the PHP License and are unable to obtain it through the web, please |
* send a note to license@php.net so we can mail you a copy immediately. |
* |
* @category Spreadsheet |
* @package Spreadsheet_Excel_Reader |
* @author Vadim Tkachenko <vt@apachephp.com> |
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
* @version CVS: $Id: reader.php 19 2007-03-13 12:42:41Z shangxiao $ |
* @link http://pear.php.net/package/Spreadsheet_Excel_Reader |
* @see OLE, Spreadsheet_Excel_Writer |
* -------------------------------------------------------------------------- |
*/ |
define('NUM_BIG_BLOCK_DEPOT_BLOCKS_POS', 0x2c); |
define('SMALL_BLOCK_DEPOT_BLOCK_POS', 0x3c); |
define('ROOT_START_BLOCK_POS', 0x30); |
define('BIG_BLOCK_SIZE', 0x200); |
define('SMALL_BLOCK_SIZE', 0x40); |
define('EXTENSION_BLOCK_POS', 0x44); |
define('NUM_EXTENSION_BLOCK_POS', 0x48); |
define('PROPERTY_STORAGE_BLOCK_SIZE', 0x80); |
define('BIG_BLOCK_DEPOT_BLOCKS_POS', 0x4c); |
define('SMALL_BLOCK_THRESHOLD', 0x1000); |
// property storage offsets |
define('SIZE_OF_NAME_POS', 0x40); |
define('TYPE_POS', 0x42); |
define('START_BLOCK_POS', 0x74); |
define('SIZE_POS', 0x78); |
define('IDENTIFIER_OLE', pack("CCCCCCCC",0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1)); |
function GetInt4d($data, $pos) { |
$value = ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24); |
if ($value>=4294967294) { |
$value=-2; |
} |
return $value; |
} |
// http://uk.php.net/manual/en/function.getdate.php |
function gmgetdate($ts = null){ |
$k = array('seconds','minutes','hours','mday','wday','mon','year','yday','weekday','month',0); |
return(array_comb($k,explode(":",gmdate('s:i:G:j:w:n:Y:z:l:F:U',is_null($ts)?time():$ts)))); |
} |
// Added for PHP4 compatibility |
function array_comb($array1, $array2) { |
$out = array(); |
foreach ($array1 as $key => $value) { |
$out[$value] = $array2[$key]; |
} |
return $out; |
} |
function v($data,$pos) { |
return ord($data[$pos]) | ord($data[$pos+1])<<8; |
} |
class OLERead { |
var $data = ''; |
function OLERead(){ } |
function read($sFileName){ |
// check if file exist and is readable (Darko Miljanovic) |
if(!is_readable($sFileName)) { |
$this->error = 1; |
return false; |
} |
$this->data = @file_get_contents($sFileName); |
if (!$this->data) { |
$this->error = 1; |
return false; |
} |
if (substr($this->data, 0, 8) != IDENTIFIER_OLE) { |
$this->error = 1; |
return false; |
} |
$this->numBigBlockDepotBlocks = GetInt4d($this->data, NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); |
$this->sbdStartBlock = GetInt4d($this->data, SMALL_BLOCK_DEPOT_BLOCK_POS); |
$this->rootStartBlock = GetInt4d($this->data, ROOT_START_BLOCK_POS); |
$this->extensionBlock = GetInt4d($this->data, EXTENSION_BLOCK_POS); |
$this->numExtensionBlocks = GetInt4d($this->data, NUM_EXTENSION_BLOCK_POS); |
$bigBlockDepotBlocks = array(); |
$pos = BIG_BLOCK_DEPOT_BLOCKS_POS; |
$bbdBlocks = $this->numBigBlockDepotBlocks; |
if ($this->numExtensionBlocks != 0) { |
$bbdBlocks = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS)/4; |
} |
for ($i = 0; $i < $bbdBlocks; $i++) { |
$bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos); |
$pos += 4; |
} |
for ($j = 0; $j < $this->numExtensionBlocks; $j++) { |
$pos = ($this->extensionBlock + 1) * BIG_BLOCK_SIZE; |
$blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, BIG_BLOCK_SIZE / 4 - 1); |
for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; $i++) { |
$bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos); |
$pos += 4; |
} |
$bbdBlocks += $blocksToRead; |
if ($bbdBlocks < $this->numBigBlockDepotBlocks) { |
$this->extensionBlock = GetInt4d($this->data, $pos); |
} |
} |
// readBigBlockDepot |
$pos = 0; |
$index = 0; |
$this->bigBlockChain = array(); |
for ($i = 0; $i < $this->numBigBlockDepotBlocks; $i++) { |
$pos = ($bigBlockDepotBlocks[$i] + 1) * BIG_BLOCK_SIZE; |
//echo "pos = $pos"; |
for ($j = 0 ; $j < BIG_BLOCK_SIZE / 4; $j++) { |
$this->bigBlockChain[$index] = GetInt4d($this->data, $pos); |
$pos += 4 ; |
$index++; |
} |
} |
// readSmallBlockDepot(); |
$pos = 0; |
$index = 0; |
$sbdBlock = $this->sbdStartBlock; |
$this->smallBlockChain = array(); |
while ($sbdBlock != -2) { |
$pos = ($sbdBlock + 1) * BIG_BLOCK_SIZE; |
for ($j = 0; $j < BIG_BLOCK_SIZE / 4; $j++) { |
$this->smallBlockChain[$index] = GetInt4d($this->data, $pos); |
$pos += 4; |
$index++; |
} |
$sbdBlock = $this->bigBlockChain[$sbdBlock]; |
} |
// readData(rootStartBlock) |
$block = $this->rootStartBlock; |
$pos = 0; |
$this->entry = $this->__readData($block); |
$this->__readPropertySets(); |
} |
function __readData($bl) { |
$block = $bl; |
$pos = 0; |
$data = ''; |
while ($block != -2) { |
$pos = ($block + 1) * BIG_BLOCK_SIZE; |
$data = $data.substr($this->data, $pos, BIG_BLOCK_SIZE); |
$block = $this->bigBlockChain[$block]; |
} |
return $data; |
} |
function __readPropertySets(){ |
$offset = 0; |
while ($offset < strlen($this->entry)) { |
$d = substr($this->entry, $offset, PROPERTY_STORAGE_BLOCK_SIZE); |
$nameSize = ord($d[SIZE_OF_NAME_POS]) | (ord($d[SIZE_OF_NAME_POS+1]) << 8); |
$type = ord($d[TYPE_POS]); |
$startBlock = GetInt4d($d, START_BLOCK_POS); |
$size = GetInt4d($d, SIZE_POS); |
$name = ''; |
for ($i = 0; $i < $nameSize ; $i++) { |
$name .= $d[$i]; |
} |
$name = str_replace("\x00", "", $name); |
$this->props[] = array ( |
'name' => $name, |
'type' => $type, |
'startBlock' => $startBlock, |
'size' => $size); |
if ((strtolower($name) == "workbook") || ( strtolower($name) == "book")) { |
$this->wrkbook = count($this->props) - 1; |
} |
if ($name == "Root Entry") { |
$this->rootentry = count($this->props) - 1; |
} |
$offset += PROPERTY_STORAGE_BLOCK_SIZE; |
} |
} |
function getWorkBook(){ |
if ($this->props[$this->wrkbook]['size'] < SMALL_BLOCK_THRESHOLD){ |
$rootdata = $this->__readData($this->props[$this->rootentry]['startBlock']); |
$streamData = ''; |
$block = $this->props[$this->wrkbook]['startBlock']; |
$pos = 0; |
while ($block != -2) { |
$pos = $block * SMALL_BLOCK_SIZE; |
$streamData .= substr($rootdata, $pos, SMALL_BLOCK_SIZE); |
$block = $this->smallBlockChain[$block]; |
} |
return $streamData; |
}else{ |
$numBlocks = $this->props[$this->wrkbook]['size'] / BIG_BLOCK_SIZE; |
if ($this->props[$this->wrkbook]['size'] % BIG_BLOCK_SIZE != 0) { |
$numBlocks++; |
} |
if ($numBlocks == 0) return ''; |
$streamData = ''; |
$block = $this->props[$this->wrkbook]['startBlock']; |
$pos = 0; |
while ($block != -2) { |
$pos = ($block + 1) * BIG_BLOCK_SIZE; |
$streamData .= substr($this->data, $pos, BIG_BLOCK_SIZE); |
$block = $this->bigBlockChain[$block]; |
} |
return $streamData; |
} |
} |
} |
define('SPREADSHEET_EXCEL_READER_BIFF8', 0x600); |
define('SPREADSHEET_EXCEL_READER_BIFF7', 0x500); |
define('SPREADSHEET_EXCEL_READER_WORKBOOKGLOBALS', 0x5); |
define('SPREADSHEET_EXCEL_READER_WORKSHEET', 0x10); |
define('SPREADSHEET_EXCEL_READER_TYPE_BOF', 0x809); |
define('SPREADSHEET_EXCEL_READER_TYPE_EOF', 0x0a); |
define('SPREADSHEET_EXCEL_READER_TYPE_BOUNDSHEET', 0x85); |
define('SPREADSHEET_EXCEL_READER_TYPE_DIMENSION', 0x200); |
define('SPREADSHEET_EXCEL_READER_TYPE_ROW', 0x208); |
define('SPREADSHEET_EXCEL_READER_TYPE_DBCELL', 0xd7); |
define('SPREADSHEET_EXCEL_READER_TYPE_FILEPASS', 0x2f); |
define('SPREADSHEET_EXCEL_READER_TYPE_NOTE', 0x1c); |
define('SPREADSHEET_EXCEL_READER_TYPE_TXO', 0x1b6); |
define('SPREADSHEET_EXCEL_READER_TYPE_RK', 0x7e); |
define('SPREADSHEET_EXCEL_READER_TYPE_RK2', 0x27e); |
define('SPREADSHEET_EXCEL_READER_TYPE_MULRK', 0xbd); |
define('SPREADSHEET_EXCEL_READER_TYPE_MULBLANK', 0xbe); |
define('SPREADSHEET_EXCEL_READER_TYPE_INDEX', 0x20b); |
define('SPREADSHEET_EXCEL_READER_TYPE_SST', 0xfc); |
define('SPREADSHEET_EXCEL_READER_TYPE_EXTSST', 0xff); |
define('SPREADSHEET_EXCEL_READER_TYPE_CONTINUE', 0x3c); |
define('SPREADSHEET_EXCEL_READER_TYPE_LABEL', 0x204); |
define('SPREADSHEET_EXCEL_READER_TYPE_LABELSST', 0xfd); |
define('SPREADSHEET_EXCEL_READER_TYPE_NUMBER', 0x203); |
define('SPREADSHEET_EXCEL_READER_TYPE_NAME', 0x18); |
define('SPREADSHEET_EXCEL_READER_TYPE_ARRAY', 0x221); |
define('SPREADSHEET_EXCEL_READER_TYPE_STRING', 0x207); |
define('SPREADSHEET_EXCEL_READER_TYPE_FORMULA', 0x406); |
define('SPREADSHEET_EXCEL_READER_TYPE_FORMULA2', 0x6); |
define('SPREADSHEET_EXCEL_READER_TYPE_FORMAT', 0x41e); |
define('SPREADSHEET_EXCEL_READER_TYPE_XF', 0xe0); |
define('SPREADSHEET_EXCEL_READER_TYPE_BOOLERR', 0x205); |
define('SPREADSHEET_EXCEL_READER_TYPE_FONT', 0x0031); |
define('SPREADSHEET_EXCEL_READER_TYPE_PALETTE', 0x0092); |
define('SPREADSHEET_EXCEL_READER_TYPE_UNKNOWN', 0xffff); |
define('SPREADSHEET_EXCEL_READER_TYPE_NINETEENFOUR', 0x22); |
define('SPREADSHEET_EXCEL_READER_TYPE_MERGEDCELLS', 0xE5); |
define('SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS' , 25569); |
define('SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS1904', 24107); |
define('SPREADSHEET_EXCEL_READER_MSINADAY', 86400); |
define('SPREADSHEET_EXCEL_READER_TYPE_HYPER', 0x01b8); |
define('SPREADSHEET_EXCEL_READER_TYPE_COLINFO', 0x7d); |
define('SPREADSHEET_EXCEL_READER_TYPE_DEFCOLWIDTH', 0x55); |
define('SPREADSHEET_EXCEL_READER_TYPE_STANDARDWIDTH', 0x99); |
define('SPREADSHEET_EXCEL_READER_DEF_NUM_FORMAT', "%s"); |
/* |
* Main Class |
*/ |
class Spreadsheet_Excel_Reader { |
// MK: Added to make data retrieval easier |
var $colnames = array(); |
var $colindexes = array(); |
var $standardColWidth = 0; |
var $defaultColWidth = 0; |
function myHex($d) { |
if ($d < 16) return "0" . dechex($d); |
return dechex($d); |
} |
function dumpHexData($data, $pos, $length) { |
$info = ""; |
for ($i = 0; $i <= $length; $i++) { |
$info .= ($i==0?"":" ") . $this->myHex(ord($data[$pos + $i])) . (ord($data[$pos + $i])>31? "[" . $data[$pos + $i] . "]":''); |
} |
return $info; |
} |
function getCol($col) { |
if (is_string($col)) { |
$col = strtolower($col); |
if (array_key_exists($col,$this->colnames)) { |
$col = $this->colnames[$col]; |
} |
} |
return $col; |
} |
// PUBLIC API FUNCTIONS |
// -------------------- |
function val($row,$col,$sheet=0) { |
$col = $this->getCol($col); |
if (array_key_exists($row,$this->sheets[$sheet]['cells']) && array_key_exists($col,$this->sheets[$sheet]['cells'][$row])) { |
return $this->sheets[$sheet]['cells'][$row][$col]; |
} |
return ""; |
} |
function value($row,$col,$sheet=0) { |
return $this->val($row,$col,$sheet); |
} |
function info($row,$col,$type='',$sheet=0) { |
$col = $this->getCol($col); |
if (array_key_exists('cellsInfo',$this->sheets[$sheet]) |
&& array_key_exists($row,$this->sheets[$sheet]['cellsInfo']) |
&& array_key_exists($col,$this->sheets[$sheet]['cellsInfo'][$row]) |
&& array_key_exists($type,$this->sheets[$sheet]['cellsInfo'][$row][$col])) { |
return $this->sheets[$sheet]['cellsInfo'][$row][$col][$type]; |
} |
return ""; |
} |
function type($row,$col,$sheet=0) { |
return $this->info($row,$col,'type',$sheet); |
} |
function raw($row,$col,$sheet=0) { |
return $this->info($row,$col,'raw',$sheet); |
} |
function rowspan($row,$col,$sheet=0) { |
$val = $this->info($row,$col,'rowspan',$sheet); |
if ($val=="") { return 1; } |
return $val; |
} |
function colspan($row,$col,$sheet=0) { |
$val = $this->info($row,$col,'colspan',$sheet); |
if ($val=="") { return 1; } |
return $val; |
} |
function hyperlink($row,$col,$sheet=0) { |
$link = $this->sheets[$sheet]['cellsInfo'][$row][$col]['hyperlink']; |
if ($link) { |
return $link['link']; |
} |
return ''; |
} |
function rowcount($sheet=0) { |
return $this->sheets[$sheet]['numRows']; |
} |
function colcount($sheet=0) { |
return $this->sheets[$sheet]['numCols']; |
} |
function colwidth($col,$sheet=0) { |
// Col width is actually the width of the number 0. So we have to estimate and come close |
return $this->colInfo[$sheet][$col]['width']/9142*200; |
} |
function colhidden($col,$sheet=0) { |
return !!$this->colInfo[$sheet][$col]['hidden']; |
} |
function rowheight($row,$sheet=0) { |
return $this->rowInfo[$sheet][$row]['height']; |
} |
function rowhidden($row,$sheet=0) { |
return !!$this->rowInfo[$sheet][$row]['hidden']; |
} |
// GET THE CSS FOR FORMATTING |
// ========================== |
function style($row,$col,$sheet=0,$properties='') { |
$css = ""; |
$font=$this->font($row,$col,$sheet); |
if ($font!="") { |
$css .= "font-family:$font;"; |
} |
$align=$this->align($row,$col,$sheet); |
if ($align!="") { |
$css .= "text-align:$align;"; |
} |
$height=$this->height($row,$col,$sheet); |
if ($height!="") { |
$css .= "font-size:$height"."px;"; |
} |
$bgcolor=$this->bgColor($row,$col,$sheet); |
if ($bgcolor!="") { |
$bgcolor = $this->colors[$bgcolor]; |
$css .= "background-color:$bgcolor;"; |
} |
$color=$this->color($row,$col,$sheet); |
if ($color!="") { |
$css .= "color:$color;"; |
} |
$bold=$this->bold($row,$col,$sheet); |
if ($bold) { |
$css .= "font-weight:bold;"; |
} |
$italic=$this->italic($row,$col,$sheet); |
if ($italic) { |
$css .= "font-style:italic;"; |
} |
$underline=$this->underline($row,$col,$sheet); |
if ($underline) { |
$css .= "text-decoration:underline;"; |
} |
// Borders |
$bLeft = $this->borderLeft($row,$col,$sheet); |
$bRight = $this->borderRight($row,$col,$sheet); |
$bTop = $this->borderTop($row,$col,$sheet); |
$bBottom = $this->borderBottom($row,$col,$sheet); |
$bLeftCol = $this->borderLeftColor($row,$col,$sheet); |
$bRightCol = $this->borderRightColor($row,$col,$sheet); |
$bTopCol = $this->borderTopColor($row,$col,$sheet); |
$bBottomCol = $this->borderBottomColor($row,$col,$sheet); |
// Try to output the minimal required style |
if ($bLeft!="" && $bLeft==$bRight && $bRight==$bTop && $bTop==$bBottom) { |
$css .= "border:" . $this->lineStylesCss[$bLeft] .";"; |
} |
else { |
if ($bLeft!="") { $css .= "border-left:" . $this->lineStylesCss[$bLeft] .";"; } |
if ($bRight!="") { $css .= "border-right:" . $this->lineStylesCss[$bRight] .";"; } |
if ($bTop!="") { $css .= "border-top:" . $this->lineStylesCss[$bTop] .";"; } |
if ($bBottom!="") { $css .= "border-bottom:" . $this->lineStylesCss[$bBottom] .";"; } |
} |
// Only output border colors if there is an actual border specified |
if ($bLeft!="" && $bLeftCol!="") { $css .= "border-left-color:" . $bLeftCol .";"; } |
if ($bRight!="" && $bRightCol!="") { $css .= "border-right-color:" . $bRightCol .";"; } |
if ($bTop!="" && $bTopCol!="") { $css .= "border-top-color:" . $bTopCol . ";"; } |
if ($bBottom!="" && $bBottomCol!="") { $css .= "border-bottom-color:" . $bBottomCol .";"; } |
return $css; |
} |
// FORMAT PROPERTIES |
// ================= |
function format($row,$col,$sheet=0) { |
return $this->info($row,$col,'format',$sheet); |
} |
function formatIndex($row,$col,$sheet=0) { |
return $this->info($row,$col,'formatIndex',$sheet); |
} |
function formatColor($row,$col,$sheet=0) { |
return $this->info($row,$col,'formatColor',$sheet); |
} |
// CELL (XF) PROPERTIES |
// ==================== |
function xfRecord($row,$col,$sheet=0) { |
$xfIndex = $this->info($row,$col,'xfIndex',$sheet); |
if ($xfIndex!="") { |
return $this->xfRecords[$xfIndex]; |
} |
return null; |
} |
function xfProperty($row,$col,$sheet,$prop) { |
$xfRecord = $this->xfRecord($row,$col,$sheet); |
if ($xfRecord!=null) { |
return $xfRecord[$prop]; |
} |
return ""; |
} |
function align($row,$col,$sheet=0) { |
return $this->xfProperty($row,$col,$sheet,'align'); |
} |
function bgColor($row,$col,$sheet=0) { |
return $this->xfProperty($row,$col,$sheet,'bgColor'); |
} |
function borderLeft($row,$col,$sheet=0) { |
return $this->xfProperty($row,$col,$sheet,'borderLeft'); |
} |
function borderRight($row,$col,$sheet=0) { |
return $this->xfProperty($row,$col,$sheet,'borderRight'); |
} |
function borderTop($row,$col,$sheet=0) { |
return $this->xfProperty($row,$col,$sheet,'borderTop'); |
} |
function borderBottom($row,$col,$sheet=0) { |
return $this->xfProperty($row,$col,$sheet,'borderBottom'); |
} |
function borderLeftColor($row,$col,$sheet=0) { |
return $this->colors[$this->xfProperty($row,$col,$sheet,'borderLeftColor')]; |
} |
function borderRightColor($row,$col,$sheet=0) { |
return $this->colors[$this->xfProperty($row,$col,$sheet,'borderRightColor')]; |
} |
function borderTopColor($row,$col,$sheet=0) { |
return $this->colors[$this->xfProperty($row,$col,$sheet,'borderTopColor')]; |
} |
function borderBottomColor($row,$col,$sheet=0) { |
return $this->colors[$this->xfProperty($row,$col,$sheet,'borderBottomColor')]; |
} |
// FONT PROPERTIES |
// =============== |
function fontRecord($row,$col,$sheet=0) { |
$xfRecord = $this->xfRecord($row,$col,$sheet); |
if ($xfRecord!=null) { |
$font = $xfRecord['fontIndex']; |
if ($font!=null) { |
return $this->fontRecords[$font]; |
} |
} |
return null; |
} |
function fontProperty($row,$col,$sheet=0,$prop) { |
$font = $this->fontRecord($row,$col,$sheet); |
if ($font!=null) { |
return $font[$prop]; |
} |
return false; |
} |
function fontIndex($row,$col,$sheet=0) { |
return $this->xfProperty($row,$col,$sheet,'fontIndex'); |
} |
function color($row,$col,$sheet=0) { |
$formatColor = $this->formatColor($row,$col,$sheet); |
if ($formatColor!="") { |
return $formatColor; |
} |
$ci = $this->fontProperty($row,$col,$sheet,'color'); |
return $this->rawColor($ci); |
} |
function rawColor($ci) { |
if (($ci <> 0x7FFF) && ($ci <> '')) { |
return $this->colors[$ci]; |
} |
return ""; |
} |
function bold($row,$col,$sheet=0) { |
return $this->fontProperty($row,$col,$sheet,'bold'); |
} |
function italic($row,$col,$sheet=0) { |
return $this->fontProperty($row,$col,$sheet,'italic'); |
} |
function underline($row,$col,$sheet=0) { |
return $this->fontProperty($row,$col,$sheet,'under'); |
} |
function height($row,$col,$sheet=0) { |
return $this->fontProperty($row,$col,$sheet,'height'); |
} |
function font($row,$col,$sheet=0) { |
return $this->fontProperty($row,$col,$sheet,'font'); |
} |
// DUMP AN HTML TABLE OF THE ENTIRE XLS DATA |
// ========================================= |
function dump($row_numbers=false,$col_letters=false,$sheet=0,$table_class='excel') { |
$out = "<table class=\"$table_class\" cellspacing=0>"; |
if ($col_letters) { |
$out .= "<thead>\n\t<tr>"; |
if ($row_numbers) { |
$out .= "\n\t\t<th> </th>"; |
} |
for($i=1;$i<=$this->colcount($sheet);$i++) { |
$style = "width:" . ($this->colwidth($i,$sheet)*1) . "px;"; |
if ($this->colhidden($i,$sheet)) { |
$style .= "display:none;"; |
} |
$out .= "\n\t\t<th style=\"$style\">" . strtoupper($this->colindexes[$i]) . "</th>"; |
} |
$out .= "</tr></thead>\n"; |
} |
$out .= "<tbody>\n"; |
for($row=1;$row<=$this->rowcount($sheet);$row++) { |
$rowheight = $this->rowheight($row,$sheet); |
$style = "height:" . ($rowheight*(4/3)) . "px;"; |
if ($this->rowhidden($row,$sheet)) { |
$style .= "display:none;"; |
} |
$out .= "\n\t<tr style=\"$style\">"; |
if ($row_numbers) { |
$out .= "\n\t\t<th>$row</th>"; |
} |
for($col=1;$col<=$this->colcount($sheet);$col++) { |
// Account for Rowspans/Colspans |
$rowspan = $this->rowspan($row,$col,$sheet); |
$colspan = $this->colspan($row,$col,$sheet); |
for($i=0;$i<$rowspan;$i++) { |
for($j=0;$j<$colspan;$j++) { |
if ($i>0 || $j>0) { |
$this->sheets[$sheet]['cellsInfo'][$row+$i][$col+$j]['dontprint']=1; |
} |
} |
} |
if(!$this->sheets[$sheet]['cellsInfo'][$row][$col]['dontprint']) { |
$style = $this->style($row,$col,$sheet); |
if ($this->colhidden($col,$sheet)) { |
$style .= "display:none;"; |
} |
$out .= "\n\t\t<td style=\"$style\"" . ($colspan > 1?" colspan=$colspan":"") . ($rowspan > 1?" rowspan=$rowspan":"") . ">"; |
$val = $this->val($row,$col,$sheet); |
if ($val=='') { $val=" "; } |
else { |
$val = htmlentities($val); |
$link = $this->hyperlink($row,$col,$sheet); |
if ($link!='') { |
$val = "<a href=\"$link\">$val</a>"; |
} |
} |
$out .= "<nobr>".nl2br($val)."</nobr>"; |
$out .= "</td>"; |
} |
} |
$out .= "</tr>\n"; |
} |
$out .= "</tbody></table>"; |
return $out; |
} |
// -------------- |
// END PUBLIC API |
var $boundsheets = array(); |
var $formatRecords = array(); |
var $fontRecords = array(); |
var $xfRecords = array(); |
var $colInfo = array(); |
var $rowInfo = array(); |
var $sst = array(); |
var $sheets = array(); |
var $data; |
var $_ole; |
var $_defaultEncoding = "UTF-8"; |
var $_defaultFormat = SPREADSHEET_EXCEL_READER_DEF_NUM_FORMAT; |
var $_columnsFormat = array(); |
var $_rowoffset = 1; |
var $_coloffset = 1; |
/** |
* List of default date formats used by Excel |
*/ |
var $dateFormats = array ( |
0xe => "m/d/Y", |
0xf => "M-d-Y", |
0x10 => "d-M", |
0x11 => "M-Y", |
0x12 => "h:i a", |
0x13 => "h:i:s a", |
0x14 => "H:i", |
0x15 => "H:i:s", |
0x16 => "d/m/Y H:i", |
0x2d => "i:s", |
0x2e => "H:i:s", |
0x2f => "i:s.S" |
); |
/** |
* Default number formats used by Excel |
*/ |
var $numberFormats = array( |
0x1 => "0", |
0x2 => "0.00", |
0x3 => "#,##0", |
0x4 => "#,##0.00", |
0x5 => "\$#,##0;(\$#,##0)", |
0x6 => "\$#,##0;[Red](\$#,##0)", |
0x7 => "\$#,##0.00;(\$#,##0.00)", |
0x8 => "\$#,##0.00;[Red](\$#,##0.00)", |
0x9 => "0%", |
0xa => "0.00%", |
0xb => "0.00E+00", |
0x25 => "#,##0;(#,##0)", |
0x26 => "#,##0;[Red](#,##0)", |
0x27 => "#,##0.00;(#,##0.00)", |
0x28 => "#,##0.00;[Red](#,##0.00)", |
0x29 => "#,##0;(#,##0)", // Not exactly |
0x2a => "\$#,##0;(\$#,##0)", // Not exactly |
0x2b => "#,##0.00;(#,##0.00)", // Not exactly |
0x2c => "\$#,##0.00;(\$#,##0.00)", // Not exactly |
0x30 => "##0.0E+0" |
); |
var $colors = Array( |
0x00 => "#000000", |
0x01 => "#FFFFFF", |
0x02 => "#FF0000", |
0x03 => "#00FF00", |
0x04 => "#0000FF", |
0x05 => "#FFFF00", |
0x06 => "#FF00FF", |
0x07 => "#00FFFF", |
0x08 => "#000000", |
0x09 => "#FFFFFF", |
0x0A => "#FF0000", |
0x0B => "#00FF00", |
0x0C => "#0000FF", |
0x0D => "#FFFF00", |
0x0E => "#FF00FF", |
0x0F => "#00FFFF", |
0x10 => "#800000", |
0x11 => "#008000", |
0x12 => "#000080", |
0x13 => "#808000", |
0x14 => "#800080", |
0x15 => "#008080", |
0x16 => "#C0C0C0", |
0x17 => "#808080", |
0x18 => "#9999FF", |
0x19 => "#993366", |
0x1A => "#FFFFCC", |
0x1B => "#CCFFFF", |
0x1C => "#660066", |
0x1D => "#FF8080", |
0x1E => "#0066CC", |
0x1F => "#CCCCFF", |
0x20 => "#000080", |
0x21 => "#FF00FF", |
0x22 => "#FFFF00", |
0x23 => "#00FFFF", |
0x24 => "#800080", |
0x25 => "#800000", |
0x26 => "#008080", |
0x27 => "#0000FF", |
0x28 => "#00CCFF", |
0x29 => "#CCFFFF", |
0x2A => "#CCFFCC", |
0x2B => "#FFFF99", |
0x2C => "#99CCFF", |
0x2D => "#FF99CC", |
0x2E => "#CC99FF", |
0x2F => "#FFCC99", |
0x30 => "#3366FF", |
0x31 => "#33CCCC", |
0x32 => "#99CC00", |
0x33 => "#FFCC00", |
0x34 => "#FF9900", |
0x35 => "#FF6600", |
0x36 => "#666699", |
0x37 => "#969696", |
0x38 => "#003366", |
0x39 => "#339966", |
0x3A => "#003300", |
0x3B => "#333300", |
0x3C => "#993300", |
0x3D => "#993366", |
0x3E => "#333399", |
0x3F => "#333333", |
0x40 => "#000000", |
0x41 => "#FFFFFF", |
0x43 => "#000000", |
0x4D => "#000000", |
0x4E => "#FFFFFF", |
0x4F => "#000000", |
0x50 => "#FFFFFF", |
0x51 => "#000000", |
0x7FFF => "#000000" |
); |
var $lineStyles = array( |
0x00 => "", |
0x01 => "Thin", |
0x02 => "Medium", |
0x03 => "Dashed", |
0x04 => "Dotted", |
0x05 => "Thick", |
0x06 => "Double", |
0x07 => "Hair", |
0x08 => "Medium dashed", |
0x09 => "Thin dash-dotted", |
0x0A => "Medium dash-dotted", |
0x0B => "Thin dash-dot-dotted", |
0x0C => "Medium dash-dot-dotted", |
0x0D => "Slanted medium dash-dotted" |
); |
var $lineStylesCss = array( |
"Thin" => "1px solid", |
"Medium" => "2px solid", |
"Dashed" => "1px dashed", |
"Dotted" => "1px dotted", |
"Thick" => "3px solid", |
"Double" => "double", |
"Hair" => "1px solid", |
"Medium dashed" => "2px dashed", |
"Thin dash-dotted" => "1px dashed", |
"Medium dash-dotted" => "2px dashed", |
"Thin dash-dot-dotted" => "1px dashed", |
"Medium dash-dot-dotted" => "2px dashed", |
"Slanted medium dash-dotte" => "2px dashed" |
); |
function read16bitstring($data, $start) { |
$len = 0; |
while (ord($data[$start + $len]) + ord($data[$start + $len + 1]) > 0) $len++; |
return substr($data, $start, $len); |
} |
// ADDED by Matt Kruse for better formatting |
function _format_value($format,$num,$f) { |
// 49==TEXT format |
// http://code.google.com/p/php-excel-reader/issues/detail?id=7 |
if ( (!$f && $format=="%s") || ($f==49) || ($format=="GENERAL") ) { |
return array('string'=>$num, 'formatColor'=>null); |
} |
// Custom pattern can be POSITIVE;NEGATIVE;ZERO |
// The "text" option as 4th parameter is not handled |
$parts = explode(";",$format); |
$pattern = $parts[0]; |
// Negative pattern |
if (count($parts)>2 && $num==0) { |
$pattern = $parts[2]; |
} |
// Zero pattern |
if (count($parts)>1 && $num<0) { |
$pattern = $parts[1]; |
$num = abs($num); |
} |
$color = ""; |
$matches = array(); |
$color_regex = "/^\[(BLACK|BLUE|CYAN|GREEN|MAGENTA|RED|WHITE|YELLOW)\]/i"; |
if (preg_match($color_regex,$pattern,$matches)) { |
$color = strtolower($matches[1]); |
$pattern = preg_replace($color_regex,"",$pattern); |
} |
// In Excel formats, "_" is used to add spacing, which we can't do in HTML |
$pattern = preg_replace("/_./","",$pattern); |
// Some non-number characters are escaped with \, which we don't need |
$pattern = preg_replace("/\\\/","",$pattern); |
// Some non-number strings are quoted, so we'll get rid of the quotes |
$pattern = preg_replace("/\"/","",$pattern); |
// TEMPORARY - Convert # to 0 |
$pattern = preg_replace("/\#/","0",$pattern); |
// Find out if we need comma formatting |
$has_commas = preg_match("/,/",$pattern); |
if ($has_commas) { |
$pattern = preg_replace("/,/","",$pattern); |
} |
// Handle Percentages |
if (preg_match("/\d(\%)([^\%]|$)/",$pattern,$matches)) { |
$num = $num * 100; |
$pattern = preg_replace("/(\d)(\%)([^\%]|$)/","$1%$3",$pattern); |
} |
// Handle the number itself |
$number_regex = "/(\d+)(\.?)(\d*)/"; |
if (preg_match($number_regex,$pattern,$matches)) { |
$left = $matches[1]; |
$dec = $matches[2]; |
$right = $matches[3]; |
if ($has_commas) { |
$formatted = number_format($num,strlen($right)); |
} |
else { |
$sprintf_pattern = "%1.".strlen($right)."f"; |
$formatted = sprintf($sprintf_pattern, $num); |
} |
$pattern = preg_replace($number_regex, $formatted, $pattern); |
} |
return array( |
'string'=>$pattern, |
'formatColor'=>$color |
); |
} |
/** |
* Constructor |
* |
* Some basic initialisation |
*/ |
function Spreadsheet_Excel_Reader($file='',$store_extended_info=true,$outputEncoding='') { |
$this->_ole =& new OLERead(); |
$this->setUTFEncoder('iconv'); |
if ($outputEncoding != '') { |
$this->setOutputEncoding($outputEncoding); |
} |
for ($i=1; $i<245; $i++) { |
$name = strtolower(( (($i-1)/26>=1)?chr(($i-1)/26+64):'') . chr(($i-1)%26+65)); |
$this->colnames[$name] = $i; |
$this->colindexes[$i] = $name; |
} |
$this->store_extended_info = $store_extended_info; |
if ($file!="") { |
$this->read($file); |
} |
} |
/** |
* Set the encoding method |
*/ |
function setOutputEncoding($encoding) { |
$this->_defaultEncoding = $encoding; |
} |
/** |
* $encoder = 'iconv' or 'mb' |
* set iconv if you would like use 'iconv' for encode UTF-16LE to your encoding |
* set mb if you would like use 'mb_convert_encoding' for encode UTF-16LE to your encoding |
*/ |
function setUTFEncoder($encoder = 'iconv') { |
$this->_encoderFunction = ''; |
if ($encoder == 'iconv') { |
$this->_encoderFunction = function_exists('iconv') ? 'iconv' : ''; |
} elseif ($encoder == 'mb') { |
$this->_encoderFunction = function_exists('mb_convert_encoding') ? 'mb_convert_encoding' : ''; |
} |
} |
function setRowColOffset($iOffset) { |
$this->_rowoffset = $iOffset; |
$this->_coloffset = $iOffset; |
} |
/** |
* Set the default number format |
*/ |
function setDefaultFormat($sFormat) { |
$this->_defaultFormat = $sFormat; |
} |
/** |
* Force a column to use a certain format |
*/ |
function setColumnFormat($column, $sFormat) { |
$this->_columnsFormat[$column] = $sFormat; |
} |
/** |
* Read the spreadsheet file using OLE, then parse |
*/ |
function read($sFileName) { |
$res = $this->_ole->read($sFileName); |
// oops, something goes wrong (Darko Miljanovic) |
if($res === false) { |
// check error code |
if($this->_ole->error == 1) { |
// bad file |
die('The filename ' . $sFileName . ' is not readable'); |
} |
// check other error codes here (eg bad fileformat, etc...) |
} |
$this->data = $this->_ole->getWorkBook(); |
$this->_parse(); |
} |
/** |
* Parse a workbook |
* |
* @access private |
* @return bool |
*/ |
function _parse() { |
$pos = 0; |
$data = $this->data; |
$code = v($data,$pos); |
$length = v($data,$pos+2); |
$version = v($data,$pos+4); |
$substreamType = v($data,$pos+6); |
$this->version = $version; |
if (($version != SPREADSHEET_EXCEL_READER_BIFF8) && |
($version != SPREADSHEET_EXCEL_READER_BIFF7)) { |
return false; |
} |
if ($substreamType != SPREADSHEET_EXCEL_READER_WORKBOOKGLOBALS){ |
return false; |
} |
$pos += $length + 4; |
$code = v($data,$pos); |
$length = v($data,$pos+2); |
while ($code != SPREADSHEET_EXCEL_READER_TYPE_EOF) { |
switch ($code) { |
case SPREADSHEET_EXCEL_READER_TYPE_SST: |
$spos = $pos + 4; |
$limitpos = $spos + $length; |
$uniqueStrings = $this->_GetInt4d($data, $spos+4); |
$spos += 8; |
for ($i = 0; $i < $uniqueStrings; $i++) { |
// Read in the number of characters |
if ($spos == $limitpos) { |
$opcode = v($data,$spos); |
$conlength = v($data,$spos+2); |
if ($opcode != 0x3c) { |
return -1; |
} |
$spos += 4; |
$limitpos = $spos + $conlength; |
} |
$numChars = ord($data[$spos]) | (ord($data[$spos+1]) << 8); |
$spos += 2; |
$optionFlags = ord($data[$spos]); |
$spos++; |
$asciiEncoding = (($optionFlags & 0x01) == 0) ; |
$extendedString = ( ($optionFlags & 0x04) != 0); |
// See if string contains formatting information |
$richString = ( ($optionFlags & 0x08) != 0); |
if ($richString) { |
// Read in the crun |
$formattingRuns = v($data,$spos); |
$spos += 2; |
} |
if ($extendedString) { |
// Read in cchExtRst |
$extendedRunLength = $this->_GetInt4d($data, $spos); |
$spos += 4; |
} |
$len = ($asciiEncoding)? $numChars : $numChars*2; |
if ($spos + $len < $limitpos) { |
$retstr = substr($data, $spos, $len); |
$spos += $len; |
} |
else{ |
// found countinue |
$retstr = substr($data, $spos, $limitpos - $spos); |
$bytesRead = $limitpos - $spos; |
$charsLeft = $numChars - (($asciiEncoding) ? $bytesRead : ($bytesRead / 2)); |
$spos = $limitpos; |
while ($charsLeft > 0){ |
$opcode = v($data,$spos); |
$conlength = v($data,$spos+2); |
if ($opcode != 0x3c) { |
return -1; |
} |
$spos += 4; |
$limitpos = $spos + $conlength; |
$option = ord($data[$spos]); |
$spos += 1; |
if ($asciiEncoding && ($option == 0)) { |
$len = min($charsLeft, $limitpos - $spos); // min($charsLeft, $conlength); |
$retstr .= substr($data, $spos, $len); |
$charsLeft -= $len; |
$asciiEncoding = true; |
} |
elseif (!$asciiEncoding && ($option != 0)) { |
$len = min($charsLeft * 2, $limitpos - $spos); // min($charsLeft, $conlength); |
$retstr .= substr($data, $spos, $len); |
$charsLeft -= $len/2; |
$asciiEncoding = false; |
} |
elseif (!$asciiEncoding && ($option == 0)) { |
// Bummer - the string starts off as Unicode, but after the |
// continuation it is in straightforward ASCII encoding |
$len = min($charsLeft, $limitpos - $spos); // min($charsLeft, $conlength); |
for ($j = 0; $j < $len; $j++) { |
$retstr .= $data[$spos + $j].chr(0); |
} |
$charsLeft -= $len; |
$asciiEncoding = false; |
} |
else{ |
$newstr = ''; |
for ($j = 0; $j < strlen($retstr); $j++) { |
$newstr = $retstr[$j].chr(0); |
} |
$retstr = $newstr; |
$len = min($charsLeft * 2, $limitpos - $spos); // min($charsLeft, $conlength); |
$retstr .= substr($data, $spos, $len); |
$charsLeft -= $len/2; |
$asciiEncoding = false; |
} |
$spos += $len; |
} |
} |
$retstr = ($asciiEncoding) ? $retstr : $this->_encodeUTF16($retstr); |
if ($richString){ |
$spos += 4 * $formattingRuns; |
} |
// For extended strings, skip over the extended string data |
if ($extendedString) { |
$spos += $extendedRunLength; |
} |
$this->sst[]=$retstr; |
} |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_FILEPASS: |
return false; |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_NAME: |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_FORMAT: |
$indexCode = v($data,$pos+4); |
if ($version == SPREADSHEET_EXCEL_READER_BIFF8) { |
$numchars = v($data,$pos+6); |
if (ord($data[$pos+8]) == 0){ |
$formatString = substr($data, $pos+9, $numchars); |
} else { |
$formatString = substr($data, $pos+9, $numchars*2); |
} |
} else { |
$numchars = ord($data[$pos+6]); |
$formatString = substr($data, $pos+7, $numchars*2); |
} |
$this->formatRecords[$indexCode] = $formatString; |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_FONT: |
$height = v($data,$pos+4); |
$option = v($data,$pos+6); |
$color = v($data,$pos+8); |
$weight = v($data,$pos+10); |
$under = ord($data[$pos+14]); |
$font = ""; |
// Font name |
$numchars = ord($data[$pos+18]); |
if ((ord($data[$pos+19]) & 1) == 0){ |
$font = substr($data, $pos+20, $numchars); |
} else { |
$font = substr($data, $pos+20, $numchars*2); |
$font = $this->_encodeUTF16($font); |
} |
$this->fontRecords[] = array( |
'height' => $height / 20, |
'italic' => !!($option & 2), |
'color' => $color, |
'under' => !($under==0), |
'bold' => ($weight==700), |
'font' => $font, |
'raw' => $this->dumpHexData($data, $pos+3, $length) |
); |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_PALETTE: |
$colors = ord($data[$pos+4]) | ord($data[$pos+5]) << 8; |
for ($coli = 0; $coli < $colors; $coli++) { |
$colOff = $pos + 2 + ($coli * 4); |
$colr = ord($data[$colOff]); |
$colg = ord($data[$colOff+1]); |
$colb = ord($data[$colOff+2]); |
$this->colors[0x07 + $coli] = '#' . $this->myhex($colr) . $this->myhex($colg) . $this->myhex($colb); |
} |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_XF: |
$fontIndexCode = (ord($data[$pos+4]) | ord($data[$pos+5]) << 8) - 1; |
$fontIndexCode = max(0,$fontIndexCode); |
$indexCode = ord($data[$pos+6]) | ord($data[$pos+7]) << 8; |
$alignbit = ord($data[$pos+10]) & 3; |
$bgi = (ord($data[$pos+22]) | ord($data[$pos+23]) << 8) & 0x3FFF; |
$bgcolor = ($bgi & 0x7F); |
// $bgcolor = ($bgi & 0x3f80) >> 7; |
$align = ""; |
if ($alignbit==3) { $align="right"; } |
if ($alignbit==2) { $align="center"; } |
$fillPattern = (ord($data[$pos+21]) & 0xFC) >> 2; |
if ($fillPattern == 0) { |
$bgcolor = ""; |
} |
$xf = array(); |
$xf['formatIndex'] = $indexCode; |
$xf['align'] = $align; |
$xf['fontIndex'] = $fontIndexCode; |
$xf['bgColor'] = $bgcolor; |
$xf['fillPattern'] = $fillPattern; |
$border = ord($data[$pos+14]) | (ord($data[$pos+15]) << 8) | (ord($data[$pos+16]) << 16) | (ord($data[$pos+17]) << 24); |
$xf['borderLeft'] = $this->lineStyles[($border & 0xF)]; |
$xf['borderRight'] = $this->lineStyles[($border & 0xF0) >> 4]; |
$xf['borderTop'] = $this->lineStyles[($border & 0xF00) >> 8]; |
$xf['borderBottom'] = $this->lineStyles[($border & 0xF000) >> 12]; |
$xf['borderLeftColor'] = ($border & 0x7F0000) >> 16; |
$xf['borderRightColor'] = ($border & 0x3F800000) >> 23; |
$border = (ord($data[$pos+18]) | ord($data[$pos+19]) << 8); |
$xf['borderTopColor'] = ($border & 0x7F); |
$xf['borderBottomColor'] = ($border & 0x3F80) >> 7; |
if (array_key_exists($indexCode, $this->dateFormats)) { |
$xf['type'] = 'date'; |
$xf['format'] = $this->dateFormats[$indexCode]; |
if ($align=='') { $xf['align'] = 'right'; } |
}elseif (array_key_exists($indexCode, $this->numberFormats)) { |
$xf['type'] = 'number'; |
$xf['format'] = $this->numberFormats[$indexCode]; |
if ($align=='') { $xf['align'] = 'right'; } |
}else{ |
$isdate = FALSE; |
$formatstr = ''; |
if ($indexCode > 0){ |
if (isset($this->formatRecords[$indexCode])) |
$formatstr = $this->formatRecords[$indexCode]; |
if ($formatstr!="") { |
$tmp = preg_replace("/\;.*/","",$formatstr); |
$tmp = preg_replace("/^\[[^\]]*\]/","",$tmp); |
if (preg_match("/[^hmsday\/\-:\s\\\,AMP]/i", $tmp) == 0) { // found day and time format |
$isdate = TRUE; |
$formatstr = $tmp; |
$formatstr = str_replace(array('AM/PM','mmmm','mmm'), array('a','F','M'), $formatstr); |
// m/mm are used for both minutes and months - oh SNAP! |
// This mess tries to fix for that. |
// 'm' == minutes only if following h/hh or preceding s/ss |
$formatstr = preg_replace("/(h:?)mm?/","$1i", $formatstr); |
$formatstr = preg_replace("/mm?(:?s)/","i$1", $formatstr); |
// A single 'm' = n in PHP |
$formatstr = preg_replace("/(^|[^m])m([^m]|$)/", '$1n$2', $formatstr); |
$formatstr = preg_replace("/(^|[^m])m([^m]|$)/", '$1n$2', $formatstr); |
// else it's months |
$formatstr = str_replace('mm', 'm', $formatstr); |
// Convert single 'd' to 'j' |
$formatstr = preg_replace("/(^|[^d])d([^d]|$)/", '$1j$2', $formatstr); |
$formatstr = str_replace(array('dddd','ddd','dd','yyyy','yy','hh','h'), array('l','D','d','Y','y','H','g'), $formatstr); |
$formatstr = preg_replace("/ss?/", 's', $formatstr); |
} |
} |
} |
if ($isdate){ |
$xf['type'] = 'date'; |
$xf['format'] = $formatstr; |
if ($align=='') { $xf['align'] = 'right'; } |
}else{ |
// If the format string has a 0 or # in it, we'll assume it's a number |
if (preg_match("/[0#]/", $formatstr)) { |
$xf['type'] = 'number'; |
if ($align=='') { $xf['align']='right'; } |
} |
else { |
$xf['type'] = 'other'; |
} |
$xf['format'] = $formatstr; |
$xf['code'] = $indexCode; |
} |
} |
$this->xfRecords[] = $xf; |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_NINETEENFOUR: |
$this->nineteenFour = (ord($data[$pos+4]) == 1); |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_BOUNDSHEET: |
$rec_offset = $this->_GetInt4d($data, $pos+4); |
$rec_typeFlag = ord($data[$pos+8]); |
$rec_visibilityFlag = ord($data[$pos+9]); |
$rec_length = ord($data[$pos+10]); |
if ($version == SPREADSHEET_EXCEL_READER_BIFF8){ |
$chartype = ord($data[$pos+11]); |
if ($chartype == 0){ |
$rec_name = substr($data, $pos+12, $rec_length); |
} else { |
$rec_name = $this->_encodeUTF16(substr($data, $pos+12, $rec_length*2)); |
} |
}elseif ($version == SPREADSHEET_EXCEL_READER_BIFF7){ |
$rec_name = substr($data, $pos+11, $rec_length); |
} |
$this->boundsheets[] = array('name'=>$rec_name,'offset'=>$rec_offset); |
break; |
} |
$pos += $length + 4; |
$code = ord($data[$pos]) | ord($data[$pos+1])<<8; |
$length = ord($data[$pos+2]) | ord($data[$pos+3])<<8; |
} |
foreach ($this->boundsheets as $key=>$val){ |
$this->sn = $key; |
$this->_parsesheet($val['offset']); |
} |
return true; |
} |
/** |
* Parse a worksheet |
*/ |
function _parsesheet($spos) { |
$cont = true; |
$data = $this->data; |
// read BOF |
$code = ord($data[$spos]) | ord($data[$spos+1])<<8; |
$length = ord($data[$spos+2]) | ord($data[$spos+3])<<8; |
$version = ord($data[$spos + 4]) | ord($data[$spos + 5])<<8; |
$substreamType = ord($data[$spos + 6]) | ord($data[$spos + 7])<<8; |
if (($version != SPREADSHEET_EXCEL_READER_BIFF8) && ($version != SPREADSHEET_EXCEL_READER_BIFF7)) { |
return -1; |
} |
if ($substreamType != SPREADSHEET_EXCEL_READER_WORKSHEET){ |
return -2; |
} |
$spos += $length + 4; |
while($cont) { |
$lowcode = ord($data[$spos]); |
if ($lowcode == SPREADSHEET_EXCEL_READER_TYPE_EOF) break; |
$code = $lowcode | ord($data[$spos+1])<<8; |
$length = ord($data[$spos+2]) | ord($data[$spos+3])<<8; |
$spos += 4; |
$this->sheets[$this->sn]['maxrow'] = $this->_rowoffset - 1; |
$this->sheets[$this->sn]['maxcol'] = $this->_coloffset - 1; |
unset($this->rectype); |
switch ($code) { |
case SPREADSHEET_EXCEL_READER_TYPE_DIMENSION: |
if (!isset($this->numRows)) { |
if (($length == 10) || ($version == SPREADSHEET_EXCEL_READER_BIFF7)){ |
$this->sheets[$this->sn]['numRows'] = ord($data[$spos+2]) | ord($data[$spos+3]) << 8; |
$this->sheets[$this->sn]['numCols'] = ord($data[$spos+6]) | ord($data[$spos+7]) << 8; |
} else { |
$this->sheets[$this->sn]['numRows'] = ord($data[$spos+4]) | ord($data[$spos+5]) << 8; |
$this->sheets[$this->sn]['numCols'] = ord($data[$spos+10]) | ord($data[$spos+11]) << 8; |
} |
} |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_MERGEDCELLS: |
$cellRanges = ord($data[$spos]) | ord($data[$spos+1])<<8; |
for ($i = 0; $i < $cellRanges; $i++) { |
$fr = ord($data[$spos + 8*$i + 2]) | ord($data[$spos + 8*$i + 3])<<8; |
$lr = ord($data[$spos + 8*$i + 4]) | ord($data[$spos + 8*$i + 5])<<8; |
$fc = ord($data[$spos + 8*$i + 6]) | ord($data[$spos + 8*$i + 7])<<8; |
$lc = ord($data[$spos + 8*$i + 8]) | ord($data[$spos + 8*$i + 9])<<8; |
if ($lr - $fr > 0) { |
$this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['rowspan'] = $lr - $fr + 1; |
} |
if ($lc - $fc > 0) { |
$this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['colspan'] = $lc - $fc + 1; |
} |
} |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_RK: |
case SPREADSHEET_EXCEL_READER_TYPE_RK2: |
$row = ord($data[$spos]) | ord($data[$spos+1])<<8; |
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8; |
$rknum = $this->_GetInt4d($data, $spos + 6); |
$numValue = $this->_GetIEEE754($rknum); |
$info = $this->_getCellDetails($spos,$numValue,$column); |
$this->addcell($row, $column, $info['string'],$info); |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_LABELSST: |
$row = ord($data[$spos]) | ord($data[$spos+1])<<8; |
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8; |
$xfindex = ord($data[$spos+4]) | ord($data[$spos+5])<<8; |
$index = $this->_GetInt4d($data, $spos + 6); |
$this->addcell($row, $column, $this->sst[$index], array('xfIndex'=>$xfindex) ); |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_MULRK: |
$row = ord($data[$spos]) | ord($data[$spos+1])<<8; |
$colFirst = ord($data[$spos+2]) | ord($data[$spos+3])<<8; |
$colLast = ord($data[$spos + $length - 2]) | ord($data[$spos + $length - 1])<<8; |
$columns = $colLast - $colFirst + 1; |
$tmppos = $spos+4; |
for ($i = 0; $i < $columns; $i++) { |
$numValue = $this->_GetIEEE754($this->_GetInt4d($data, $tmppos + 2)); |
$info = $this->_getCellDetails($tmppos-4,$numValue,$colFirst + $i + 1); |
$tmppos += 6; |
$this->addcell($row, $colFirst + $i, $info['string'], $info); |
} |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_NUMBER: |
$row = ord($data[$spos]) | ord($data[$spos+1])<<8; |
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8; |
$tmp = unpack("ddouble", substr($data, $spos + 6, 8)); // It machine machine dependent |
if ($this->isDate($spos)) { |
$numValue = $tmp['double']; |
} |
else { |
$numValue = $this->createNumber($spos); |
} |
$info = $this->_getCellDetails($spos,$numValue,$column); |
$this->addcell($row, $column, $info['string'], $info); |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_FORMULA: |
case SPREADSHEET_EXCEL_READER_TYPE_FORMULA2: |
$row = ord($data[$spos]) | ord($data[$spos+1])<<8; |
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8; |
if ((ord($data[$spos+6])==0) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) { |
//String formula. Result follows in a STRING record |
// This row/col are stored to be referenced in that record |
// http://code.google.com/p/php-excel-reader/issues/detail?id=4 |
$previousRow = $row; |
$previousCol = $column; |
} elseif ((ord($data[$spos+6])==1) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) { |
//Boolean formula. Result is in +2; 0=false,1=true |
// http://code.google.com/p/php-excel-reader/issues/detail?id=4 |
if (ord($this->data[$spos+8])==1) { |
$this->addcell($row, $column, "TRUE"); |
} else { |
$this->addcell($row, $column, "FALSE"); |
} |
} elseif ((ord($data[$spos+6])==2) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) { |
//Error formula. Error code is in +2; |
} elseif ((ord($data[$spos+6])==3) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) { |
//Formula result is a null string. |
$this->addcell($row, $column, ''); |
} else { |
// result is a number, so first 14 bytes are just like a _NUMBER record |
$tmp = unpack("ddouble", substr($data, $spos + 6, 8)); // It machine machine dependent |
if ($this->isDate($spos)) { |
$numValue = $tmp['double']; |
} |
else { |
$numValue = $this->createNumber($spos); |
} |
$info = $this->_getCellDetails($spos,$numValue,$column); |
$this->addcell($row, $column, $info['string'], $info); |
} |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_BOOLERR: |
$row = ord($data[$spos]) | ord($data[$spos+1])<<8; |
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8; |
$string = ord($data[$spos+6]); |
$this->addcell($row, $column, $string); |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_STRING: |
// http://code.google.com/p/php-excel-reader/issues/detail?id=4 |
if ($version == SPREADSHEET_EXCEL_READER_BIFF8){ |
// Unicode 16 string, like an SST record |
$xpos = $spos; |
$numChars =ord($data[$xpos]) | (ord($data[$xpos+1]) << 8); |
$xpos += 2; |
$optionFlags =ord($data[$xpos]); |
$xpos++; |
$asciiEncoding = (($optionFlags &0x01) == 0) ; |
$extendedString = (($optionFlags & 0x04) != 0); |
// See if string contains formatting information |
$richString = (($optionFlags & 0x08) != 0); |
if ($richString) { |
// Read in the crun |
$formattingRuns =ord($data[$xpos]) | (ord($data[$xpos+1]) << 8); |
$xpos += 2; |
} |
if ($extendedString) { |
// Read in cchExtRst |
$extendedRunLength =$this->_GetInt4d($this->data, $xpos); |
$xpos += 4; |
} |
$len = ($asciiEncoding)?$numChars : $numChars*2; |
$retstr =substr($data, $xpos, $len); |
$xpos += $len; |
$retstr = ($asciiEncoding)? $retstr : $this->_encodeUTF16($retstr); |
} |
elseif ($version == SPREADSHEET_EXCEL_READER_BIFF7){ |
// Simple byte string |
$xpos = $spos; |
$numChars =ord($data[$xpos]) | (ord($data[$xpos+1]) << 8); |
$xpos += 2; |
$retstr =substr($data, $xpos, $numChars); |
} |
$this->addcell($previousRow, $previousCol, $retstr); |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_ROW: |
$row = ord($data[$spos]) | ord($data[$spos+1])<<8; |
$rowInfo = ord($data[$spos + 6]) | ((ord($data[$spos+7]) << 8) & 0x7FFF); |
if (($rowInfo & 0x8000) > 0) { |
$rowHeight = -1; |
} else { |
$rowHeight = $rowInfo & 0x7FFF; |
} |
$rowHidden = (ord($data[$spos + 12]) & 0x20) >> 5; |
$this->rowInfo[$this->sn][$row+1] = Array('height' => $rowHeight / 20, 'hidden'=>$rowHidden ); |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_DBCELL: |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_MULBLANK: |
$row = ord($data[$spos]) | ord($data[$spos+1])<<8; |
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8; |
$cols = ($length / 2) - 3; |
for ($c = 0; $c < $cols; $c++) { |
$xfindex = ord($data[$spos + 4 + ($c * 2)]) | ord($data[$spos + 5 + ($c * 2)])<<8; |
$this->addcell($row, $column + $c, "", array('xfIndex'=>$xfindex)); |
} |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_LABEL: |
$row = ord($data[$spos]) | ord($data[$spos+1])<<8; |
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8; |
$this->addcell($row, $column, substr($data, $spos + 8, ord($data[$spos + 6]) | ord($data[$spos + 7])<<8)); |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_EOF: |
$cont = false; |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_HYPER: |
// Only handle hyperlinks to a URL |
$row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; |
$row2 = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; |
$column = ord($this->data[$spos+4]) | ord($this->data[$spos+5])<<8; |
$column2 = ord($this->data[$spos+6]) | ord($this->data[$spos+7])<<8; |
$linkdata = Array(); |
$flags = ord($this->data[$spos + 28]); |
$udesc = ""; |
$ulink = ""; |
$uloc = 32; |
$linkdata['flags'] = $flags; |
if (($flags & 1) > 0 ) { // is a type we understand |
// is there a description ? |
if (($flags & 0x14) == 0x14 ) { // has a description |
$uloc += 4; |
$descLen = ord($this->data[$spos + 32]) | ord($this->data[$spos + 33]) << 8; |
$udesc = substr($this->data, $spos + $uloc, $descLen * 2); |
$uloc += 2 * $descLen; |
} |
$ulink = $this->read16bitstring($this->data, $spos + $uloc + 20); |
if ($udesc == "") { |
$udesc = $ulink; |
} |
} |
$linkdata['desc'] = $udesc; |
$linkdata['link'] = $this->_encodeUTF16($ulink); |
for ($r=$row; $r<=$row2; $r++) { |
for ($c=$column; $c<=$column2; $c++) { |
$this->sheets[$this->sn]['cellsInfo'][$r+1][$c+1]['hyperlink'] = $linkdata; |
} |
} |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_DEFCOLWIDTH: |
$this->defaultColWidth = ord($data[$spos+4]) | ord($data[$spos+5]) << 8; |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_STANDARDWIDTH: |
$this->standardColWidth = ord($data[$spos+4]) | ord($data[$spos+5]) << 8; |
break; |
case SPREADSHEET_EXCEL_READER_TYPE_COLINFO: |
$colfrom = ord($data[$spos+0]) | ord($data[$spos+1]) << 8; |
$colto = ord($data[$spos+2]) | ord($data[$spos+3]) << 8; |
$cw = ord($data[$spos+4]) | ord($data[$spos+5]) << 8; |
$cxf = ord($data[$spos+6]) | ord($data[$spos+7]) << 8; |
$co = ord($data[$spos+8]); |
for ($coli = $colfrom; $coli <= $colto; $coli++) { |
$this->colInfo[$this->sn][$coli+1] = Array('width' => $cw, 'xf' => $cxf, 'hidden' => ($co & 0x01), 'collapsed' => ($co & 0x1000) >> 12); |
} |
break; |
default: |
break; |
} |
$spos += $length; |
} |
if (!isset($this->sheets[$this->sn]['numRows'])) |
$this->sheets[$this->sn]['numRows'] = $this->sheets[$this->sn]['maxrow']; |
if (!isset($this->sheets[$this->sn]['numCols'])) |
$this->sheets[$this->sn]['numCols'] = $this->sheets[$this->sn]['maxcol']; |
} |
function isDate($spos) { |
$xfindex = ord($this->data[$spos+4]) | ord($this->data[$spos+5]) << 8; |
return ($this->xfRecords[$xfindex]['type'] == 'date'); |
} |
// Get the details for a particular cell |
function _getCellDetails($spos,$numValue,$column) { |
$xfindex = ord($this->data[$spos+4]) | ord($this->data[$spos+5]) << 8; |
$xfrecord = $this->xfRecords[$xfindex]; |
$type = $xfrecord['type']; |
$format = $xfrecord['format']; |
$formatIndex = $xfrecord['formatIndex']; |
$fontIndex = $xfrecord['fontIndex']; |
$formatColor = ""; |
$rectype = ''; |
$string = ''; |
$raw = ''; |
if (isset($this->_columnsFormat[$column + 1])){ |
$format = $this->_columnsFormat[$column + 1]; |
} |
if ($type == 'date') { |
// See http://groups.google.com/group/php-excel-reader-discuss/browse_frm/thread/9c3f9790d12d8e10/f2045c2369ac79de |
$rectype = 'date'; |
// Convert numeric value into a date |
$utcDays = floor($numValue - ($this->nineteenFour ? SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS1904 : SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS)); |
$utcValue = ($utcDays) * SPREADSHEET_EXCEL_READER_MSINADAY; |
$dateinfo = gmgetdate($utcValue); |
$raw = $numValue; |
$fractionalDay = $numValue - floor($numValue) + .0000001; // The .0000001 is to fix for php/excel fractional diffs |
$totalseconds = floor(SPREADSHEET_EXCEL_READER_MSINADAY * $fractionalDay); |
$secs = $totalseconds % 60; |
$totalseconds -= $secs; |
$hours = floor($totalseconds / (60 * 60)); |
$mins = floor($totalseconds / 60) % 60; |
// David Delon : on force du JJ/MM/AAAA |
$format= "d/m/Y"; |
$string = date ($format, mktime($hours, $mins, $secs, $dateinfo["mon"], $dateinfo["mday"], $dateinfo["year"])); |
} else if ($type == 'number') { |
$rectype = 'number'; |
$formatted = $this->_format_value($format, $numValue, $formatIndex); |
$string = $formatted['string']; |
$formatColor = $formatted['formatColor']; |
$raw = $numValue; |
} else{ |
if ($format=="") { |
$format = $this->_defaultFormat; |
} |
$rectype = 'unknown'; |
$formatted = $this->_format_value($format, $numValue, $formatIndex); |
$string = $formatted['string']; |
$formatColor = $formatted['formatColor']; |
$raw = $numValue; |
} |
return array( |
'string'=>$string, |
'raw'=>$raw, |
'rectype'=>$rectype, |
'format'=>$format, |
'formatIndex'=>$formatIndex, |
'fontIndex'=>$fontIndex, |
'formatColor'=>$formatColor, |
'xfIndex'=>$xfindex |
); |
} |
function createNumber($spos) { |
$rknumhigh = $this->_GetInt4d($this->data, $spos + 10); |
$rknumlow = $this->_GetInt4d($this->data, $spos + 6); |
$sign = ($rknumhigh & 0x80000000) >> 31; |
$exp = ($rknumhigh & 0x7ff00000) >> 20; |
$mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); |
$mantissalow1 = ($rknumlow & 0x80000000) >> 31; |
$mantissalow2 = ($rknumlow & 0x7fffffff); |
$value = $mantissa / pow( 2 , (20- ($exp - 1023))); |
if ($mantissalow1 != 0) $value += 1 / pow (2 , (21 - ($exp - 1023))); |
$value += $mantissalow2 / pow (2 , (52 - ($exp - 1023))); |
if ($sign) {$value = -1 * $value;} |
return $value; |
} |
function addcell($row, $col, $string, $info=null) { |
$this->sheets[$this->sn]['maxrow'] = max($this->sheets[$this->sn]['maxrow'], $row + $this->_rowoffset); |
$this->sheets[$this->sn]['maxcol'] = max($this->sheets[$this->sn]['maxcol'], $col + $this->_coloffset); |
$this->sheets[$this->sn]['cells'][$row + $this->_rowoffset][$col + $this->_coloffset] = $string; |
if ($this->store_extended_info && $info) { |
foreach ($info as $key=>$val) { |
$this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset][$key] = $val; |
} |
} |
} |
function _GetIEEE754($rknum) { |
if (($rknum & 0x02) != 0) { |
$value = $rknum >> 2; |
} else { |
//mmp |
// I got my info on IEEE754 encoding from |
// http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html |
// The RK format calls for using only the most significant 30 bits of the |
// 64 bit floating point value. The other 34 bits are assumed to be 0 |
// So, we use the upper 30 bits of $rknum as follows... |
$sign = ($rknum & 0x80000000) >> 31; |
$exp = ($rknum & 0x7ff00000) >> 20; |
$mantissa = (0x100000 | ($rknum & 0x000ffffc)); |
$value = $mantissa / pow( 2 , (20- ($exp - 1023))); |
if ($sign) { |
$value = -1 * $value; |
} |
//end of changes by mmp |
} |
if (($rknum & 0x01) != 0) { |
$value /= 100; |
} |
return $value; |
} |
function _encodeUTF16($string) { |
$result = $string; |
if ($this->_defaultEncoding){ |
switch ($this->_encoderFunction){ |
case 'iconv' : $result = iconv('UTF-16LE', $this->_defaultEncoding, $string); |
break; |
case 'mb_convert_encoding' : $result = mb_convert_encoding($string, $this->_defaultEncoding, 'UTF-16LE' ); |
break; |
} |
} |
return $result; |
} |
function _GetInt4d($data, $pos) { |
$value = ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24); |
if ($value>=4294967294) { |
$value=-2; |
} |
return $value; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/gPoint.php |
---|
New file |
0,0 → 1,534 |
<?php |
/*------------------------------------------------------------------------------ |
** File: gPoint.php |
** Description: PHP class to convert Latitude & Longitude coordinates into |
** UTM & Lambert Conic Conformal Northing/Easting coordinates. |
** Version: 1.3 |
** Author: Brenor Brophy |
** Email: brenor dot brophy at gmail dot com |
** Homepage: brenorbrophy.com |
**------------------------------------------------------------------------------ |
** COPYRIGHT (c) 2005, 2006, 2007, 2008 BRENOR BROPHY |
** |
** The source code included in this package 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. This license can be |
** read at: |
** |
** http://www.opensource.org/licenses/gpl-license.php |
** |
** This program 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. |
**------------------------------------------------------------------------------ |
** |
** Code for datum and UTM conversion was converted from C++ code written by |
** Chuck Gantz (chuck dot gantz at globalstar dot com) from |
** http://www.gpsy.com/gpsinfo/geotoutm/ This URL has many other references to |
** useful information concerning conversion of coordinates. |
** |
** Rev History |
** ----------------------------------------------------------------------------- |
** 1.0 08/25/2005 Initial Release |
** 1.1 05/15/2006 Added software license language to header comments |
** Fixed an error in the convertTMtoLL() method. The latitude |
** calculation had a bunch of variables without $ symbols. |
** Fixed an error in convertLLtoTM() method, The $this-> was |
** missing in front of a couple of variables. Thanks to Bob |
** Robins of Maryland for catching the bugs. |
** 1.2 05/18/2007 Added default of NULL to $LongOrigin arguement in convertTMtoLL() |
** and convertLLtoTM() to eliminate warning messages when the |
** methods are called without a value for $LongOrigin. |
** 1.3 02/21/2008 Fixed a bug in the distanceFrom method, where the input parameters |
** were not being converted to radians prior to calculating the |
** distance. Thanks to Enrico Benco for finding pointing it out. |
*/ |
define ("meter2nm", (1/1852)); |
define ("nm2meter", 1852); |
/*------------------------------------------------------------------------------ |
** class gPoint ... for Geographic Point |
** |
** This class encapsulates the methods for representing a geographic point on the |
** earth in three different coordinate systema. Lat/Long, UTM and Lambert Conic |
** Conformal. |
*/ |
class gPoint |
{ |
/* Reference ellipsoids derived from Peter H. Dana's website- |
** http://www.colorado.edu/geography/gcraft/notes/datum/datum_f.html |
** email: pdana@pdana.com, web page: www.pdana.com |
** |
** Source: |
** Defense Mapping Agency. 1987b. DMA Technical Report: Supplement to Department |
** of Defense World Geodetic System 1984 Technical Report. Part I and II. |
** Washington, DC: Defense Mapping Agency |
*/ |
var $ellipsoid = array(//Ellipsoid name, Equatorial Radius, square of eccentricity |
"Airy" =>array (6377563, 0.00667054), |
"Australian National" =>array (6378160, 0.006694542), |
"Bessel 1841" =>array (6377397, 0.006674372), |
"Bessel 1841 Nambia" =>array (6377484, 0.006674372), |
"Clarke 1866" =>array (6378206, 0.006768658), |
"Clarke 1880" =>array (6378249, 0.006803511), |
"Everest" =>array (6377276, 0.006637847), |
"Fischer 1960 Mercury" =>array (6378166, 0.006693422), |
"Fischer 1968" =>array (6378150, 0.006693422), |
"GRS 1967" =>array (6378160, 0.006694605), |
"GRS 1980" =>array (6378137, 0.00669438), |
"Helmert 1906" =>array (6378200, 0.006693422), |
"Hough" =>array (6378270, 0.00672267), |
"International" =>array (6378388, 0.00672267), |
"Krassovsky" =>array (6378245, 0.006693422), |
"Modified Airy" =>array (6377340, 0.00667054), |
"Modified Everest" =>array (6377304, 0.006637847), |
"Modified Fischer 1960" =>array (6378155, 0.006693422), |
"South American 1969" =>array (6378160, 0.006694542), |
"WGS 60" =>array (6378165, 0.006693422), |
"WGS 66" =>array (6378145, 0.006694542), |
"WGS 72" =>array (6378135, 0.006694318), |
"WGS 84" =>array (6378137, 0.00669438)); |
// Properties |
var $a; // Equatorial Radius |
var $e2; // Square of eccentricity |
var $datum; // Selected datum |
var $Xp, $Yp; // X,Y pixel location |
var $lat, $long; // Latitude & Longitude of the point |
var $utmNorthing, $utmEasting, $utmZone; // UTM Coordinates of the point |
var $lccNorthing, $lccEasting; // Lambert coordinates of the point |
var $falseNorthing, $falseEasting; // Origin coordinates for Lambert Projection |
var $latOfOrigin; // For Lambert Projection |
var $longOfOrigin; // For Lambert Projection |
var $firstStdParallel; // For lambert Projection |
var $secondStdParallel; // For lambert Projection |
// constructor |
function gPoint($datum='WGS 84') // Default datum is WGS 84 |
{ |
$this->a = $this->ellipsoid[$datum][0]; // Set datum Equatorial Radius |
$this->e2 = $this->ellipsoid[$datum][1]; // Set datum Square of eccentricity |
$this->datum = $datum; // Save the datum |
} |
// |
// Set/Get X & Y pixel of the point (used if it is being drawn on an image) |
// |
function setXY($x, $y) |
{ |
$this->Xp = $x; $this->Yp = $y; |
} |
function Xp() { return $this->Xp; } |
function Yp() { return $this->Yp; } |
// |
// Set/Get/Output Longitude & Latitude of the point |
// |
function setLongLat($long, $lat) |
{ |
$this->long = $long; $this->lat = $lat; |
} |
function Lat() { return $this->lat; } |
function Long() { return $this->long; } |
function printLatLong() { printf("Latitude: %1.5f Longitude: %1.5f",$this->lat, $this->long); } |
// |
// Set/Get/Output Universal Transverse Mercator Coordinates |
// |
function setUTM($easting, $northing, $zone='') // Zone is optional |
{ |
$this->utmNorthing = $northing; |
$this->utmEasting = $easting; |
$this->utmZone = $zone; |
} |
function N() { return $this->utmNorthing; } |
function E() { return $this->utmEasting; } |
function Z() { return $this->utmZone; } |
function printUTM() { print( "Northing: ".(int)$this->utmNorthing.", Easting: ".(int)$this->utmEasting.", Zone: ".$this->utmZone); } |
// |
// Set/Get/Output Lambert Conic Conformal Coordinates |
// |
function setLambert($easting, $northing) |
{ |
$this->lccNorthing = $northing; |
$this->lccEasting = $easting; |
} |
function lccN() { return $this->lccNorthing; } |
function lccE() { return $this->lccEasting; } |
function printLambert() { print( "Northing: ".(int)$this->lccNorthing.", Easting: ".(int)$this->lccEasting); } |
//------------------------------------------------------------------------------ |
// |
// Convert Longitude/Latitude to UTM |
// |
// Equations from USGS Bulletin 1532 |
// East Longitudes are positive, West longitudes are negative. |
// North latitudes are positive, South latitudes are negative |
// Lat and Long are in decimal degrees |
// Written by Chuck Gantz- chuck dot gantz at globalstar dot com, converted to PHP by |
// Brenor Brophy, brenor dot brophy at gmail dot com |
// |
// UTM coordinates are useful when dealing with paper maps. Basically the |
// map will can cover a single UTM zone which is 6 degrees on longitude. |
// So you really don't care about an object crossing two zones. You just get a |
// second map of the other zone. However, if you happen to live in a place that |
// straddles two zones (For example the Santa Babara area in CA straddles zone 10 |
// and zone 11) Then it can become a real pain having to have two maps all the time. |
// So relatively small parts of the world (like say California) create their own |
// version of UTM coordinates that are adjusted to conver the whole area of interest |
// on a single map. These are called state grids. The projection system is the |
// usually same as UTM (i.e. Transverse Mercator), but the central meridian |
// aka Longitude of Origin is selected to suit the logitude of the area being |
// mapped (like being moved to the central meridian of the area) and the grid |
// may cover more than the 6 degrees of lingitude found on a UTM map. Areas |
// that are wide rather than long - think Montana as an example. May still |
// have to have a couple of maps to cover the whole state because TM projection |
// looses accuracy as you move further away from the Longitude of Origin, 15 degrees |
// is usually the limit. |
// |
// Now, in the case where we want to generate electronic maps that may be |
// placed pretty much anywhere on the globe we really don't to deal with the |
// issue of UTM zones in our coordinate system. We would really just like a |
// grid that is fully contigious over the area of the map we are drawing. Similiar |
// to the state grid, but local to the area we are interested in. I call this |
// Local Transverse Mercator and I have modified the function below to also |
// make this conversion. If you pass a Longitude value to the function as $LongOrigin |
// then that is the Longitude of Origin that will be used for the projection. |
// Easting coordinates will be returned (in meters) relative to that line of |
// longitude - So an Easting coordinate for a point located East of the longitude |
// of origin will be a positive value in meters, an Easting coordinate for a point |
// West of the longitude of Origin will have a negative value in meters. Northings |
// will always be returned in meters from the equator same as the UTM system. The |
// UTMZone value will be valid for Long/Lat given - thought it is not meaningful |
// in the context of Local TM. If a NULL value is passed for $LongOrigin |
// then the standard UTM coordinates are calculated. |
// |
function convertLLtoTM($LongOrigin = NULL) |
{ |
$k0 = 0.9996; |
$falseEasting = 0.0; |
//Make sure the longitude is between -180.00 .. 179.9 |
$LongTemp = ($this->long+180)-(integer)(($this->long+180)/360)*360-180; // -180.00 .. 179.9; |
$LatRad = deg2rad($this->lat); |
$LongRad = deg2rad($LongTemp); |
if (!$LongOrigin) |
{ // Do a standard UTM conversion - so findout what zone the point is in |
$ZoneNumber = (integer)(($LongTemp + 180)/6) + 1; |
// Special zone for South Norway |
if( $this->lat >= 56.0 && $this->lat < 64.0 && $LongTemp >= 3.0 && $LongTemp < 12.0 ) // Fixed 1.1 |
$ZoneNumber = 32; |
// Special zones for Svalbard |
if( $this->lat >= 72.0 && $this->lat < 84.0 ) |
{ |
if( $LongTemp >= 0.0 && $LongTemp < 9.0 ) $ZoneNumber = 31; |
else if( $LongTemp >= 9.0 && $LongTemp < 21.0 ) $ZoneNumber = 33; |
else if( $LongTemp >= 21.0 && $LongTemp < 33.0 ) $ZoneNumber = 35; |
else if( $LongTemp >= 33.0 && $LongTemp < 42.0 ) $ZoneNumber = 37; |
} |
$LongOrigin = ($ZoneNumber - 1)*6 - 180 + 3; //+3 puts origin in middle of zone |
//compute the UTM Zone from the latitude and longitude |
$this->utmZone = sprintf("%d%s", $ZoneNumber, $this->UTMLetterDesignator()); |
// We also need to set the false Easting value adjust the UTM easting coordinate |
$falseEasting = 500000.0; |
} |
$LongOriginRad = deg2rad($LongOrigin); |
$eccPrimeSquared = ($this->e2)/(1-$this->e2); |
$N = $this->a/sqrt(1-$this->e2*sin($LatRad)*sin($LatRad)); |
$T = tan($LatRad)*tan($LatRad); |
$C = $eccPrimeSquared*cos($LatRad)*cos($LatRad); |
$A = cos($LatRad)*($LongRad-$LongOriginRad); |
$M = $this->a*((1 - $this->e2/4 - 3*$this->e2*$this->e2/64 - 5*$this->e2*$this->e2*$this->e2/256)*$LatRad |
- (3*$this->e2/8 + 3*$this->e2*$this->e2/32 + 45*$this->e2*$this->e2*$this->e2/1024)*sin(2*$LatRad) |
+ (15*$this->e2*$this->e2/256 + 45*$this->e2*$this->e2*$this->e2/1024)*sin(4*$LatRad) |
- (35*$this->e2*$this->e2*$this->e2/3072)*sin(6*$LatRad)); |
$this->utmEasting = ($k0*$N*($A+(1-$T+$C)*$A*$A*$A/6 |
+ (5-18*$T+$T*$T+72*$C-58*$eccPrimeSquared)*$A*$A*$A*$A*$A/120) |
+ $falseEasting); |
$this->utmNorthing = ($k0*($M+$N*tan($LatRad)*($A*$A/2+(5-$T+9*$C+4*$C*$C)*$A*$A*$A*$A/24 |
+ (61-58*$T+$T*$T+600*$C-330*$eccPrimeSquared)*$A*$A*$A*$A*$A*$A/720))); |
if($this->lat < 0) |
$this->utmNorthing += 10000000.0; //10000000 meter offset for southern hemisphere |
} |
// |
// This routine determines the correct UTM letter designator for the given latitude |
// returns 'Z' if latitude is outside the UTM limits of 84N to 80S |
// Written by Chuck Gantz- chuck dot gantz at globalstar dot com, converted to PHP by |
// Brenor Brophy, brenor dot brophy at gmail dot com |
// |
function UTMLetterDesignator() |
{ |
if((84 >= $this->lat) && ($this->lat >= 72)) $LetterDesignator = 'X'; |
else if((72 > $this->lat) && ($this->lat >= 64)) $LetterDesignator = 'W'; |
else if((64 > $this->lat) && ($this->lat >= 56)) $LetterDesignator = 'V'; |
else if((56 > $this->lat) && ($this->lat >= 48)) $LetterDesignator = 'U'; |
else if((48 > $this->lat) && ($this->lat >= 40)) $LetterDesignator = 'T'; |
else if((40 > $this->lat) && ($this->lat >= 32)) $LetterDesignator = 'S'; |
else if((32 > $this->lat) && ($this->lat >= 24)) $LetterDesignator = 'R'; |
else if((24 > $this->lat) && ($this->lat >= 16)) $LetterDesignator = 'Q'; |
else if((16 > $this->lat) && ($this->lat >= 8)) $LetterDesignator = 'P'; |
else if(( 8 > $this->lat) && ($this->lat >= 0)) $LetterDesignator = 'N'; |
else if(( 0 > $this->lat) && ($this->lat >= -8)) $LetterDesignator = 'M'; |
else if((-8 > $this->lat) && ($this->lat >= -16)) $LetterDesignator = 'L'; |
else if((-16 > $this->lat) && ($this->lat >= -24)) $LetterDesignator = 'K'; |
else if((-24 > $this->lat) && ($this->lat >= -32)) $LetterDesignator = 'J'; |
else if((-32 > $this->lat) && ($this->lat >= -40)) $LetterDesignator = 'H'; |
else if((-40 > $this->lat) && ($this->lat >= -48)) $LetterDesignator = 'G'; |
else if((-48 > $this->lat) && ($this->lat >= -56)) $LetterDesignator = 'F'; |
else if((-56 > $this->lat) && ($this->lat >= -64)) $LetterDesignator = 'E'; |
else if((-64 > $this->lat) && ($this->lat >= -72)) $LetterDesignator = 'D'; |
else if((-72 > $this->lat) && ($this->lat >= -80)) $LetterDesignator = 'C'; |
else $LetterDesignator = 'Z'; //This is here as an error flag to show that the Latitude is outside the UTM limits |
return($LetterDesignator); |
} |
//------------------------------------------------------------------------------ |
// |
// Convert UTM to Longitude/Latitude |
// |
// Equations from USGS Bulletin 1532 |
// East Longitudes are positive, West longitudes are negative. |
// North latitudes are positive, South latitudes are negative |
// Lat and Long are in decimal degrees. |
// Written by Chuck Gantz- chuck dot gantz at globalstar dot com, converted to PHP by |
// Brenor Brophy, brenor dot brophy at gmail dot com |
// |
// If a value is passed for $LongOrigin then the function assumes that |
// a Local (to the Longitude of Origin passed in) Transverse Mercator |
// coordinates is to be converted - not a UTM coordinate. This is the |
// complementary function to the previous one. The function cannot |
// tell if a set of Northing/Easting coordinates are in the North |
// or South hemesphere - they just give distance from the equator not |
// direction - so only northern hemesphere lat/long coordinates are returned. |
// If you live south of the equator there is a note later in the code |
// explaining how to have it just return southern hemesphere lat/longs. |
// |
function convertTMtoLL($LongOrigin = NULL) |
{ |
$k0 = 0.9996; |
$e1 = (1-sqrt(1-$this->e2))/(1+sqrt(1-$this->e2)); |
$falseEasting = 0.0; |
$y = $this->utmNorthing; |
if (!$LongOrigin) |
{ // It is a UTM coordinate we want to convert |
sscanf($this->utmZone,"%d%s",$ZoneNumber,$ZoneLetter); |
if($ZoneLetter >= 'N') |
$NorthernHemisphere = 1;//point is in northern hemisphere |
else |
{ |
$NorthernHemisphere = 0;//point is in southern hemisphere |
$y -= 10000000.0;//remove 10,000,000 meter offset used for southern hemisphere |
} |
$LongOrigin = ($ZoneNumber - 1)*6 - 180 + 3; //+3 puts origin in middle of zone |
$falseEasting = 500000.0; |
} |
// $y -= 10000000.0; // Uncomment line to make LOCAL coordinates return southern hemesphere Lat/Long |
$x = $this->utmEasting - $falseEasting; //remove 500,000 meter offset for longitude |
$eccPrimeSquared = ($this->e2)/(1-$this->e2); |
$M = $y / $k0; |
$mu = $M/($this->a*(1-$this->e2/4-3*$this->e2*$this->e2/64-5*$this->e2*$this->e2*$this->e2/256)); |
$phi1Rad = $mu + (3*$e1/2-27*$e1*$e1*$e1/32)*sin(2*$mu) |
+ (21*$e1*$e1/16-55*$e1*$e1*$e1*$e1/32)*sin(4*$mu) |
+(151*$e1*$e1*$e1/96)*sin(6*$mu); |
$phi1 = rad2deg($phi1Rad); |
$N1 = $this->a/sqrt(1-$this->e2*sin($phi1Rad)*sin($phi1Rad)); |
$T1 = tan($phi1Rad)*tan($phi1Rad); |
$C1 = $eccPrimeSquared*cos($phi1Rad)*cos($phi1Rad); |
$R1 = $this->a*(1-$this->e2)/pow(1-$this->e2*sin($phi1Rad)*sin($phi1Rad), 1.5); |
$D = $x/($N1*$k0); |
$tlat = $phi1Rad - ($N1*tan($phi1Rad)/$R1)*($D*$D/2-(5+3*$T1+10*$C1-4*$C1*$C1-9*$eccPrimeSquared)*$D*$D*$D*$D/24 |
+(61+90*$T1+298*$C1+45*$T1*$T1-252*$eccPrimeSquared-3*$C1*$C1)*$D*$D*$D*$D*$D*$D/720); // fixed in 1.1 |
$this->lat = rad2deg($tlat); |
$tlong = ($D-(1+2*$T1+$C1)*$D*$D*$D/6+(5-2*$C1+28*$T1-3*$C1*$C1+8*$eccPrimeSquared+24*$T1*$T1) |
*$D*$D*$D*$D*$D/120)/cos($phi1Rad); |
$this->long = $LongOrigin + rad2deg($tlong); |
} |
//------------------------------------------------------------------------------ |
// Configure a Lambert Conic Conformal Projection |
// |
// falseEasting & falseNorthing are just an offset in meters added to the final |
// coordinate calculated. |
// |
// longOfOrigin & LatOfOrigin are the "center" latitiude and longitude of the |
// area being projected. All coordinates will be calculated in meters relative |
// to this point on the earth. |
// |
// firstStdParallel & secondStdParallel are the two lines of longitude (that |
// is they run east-west) that define where the "cone" intersects the earth. |
// Simply put they should bracket the area being projected. |
// |
// google is your friend to find out more |
// |
function configLambertProjection ($falseEasting, $falseNorthing, |
$longOfOrigin, $latOfOrigin, |
$firstStdParallel, $secondStdParallel) |
{ |
$this->falseEasting = $falseEasting; |
$this->falseNorthing = $falseNorthing; |
$this->longOfOrigin = $longOfOrigin; |
$this->latOfOrigin = $latOfOrigin; |
$this->firstStdParallel = $firstStdParallel; |
$this->secondStdParallel = $secondStdParallel; |
} |
//------------------------------------------------------------------------------ |
// |
// Convert Longitude/Latitude to Lambert Conic Easting/Northing |
// |
// This routine will convert a Latitude/Longitude coordinate to an Northing/ |
// Easting coordinate on a Lambert Conic Projection. The configLambertProjection() |
// function should have been called prior to this one to setup the specific |
// parameters for the projection. The Northing/Easting parameters calculated are |
// in meters (because the datum used is in meters) and are relative to the |
// falseNorthing/falseEasting coordinate. Which in turn is relative to the |
// Lat/Long of origin The formula were obtained from URL: |
// http://www.ihsenergy.com/epsg/guid7_2.html. |
// Code was written by Brenor Brophy, brenor dot brophy at gmail dot com |
// |
function convertLLtoLCC() |
{ |
$e = sqrt($this->e2); |
$phi = deg2rad($this->lat); // Latitude to convert |
$phi1 = deg2rad($this->firstStdParallel); // Latitude of 1st std parallel |
$phi2 = deg2rad($this->secondStdParallel); // Latitude of 2nd std parallel |
$lamda = deg2rad($this->long); // Lonitude to convert |
$phio = deg2rad($this->latOfOrigin); // Latitude of Origin |
$lamdao = deg2rad($this->longOfOrigin); // Longitude of Origin |
$m1 = cos($phi1) / sqrt(( 1 - $this->e2*sin($phi1)*sin($phi1))); |
$m2 = cos($phi2) / sqrt(( 1 - $this->e2*sin($phi2)*sin($phi2))); |
$t1 = tan((pi()/4)-($phi1/2)) / pow(( ( 1 - $e*sin($phi1) ) / ( 1 + $e*sin($phi1) )),$e/2); |
$t2 = tan((pi()/4)-($phi2/2)) / pow(( ( 1 - $e*sin($phi2) ) / ( 1 + $e*sin($phi2) )),$e/2); |
$to = tan((pi()/4)-($phio/2)) / pow(( ( 1 - $e*sin($phio) ) / ( 1 + $e*sin($phio) )),$e/2); |
$t = tan((pi()/4)-($phi /2)) / pow(( ( 1 - $e*sin($phi ) ) / ( 1 + $e*sin($phi ) )),$e/2); |
$n = (log($m1)-log($m2)) / (log($t1)-log($t2)); |
$F = $m1/($n*pow($t1,$n)); |
$rf = $this->a*$F*pow($to,$n); |
$r = $this->a*$F*pow($t,$n); |
$theta = $n*($lamda - $lamdao); |
$this->lccEasting = $this->falseEasting + $r*sin($theta); |
$this->lccNorthing = $this->falseNorthing + $rf - $r*cos($theta); |
} |
//------------------------------------------------------------------------------ |
// |
// Convert Easting/Northing on a Lambert Conic projection to Longitude/Latitude |
// |
// This routine will convert a Lambert Northing/Easting coordinate to an |
// Latitude/Longitude coordinate. The configLambertProjection() function should |
// have been called prior to this one to setup the specific parameters for the |
// projection. The Northing/Easting parameters are in meters (because the datum |
// used is in meters) and are relative to the falseNorthing/falseEasting |
// coordinate. Which in turn is relative to the Lat/Long of origin The formula |
// were obtained from URL http://www.ihsenergy.com/epsg/guid7_2.html. Code |
// was written by Brenor Brophy, brenor dot brophy at gmail dot com |
// |
function convertLCCtoLL() |
{ |
$e = sqrt($this->e2); |
$phi1 = deg2rad($this->firstStdParallel); // Latitude of 1st std parallel |
$phi2 = deg2rad($this->secondStdParallel); // Latitude of 2nd std parallel |
$phio = deg2rad($this->latOfOrigin); // Latitude of Origin |
$lamdao = deg2rad($this->longOfOrigin); // Longitude of Origin |
$E = $this->lccEasting; |
$N = $this->lccNorthing; |
$Ef = $this->falseEasting; |
$Nf = $this->falseNorthing; |
$m1 = cos($phi1) / sqrt(( 1 - $this->e2*sin($phi1)*sin($phi1))); |
$m2 = cos($phi2) / sqrt(( 1 - $this->e2*sin($phi2)*sin($phi2))); |
$t1 = tan((pi()/4)-($phi1/2)) / pow(( ( 1 - $e*sin($phi1) ) / ( 1 + $e*sin($phi1) )),$e/2); |
$t2 = tan((pi()/4)-($phi2/2)) / pow(( ( 1 - $e*sin($phi2) ) / ( 1 + $e*sin($phi2) )),$e/2); |
$to = tan((pi()/4)-($phio/2)) / pow(( ( 1 - $e*sin($phio) ) / ( 1 + $e*sin($phio) )),$e/2); |
$n = (log($m1)-log($m2)) / (log($t1)-log($t2)); |
$F = $m1/($n*pow($t1,$n)); |
$rf = $this->a*$F*pow($to,$n); |
$r_ = sqrt( pow(($E-$Ef),2) + pow(($rf-($N-$Nf)),2) ); |
$t_ = pow($r_/($this->a*$F),(1/$n)); |
$theta_ = atan(($E-$Ef)/($rf-($N-$Nf))); |
$lamda = $theta_/$n + $lamdao; |
$phi0 = (pi()/2) - 2*atan($t_); |
$phi1 = (pi()/2) - 2*atan($t_*pow(((1-$e*sin($phi0))/(1+$e*sin($phi0))),$e/2)); |
$phi2 = (pi()/2) - 2*atan($t_*pow(((1-$e*sin($phi1))/(1+$e*sin($phi1))),$e/2)); |
$phi = (pi()/2) - 2*atan($t_*pow(((1-$e*sin($phi2))/(1+$e*sin($phi2))),$e/2)); |
$this->lat = rad2deg($phi); |
$this->long = rad2deg($lamda); |
} |
//------------------------------------------------------------------------------ |
// This is a useful function that returns the Great Circle distance from the |
// gPoint to another Long/Lat coordinate |
// |
// Result is returned as meters |
// |
function distanceFrom($lon1, $lat1) |
{ |
$lon1 = deg2rad($lon1); $lat1 = deg2rad($lat1); // Added in 1.3 |
$lon2 = deg2rad($this->Long()); $lat2 = deg2rad($this->Lat()); |
$theta = $lon2 - $lon1; |
$dist = acos(sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($theta)); |
// Alternative formula supposed to be more accurate for short distances |
// $dist = 2*asin(sqrt( pow(sin(($lat1-$lat2)/2),2) + cos($lat1)*cos($lat2)*pow(sin(($lon1-$lon2)/2),2))); |
return ( $dist * 6366710 ); // from http://williams.best.vwh.net/avform.htm#GCF |
} |
//------------------------------------------------------------------------------ |
// This function also calculates the distance between two points. In this case |
// it just uses Pythagoras's theorm using TM coordinates. |
// |
function distanceFromTM(&$pt) |
{ |
$E1 = $pt->E(); $N1 = $pt->N(); |
$E2 = $this->E(); $N2 = $this->N(); |
$dist = sqrt(pow(($E1-$E2),2)+pow(($N1-$N2),2)); |
return $dist; |
} |
//------------------------------------------------------------------------------ |
// This function geo-references a geoPoint to a given map. This means that it |
// calculates the x,y pixel coordinate that coresponds to the Lat/Long value of |
// the geoPoint. The calculation is done using the Transverse Mercator(TM) |
// coordinates of the gPoint with respect to the TM coordinates of the center |
// point of the map. So this only makes sense if you are using Local TM |
// projection. |
// |
// $rX & $rY are the pixel coordinates that corespond to the Northing/Easting |
// ($rE/$rN) coordinate it is to this coordinate that the point will be |
// geo-referenced. The $LongOrigin is needed to make sure the Easting/Northing |
// coordinates of the point are correctly converted. |
// |
function gRef($rX, $rY, $rE, $rN, $Scale, $LongOrigin) |
{ |
$this->convertLLtoTM($LongOrigin); |
$x = (($this->E() - $rE) / $Scale) // The easting in meters times the scale to get pixels |
// is relative to the center of the image so adjust to |
+ ($rX); // the left coordinate. |
$y = $rY - // Adjust to bottom coordinate. |
(($rN - $this->N()) / $Scale); // The northing in meters |
// relative to the equator. Subtract center point northing |
// to get relative to image center and convert meters to pixels |
$this->setXY((int)$x,(int)$y); // Save the geo-referenced result. |
} |
} // end of class gPoint |
?> |
/branches/v1.6-croc/jrest/lib/RechercheInfosTaxon.php |
---|
New file |
0,0 → 1,423 |
<?php |
/** |
* PHP Version 5 |
* |
* @category PHP |
* @package jrest |
* @author David Delon <david@tela-botania.org> |
* @author Aurélien Peronnet <aurelien@tela-botania.org> |
* @copyright 2010 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @version SVN: <svn_id> |
* @link /doc/jrest/ |
*/ |
/** |
* |
* Classe de recherche d'informations sur un taxon donné |
* lors de l'évolution d'eflore, devrait être remplacée par |
* un appel aux nouveaux web services |
*/ |
class RechercheInfosTaxon extends Cel { |
public function RechercheInfosTaxon($config) { |
parent::__construct($config); |
// Connection à la base de données spécifique eflore |
$this->bdd = $this->connecterPDO($this->config, 'eflore'); |
} |
public function rechercherGenreEspeceSurPrefixe($genre = null, $espece = null) { |
$liste_genre_espece = array(); |
$requete_recherche = ''; |
// Genre et Espece |
if ($espece != null && $genre != null) { |
if (strlen($espece) > 0 ) { |
$espece=preg_replace('/\*+/','%',$espece); |
$requete_recherche = "SELECT DISTINCT en_nom_genre, en_epithete_espece, en_nom_supra_generique, en_epithete_infra_generique,". |
" auteur_bex.enaia_intitule_abrege AS abreviation_auteur_basio_ex ". |
" , auteur_b.enaia_intitule_abrege AS abreviation_auteur_basio ". |
" , auteur_mex.enaia_intitule_abrege AS abreviation_auteur_modif_ex ". |
" , auteur_m.enaia_intitule_abrege AS abreviation_auteur_modif ". |
" , en_epithete_espece, en_epithete_infra_specifique, enrg_abreviation_rang, en_id_nom, esn_ce_statut" . |
" FROM eflore_nom, eflore_nom_rang, " . |
" eflore_naturaliste_intitule_abreviation AS auteur_bex ". |
" , eflore_naturaliste_intitule_abreviation AS auteur_b ". |
" , eflore_naturaliste_intitule_abreviation AS auteur_mex ". |
" , eflore_naturaliste_intitule_abreviation AS auteur_m ". |
" , eflore_selection_nom". |
" WHERE en_id_version_projet_nom = '25' AND en_nom_genre LIKE ".$this->proteger($genre.'%'). |
" AND en_ce_rang > 160 " . |
" AND en_epithete_espece like ".$this->proteger($espece.'%')." AND en_ce_rang = enrg_id_rang " . |
" AND en_ce_auteur_basio_ex = auteur_bex.enaia_id_intitule_naturaliste_abrege ". |
" AND en_ce_auteur_basio = auteur_b.enaia_id_intitule_naturaliste_abrege ". |
" AND en_ce_auteur_modif_ex = auteur_mex.enaia_id_intitule_naturaliste_abrege ". |
" AND en_ce_auteur_modif = auteur_m.enaia_id_intitule_naturaliste_abrege ". |
" AND esn_id_version_projet_taxon=en_id_version_projet_nom " . |
" AND esn_id_nom= en_id_nom ". |
" ORDER BY esn_ce_statut, en_ce_rang, en_epithete_espece, en_nom_genre LIMIT 50"; |
} |
} |
else { |
if ($genre != null) { |
$genre=preg_replace('/\*+/','%',$genre); |
//TODO: comprendre pourquoi à l'origine il y avait : (strlen($genre) >= 1) /*&& ($genre != '%') |
// voir avec david |
if ((strlen($genre) >= 1)) { |
$requete_recherche = "SELECT DISTINCT en_nom_genre, en_id_nom, 0 as esn_ce_statut FROM eflore_nom WHERE en_id_version_projet_nom = '25'" . |
"AND en_ce_rang = 160 " . |
"AND en_nom_genre LIKE ".$this->proteger($genre.'%')." ORDER BY esn_ce_statut, en_nom_genre LIMIT 50"; |
} |
} |
} |
if ($requete_recherche != '') { |
$resultat_recherche = $this->executerRequete($requete_recherche); |
if (is_array($resultat_recherche)) { |
foreach ($resultat_recherche as $ligne) { |
$liste_genre_espece[] = array($this->formaterNom($ligne), |
$ligne['en_id_nom'], |
$ligne['esn_ce_statut'] |
); |
} |
} |
} |
return $liste_genre_espece; |
} |
function rechercherInformationsComplementairesSurNumNom($numNom) { |
$resultat_infos_complementaires = $this->effectuerRequeteInfosComplementairesSurNumNom($numNom); |
// Nom retenu, Num Nomen nom retenu, Num Taxon, Famille |
$value=array('Nom_Retenu'=>"",'Num_Nom_Retenu'=>"0",'Num_Taxon'=>"0",'Famille'=>""); |
if (is_array($resultat_infos_complementaires)) { |
foreach ($resultat_infos_complementaires as $row) { |
$fam=$this->rechercherFamille($row['esn_id_taxon']); |
while (($fam['en_ce_rang']!='fin') && ($fam['en_ce_rang'] !=120)) { |
$fam=$this->rechercherFamille($fam['etr_id_taxon_2']); |
} |
if ($fam['en_ce_rang']==120) { |
$famille=$fam['en_nom_supra_generique']; |
} |
else { |
$famille="Famille inconnue"; |
} |
$value=array('Nom_Retenu'=>$this->formaterNom($row),'Num_Nom_Retenu'=>$row['esn_id_nom'],'Num_Taxon'=>$row['esn_id_taxon'],'Famille'=>$famille); |
} |
} |
return $value; |
} |
public function effectuerRequeteInfosComplementairesEtFormaterNom($numNom) { |
$resultat_infos_complementaires = $this->effectuerRequeteInfosComplementairesSurNumNom($numNom); |
$retour_infos_complementaires = array(); |
foreach ($resultat_infos_complementaires as $info) { |
$retour_infos_complementaires=array(($this->formaterNom($info))); |
} |
return $retour_infos_complementaires; |
} |
public function effectuerRequeteInfosComplementairesSurNumNom($numNom) { |
$requete_infos_complementaires = "SELECT DISTINCT en_nom_genre, en_epithete_espece, en_nom_supra_generique, en_epithete_infra_generique,". |
" auteur_bex.enaia_intitule_abrege AS abreviation_auteur_basio_ex ". |
" , auteur_b.enaia_intitule_abrege AS abreviation_auteur_basio ". |
" , auteur_mex.enaia_intitule_abrege AS abreviation_auteur_modif_ex ". |
" , auteur_m.enaia_intitule_abrege AS abreviation_auteur_modif ". |
" , en_epithete_espece, en_epithete_infra_specifique, enrg_abreviation_rang, b.esn_id_taxon, b.esn_id_nom" . |
" FROM eflore_nom, eflore_nom_rang," . |
" eflore_naturaliste_intitule_abreviation AS auteur_bex ". |
" , eflore_naturaliste_intitule_abreviation AS auteur_b ". |
" , eflore_naturaliste_intitule_abreviation AS auteur_mex ". |
" , eflore_naturaliste_intitule_abreviation AS auteur_m ". |
" ,eflore_selection_nom a, eflore_selection_nom b". |
" WHERE a.esn_id_nom= ".$this->proteger($numNom). |
" AND a.esn_id_version_projet_taxon = 25 ". |
" AND a.esn_id_taxon=b.esn_id_taxon ". |
" AND b.esn_ce_statut=3 ". |
" AND a.esn_id_version_projet_taxon=b.esn_id_version_projet_taxon" . |
" AND en_ce_rang = enrg_id_rang" . |
" AND en_id_nom = b.esn_id_nom" . |
" AND en_ce_auteur_basio_ex = auteur_bex.enaia_id_intitule_naturaliste_abrege ". |
" AND en_ce_auteur_basio = auteur_b.enaia_id_intitule_naturaliste_abrege ". |
" AND en_ce_auteur_modif_ex = auteur_mex.enaia_id_intitule_naturaliste_abrege ". |
" AND en_ce_auteur_modif = auteur_m.enaia_id_intitule_naturaliste_abrege ". |
" AND a.esn_id_version_projet_taxon=en_id_version_projet_nom "; |
$resultat_infos_complementaires = $this->executerRequete($requete_infos_complementaires); |
return $resultat_infos_complementaires; |
} |
public function effectuerRequeteInfosComplementairesSurNumTax($numTax) { |
$requete_infos_complementaires = "SELECT DISTINCT en_nom_genre, en_epithete_espece, en_nom_supra_generique, en_epithete_infra_generique,". |
" auteur_bex.enaia_intitule_abrege AS abreviation_auteur_basio_ex ". |
" , auteur_b.enaia_intitule_abrege AS abreviation_auteur_basio ". |
" , auteur_mex.enaia_intitule_abrege AS abreviation_auteur_modif_ex ". |
" , auteur_m.enaia_intitule_abrege AS abreviation_auteur_modif ". |
" , en_epithete_espece, en_epithete_infra_specifique, enrg_abreviation_rang, en_id_nom" . |
" FROM eflore_nom, eflore_nom_rang," . |
" eflore_naturaliste_intitule_abreviation AS auteur_bex ". |
" , eflore_naturaliste_intitule_abreviation AS auteur_b ". |
" , eflore_naturaliste_intitule_abreviation AS auteur_mex ". |
" , eflore_naturaliste_intitule_abreviation AS auteur_m ". |
" , eflore_selection_nom ". |
" WHERE esn_id_taxon = '".$numTax. "'". |
" AND esn_id_version_projet_taxon = 25 ". |
" AND esn_ce_statut=3 ". |
" AND en_id_nom = esn_id_nom" . |
" AND en_ce_rang = enrg_id_rang" . |
" AND en_ce_auteur_basio_ex = auteur_bex.enaia_id_intitule_naturaliste_abrege ". |
" AND en_ce_auteur_basio = auteur_b.enaia_id_intitule_naturaliste_abrege ". |
" AND en_ce_auteur_modif_ex = auteur_mex.enaia_id_intitule_naturaliste_abrege ". |
" AND en_ce_auteur_modif = auteur_m.enaia_id_intitule_naturaliste_abrege ". |
" AND esn_id_version_projet_taxon=en_id_version_projet_nom "; |
$resultat_infos_complementaires = $this->executerRequete($requete_infos_complementaires); |
return $resultat_infos_complementaires; |
} |
public function rechercherInformationsComplementairesSurNom($nom_saisi) { |
$value = array(); |
if ($nom_saisi != null && $nom_saisi != "") { |
$requete_infos_comp_sur_nom = 'SELECT * FROM eflore_nom_intitule '. |
'WHERE eni_id_categorie_format = 3 AND '. |
'eni_id_version_projet_nom = 25 AND '. |
'(eni_id_valeur_format = 3 OR eni_id_valeur_format = 4) AND '. |
'eni_intitule_nom LIKE "'.$nom_saisi.'%" '. |
'ORDER BY LENGTH(eni_intitule_nom)'; |
$resultat_infos_comp_sur_nom = $this->executerRequete($requete_infos_comp_sur_nom); |
if (is_array($resultat_infos_comp_sur_nom)) { |
foreach ($resultat_infos_comp_sur_nom as $ligne) { |
$value[]=array($ligne['eni_id_nom'], $ligne['eni_intitule_nom']); |
} |
} |
} |
return $value; |
} |
public function rechercherFamille($taxon) { |
$row = array(); |
$requete_famille = "SELECT DISTINCT en_ce_rang, etr_id_taxon_2, en_id_nom, en_nom_supra_generique ". |
" FROM eflore_taxon_relation, ". |
" eflore_selection_nom, ". |
" eflore_nom ". |
" WHERE etr_id_taxon_1 = ".$taxon. |
" AND etr_id_version_projet_taxon_1 = 25 ". |
" AND etr_id_categorie_taxon = 3 ". |
" AND etr_id_valeur_taxon = 3 ". |
" AND esn_id_taxon = etr_id_taxon_2 ". |
" AND esn_ce_statut = 3 ". |
" AND esn_id_version_projet_taxon = etr_id_version_projet_taxon_1 ". |
" AND en_id_nom = esn_id_nom ". |
" AND esn_id_version_projet_taxon=en_id_version_projet_nom "; |
$resultat_recherche_famille = $this->executerRequete($requete_famille); |
if (!is_array($resultat_recherche_famille) || count($resultat_recherche_famille) == 0) { |
$resultat_recherche_famille = array('en_ce_rang' => 'fin'); |
} else { |
$resultat_recherche_famille = $resultat_recherche_famille[0]; |
} |
return $resultat_recherche_famille; |
} |
public function rechercherNumTaxSurNumNom($num_nom) { |
$requete_num_tax = "SELECT DISTINCT b.esn_id_taxon FROM eflore_nom, eflore_nom_rang," . |
" eflore_selection_nom a, eflore_selection_nom b". |
" WHERE a.esn_id_nom= ".$this->proteger($num_nom). |
" AND a.esn_id_version_projet_taxon = 25 ". |
" AND a.esn_id_taxon=b.esn_id_taxon ". |
" AND b.esn_ce_statut=3 ". |
" AND a.esn_id_version_projet_taxon=b.esn_id_version_projet_taxon" . |
" AND en_ce_rang = enrg_id_rang" . |
" AND en_id_nom = b.esn_id_nom" . |
" AND a.esn_id_version_projet_taxon=en_id_version_projet_nom "; |
$res_num_nom = $this->executerRequete($requete_num_tax); |
$nt = null; |
if (is_array($res_num_nom) && count($res_num_nom) > 0) { |
$nt=$res_num_nom[0]['esn_id_taxon']; |
} |
return $nt; |
} |
public function taxonEstPresentDansDepartement($num_taxon,$code_departement) { |
$requete_presence_taxon = "SELECT ecd_ce_taxon FROM eflore_zg, eflore_chorologie_donnee ". |
"WHERE ecd_ce_taxon = ".$this->proteger($num_taxon)." ". |
"AND ezg_code = ".$this->proteger($code_departement)." ". |
"AND ecd_ce_zone_geo = ezg_id_zone_geo ". |
"AND ezg_id_projet_zg = ecd_ce_version_projet_zg ". |
"AND ecd_ce_version_projet_taxon=25"; |
$resultat_presence_taxon = $this->executerRequete($requete_presence_taxon); |
$presence_taxon = (is_array($resultat_presence_taxon) && count($resultat_presence_taxon) > 0); |
return $presence_taxon; |
} |
private function decouperNomEtRechercheEspeceOuSousEspece($identifiant_espece) { |
$nameparser=new NameParser(); |
$nom_latin_decoupe=$nameparser->parse($identifiant_espece); |
// requete sous espece (on privilegie les noms retenu cf tri par esn_ce_statut) |
if (isset($nom_latin_decoupe['infra']) && $nom_latin_decoupe['infra']!="") { |
$requete="SELECT DISTINCT en_id_nom, esn_ce_statut" . |
" FROM eflore_nom, eflore_nom_rang, eflore_selection_nom " . |
" WHERE en_id_version_projet_nom = '25' AND en_nom_genre = ".$this->proteger($nom_latin_decoupe['genus'])." " . |
" AND enrg_abreviation_rang = ".$this->proteger($nom_latin_decoupe['infra_type'])." " . |
" AND en_epithete_infra_specifique = ".$this->proteger($nom_latin_decoupe['infra'])." " . |
" AND esn_id_nom= en_id_nom ". |
" AND esn_id_version_projet_taxon=en_id_version_projet_nom " . |
" AND en_epithete_espece = ".$this->proteger($nom_latin_decoupe['species'])." AND en_ce_rang = enrg_id_rang " . |
" ORDER BY esn_ce_statut ". |
" LIMIT 1"; |
} |
else { // espece (on privilegie les noms retenu cf tri par esn_ce_statut) |
$requete="SELECT DISTINCT en_id_nom, esn_ce_statut" . |
" FROM eflore_nom, eflore_nom_rang, eflore_selection_nom " . |
" WHERE en_id_version_projet_nom = '25' AND en_nom_genre = ".$this->proteger($nom_latin_decoupe['genus'])." " . |
" AND enrg_abreviation_rang = 'sp.' " . |
" AND esn_id_nom= en_id_nom ". |
" AND esn_id_version_projet_taxon=en_id_version_projet_nom " . |
" AND en_epithete_espece = ".$this->proteger($nom_latin_decoupe['species'])." AND en_ce_rang = enrg_id_rang " . |
" ORDER BY esn_ce_statut ". |
" LIMIT 1"; |
} |
$resultat = $this->executerRequete($requete); |
$retour = array(); |
if (is_array($resultat) && count($resultat) > 0) { |
$retour = $resultat[0]; |
} |
return $retour; |
} |
private function formaterNom($rawnom) { |
// Constitution du nom: |
$nom = ''; |
if (isset($rawnom['en_nom_supra_generique']) && $rawnom['en_nom_supra_generique'] != '') { |
$nom .= $rawnom['en_nom_supra_generique']; |
} else if (isset($rawnom['en_epithete_infra_generique']) && $rawnom['en_epithete_infra_generique'] != '') { |
$nom .= $rawnom['en_epithete_infra_generique']; |
} else { |
if (isset($rawnom['en_nom_genre']) && $rawnom['en_nom_genre'] != '') { |
$nom .= $rawnom['en_nom_genre']; |
} |
if (isset($rawnom['en_epithete_espece']) && $rawnom['en_epithete_espece']!= '') { |
$nom .= ' '.$rawnom['en_epithete_espece']; |
} |
if (isset($rawnom['en_epithete_infra_specifique']) && $rawnom['en_epithete_infra_specifique'] != '') { |
if (!empty($rawnom['enrg_abreviation_rang'])) { |
$nom .= ' '.$rawnom['enrg_abreviation_rang'].''; |
} |
$nom .= ' '.$rawnom['en_epithete_infra_specifique']; |
} |
} |
return $nom.$this->retournerAuteur($rawnom) ; |
} |
private function retournerAuteur($rawnom) { |
$auteurs = ''; |
$auteur_basio = ''; |
$auteur_modif = ''; |
if (!empty($rawnom['abreviation_auteur_basio_ex']) && $rawnom['abreviation_auteur_basio_ex']!='-' ) { |
$auteur_basio .= $rawnom['abreviation_auteur_basio_ex']; |
if (!empty($rawnom['abreviation_auteur_basio']) && $rawnom['abreviation_auteur_basio']!='-') { |
$auteur_basio .= ' ex '.$rawnom['abreviation_auteur_basio']; |
} |
} else if (!empty($rawnom['abreviation_auteur_basio']) && $rawnom['abreviation_auteur_basio']!='-') { |
$auteur_basio .= $rawnom['abreviation_auteur_basio']; |
} |
if (!empty($rawnom['abreviation_auteur_modif_ex']) && $rawnom['abreviation_auteur_modif_ex']!='-') { |
$auteur_modif .= $rawnom['abreviation_auteur_modif_ex']; |
if (!empty($rawnom['abreviation_auteur_modif']) && $rawnom['abreviation_auteur_modif']!='-') { |
$auteur_modif .= ' ex '.$rawnom['abreviation_auteur_modif']; |
} |
} else if (!empty($rawnom['abreviation_auteur_modif']) && $rawnom['abreviation_auteur_modif']!='-') { |
$auteur_modif .= $rawnom['abreviation_auteur_modif']; |
} |
if (!empty($auteur_modif)) { |
$auteurs = ' ('.$auteur_basio.') '.$auteur_modif; |
} elseif (!empty($auteur_basio)) { |
$auteurs = ' '.$auteur_basio; |
} |
return $auteurs ; |
} |
function rechercherInfosSurTexteCodeOuNumTax($identifiant_espece) { |
// texte libre, nom scientifique, |
// ou code nomenclatural (format BDNFFnn999999) |
// ou code taxonomique (format BDNFFnt999999) |
$identifiant_espece=trim($identifiant_espece); |
$identifiant_espece=utf8_encode($identifiant_espece); |
$retour = array(); |
preg_match('/BDNFFnn([0-9][0-9]*)/',$identifiant_espece, $elements); |
if (isset($elements[1])) { |
// Numero nomenclatural |
$infos_taxon = $this->rechercherInformationsComplementairesSurNumNom($elements[1]); |
$retour = array("nom_sel" => $this->formaterNom($infos_taxon), "en_id_nom" => $elements[1]); |
} else { |
// Numero taxonomique ou nom scientifique |
preg_match('/BDNFFnt([0-9][0-9]*)/', $identifiant_espece, $elements); |
if (isset($elements[1])) { |
// Numero taxonomique |
$infos_taxon = $this->effectuerRequeteInfosComplementairesSurNumTax($elements[1]); |
$infos_taxon = $infos_taxon[0]; |
$retour = array("nom_sel" => $this->formaterNom($infos_taxon), "en_id_nom" => $infos_taxon['en_id_nom']); |
} else { |
// Nom scientifique |
$id_nom = $this->decouperNomEtRechercheEspeceOuSousEspece($identifiant_espece); |
// Recherche du nom associe |
$retour = array("nom_sel" => $identifiant_espece); |
if(is_array($id_nom) && isset($id_nom['en_id_nom'])) { |
$infos_nom = $this->effectuerRequeteInfosComplementairesSurNumNom($id_nom['en_id_nom']); |
if (is_array($infos_nom) && !empty($infos_nom)) { |
$infos_nom = $infos_nom[0]; |
$retour = array("nom_sel" => $this->formaterNom($infos_nom), "en_id_nom" => $id_nom['en_id_nom']); |
} |
} |
} |
} |
return $retour; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/CartoGroupage.php |
---|
New file |
0,0 → 1,281 |
<?php |
class CartoGroupage { |
const MARQUEUR_GROUPE = 'GROUPE'; |
const MARQUEUR_COMMUNE = 'COMMUNE'; |
const MARQUEUR_STATION = 'STATION'; |
private static $seuilClusterisation = 200; |
private static $zoomDefaut = 3; |
private static $zoomMaxClustering = 12; |
private static $pasZoomDefaut = 1; |
private static $pasZoomMaxClustering = 0.05; |
private static $profondeurMin = 0; |
private static $profondeurMax = 8; |
private static $pasCorrectionCentre = null; |
private static $coefficientReductionPas = null; |
private static $coefficientProfondeurMax = null; |
private static $nbElements = array('stations' => 0,'communes' => 0, 'points' => 0); |
private static $listeNoeudsSelectionnes = array(); |
private static $bornesMax = array('latMin' => null, 'lngMin' => null, 'latMax' => null, 'lngMax' => null); |
private static $id_traites = array(); |
/* |
+---------+---------+ |
| | | |
| A | B | |
| | | |
+---------*---------+ |
| | | |
| D | C | |
| | | |
+---------+---------+ |
Quatres cadrans sont considérés par le quad tree |
* = centre de la fenetre |
*/ |
public static function creerGroupesQuadtree(&$markers, $neLat, $neLng, $swLat, $swLng, $zoom = 3) { |
if(count($markers) > self::$seuilClusterisation) { |
self::calculerProfondeurMax($zoom); |
self::calculerPasCorrectionCentre($zoom); |
$noeudRacine = array('nbrePoints' => count($markers), 'points' => $markers); |
self::attribuerAuCadran($noeudRacine, $neLat, $neLng, $swLat, $swLng); |
} else { |
foreach($markers as &$marker) { |
if(!self::estUnPointAExclure($marker)) { |
$emplacement = self::formaterPointPourAjout(&$marker); |
self::mettreAJourBornes(&$marker); |
$points = array($marker); |
$noeudSimple = array('points' => $points, 'nbrePoints' => 1); |
self::$nbElements[$emplacement]++; |
self::$listeNoeudsSelectionnes[] = self::ajouterGroupeOuPoint($noeudSimple); |
} |
self::$nbElements['points']++; |
} |
} |
return self::$listeNoeudsSelectionnes; |
} |
private function calculerCoefficientReductionPas() { |
if(self::$coefficientReductionPas == null) { |
self::$coefficientReductionPas = (self::$pasZoomMaxClustering - self::$pasZoomDefaut)/(self::$zoomMaxClustering - self::$zoomDefaut); |
} |
return self::$coefficientReductionPas; |
} |
private function calculerPasCorrectionCentre($zoom) { |
self::$pasCorrectionCentre = ($zoom - self::$zoomDefaut) * self::calculerCoefficientReductionPas() + self::$pasZoomDefaut; |
} |
private function calculerCoefficientProfondeurMax() { |
if(self::$coefficientProfondeurMax == null) { |
self::$coefficientProfondeurMax = (self::$profondeurMax - self::$profondeurMin)/(self::$zoomMaxClustering - self::$zoomDefaut); |
} |
return self::$coefficientProfondeurMax; |
} |
private function calculerProfondeurMax($zoom) { |
if($zoom > self::$zoomDefaut) { |
self::$profondeurMax = round(($zoom - self::$zoomDefaut) * self::calculerCoefficientProfondeurMax() + self::$profondeurMin,0); |
} else { |
self::$profondeurMax = 1; |
} |
} |
public static function getNbElements() { |
return self::$nbElements; |
} |
public static function mettreAJourBornes(&$point) { |
if(!is_numeric($point['lat']) || abs($point['lat']) > 90) return; |
if(!is_numeric($point['lng']) || abs($point['lng']) > 180) return; |
self::$bornesMax['latMin'] = ($point['lat'] < self::$bornesMax['latMin'] || self::$bornesMax['latMin'] == null) ? $point['lat'] : self::$bornesMax['latMin'] ; |
self::$bornesMax['lngMin'] = ($point['lng'] < self::$bornesMax['lngMin'] || self::$bornesMax['lngMin'] == null) ? $point['lng'] : self::$bornesMax['lngMin'] ; |
self::$bornesMax['latMax'] = ($point['lat'] > self::$bornesMax['latMax'] || self::$bornesMax['latMax'] == null) ? $point['lat'] : self::$bornesMax['latMax'] ; |
self::$bornesMax['lngMax'] = ($point['lng'] > self::$bornesMax['lngMax'] || self::$bornesMax['lngMax'] == null) ? $point['lng'] : self::$bornesMax['lngMax'] ; |
} |
public static function getBornes() { |
return self::$bornesMax; |
} |
/** |
* |
* @param mixed $noeud Le noeud à traiter par le quadtree |
* @param float $neLat Latitude du coin nord est de la fenetre |
* @param float $neLng Longitude du coin nord est de la fenetre |
* @param float $swLat Latitude du coin sud ouest de la fenetre |
* @param float $swLng Longitude du coin sud ouest de la fenetre |
* @param int $profondeur profondeur courante de l'arbre |
*/ |
private static function attribuerAuCadran(&$noeud, $neLat, $neLng, $swLat, $swLng, $profondeur = 0) { |
$latCentre = round((($neLat+$swLat)/2)/self::$pasCorrectionCentre,0)*self::$pasCorrectionCentre; |
$lngCentre = round((($neLng+$swLng)/2)/self::$pasCorrectionCentre,0)*self::$pasCorrectionCentre; |
foreach ($noeud['points'] as &$point) { |
if(!self::estUnPointAExclure($point)) { |
$emplacement = self::formaterPointPourAjout(&$point); |
self::mettreAJourBornes(&$point); |
$cadran = self::obtenirCadranPourPoint($latCentre, $lngCentre, $point); |
self::ajouterFils($noeud,$cadran,$point); |
self::$nbElements[$emplacement]++; |
} |
self::$nbElements['points']++; |
} |
$profondeur++; |
if($profondeur <= self::$profondeurMax) { |
(isset($noeud['A']) && $noeud['A'] != null) ? self::attribuerAuCadran($noeud['A'], $neLat, $lngCentre , $latCentre, $swLng, $profondeur) : ''; |
(isset($noeud['B']) && $noeud['B'] != null) ? self::attribuerAuCadran($noeud['B'], $neLat, $neLng, $latCentre, $lngCentre, $profondeur) : ''; |
(isset($noeud['C']) && $noeud['C'] != null) ? self::attribuerAuCadran($noeud['C'], $latCentre, $neLng, $swLat, $lngCentre, $profondeur) : ''; |
(isset($noeud['D']) && $noeud['D'] != null) ? self::attribuerAuCadran($noeud['D'], $latCentre, $lngCentre, $swLat, $swLng, $profondeur) : ''; |
} |
if(self::estUnParentFeuilles($noeud)) { |
self::$listeNoeudsSelectionnes[] = self::ajouterGroupeOuPoint($noeud); |
} |
} |
private static function estUnPointAExclure(&$point) { |
return self::estSensible($point) && |
self::coordonneesCommuneSontNulles($point); |
} |
private static function coordonneesCommuneSontNulles(&$point) { |
$coord_nulles = ($point['wgs84_latitude'] == null || |
$point['wgs84_latitude'] == '' || |
$point['wgs84_longitude'] == null || |
$point['wgs84_longitude'] == ''); |
return $coord_nulles; |
} |
private static function coordonneesSontNulles(&$point) { |
$coord_nulles = ($point['latitude'] == '000null' || |
$point['latitude'] == 0 || |
$point['latitude'] == '' || |
$point['longitude'] == '000null' || |
$point['longitude'] == 0 || |
$point['longitude'] == ''); |
return $coord_nulles; |
} |
private static function estSensible(&$point) { |
$sensible = isset($point['mots_cles_texte']) && substr_count(strtolower($point['mots_cles_texte']), 'sensible') != 0; |
return $sensible; |
} |
private static function formaterNomStation(&$point, $type_emplacement) { |
$station = ''; |
if($type_emplacement == 'stations' && $point['station'] != '' && $point['station'] != '000null') { |
$station = $point['station']; |
} else { |
$id_zone_geo = $point['ce_zone_geo']; |
$station = $point['zone_geo'].(($id_zone_geo != '' && $id_zone_geo != '000null') ? ' ('.self::formaterNomZoneGeo($id_zone_geo).')' : ''); |
} |
return $station; |
} |
private static function formaterNomZoneGeo($zone_geo) { |
$zone_geo = str_replace('INSEE-C:', '', $zone_geo); |
$zone_geo = strlen($zone_geo) >= 2 ? substr($zone_geo, 0, 2) : $zone_geo; |
return $zone_geo; |
} |
private static function formaterPointPourAjout(&$point) { |
if(isset($point['type_emplacement'])) { |
return $point['type_emplacement']; |
} |
if(self::coordonneesSontNulles($point) || self::estSensible($point)) { |
$point_allege = array(); |
$point_allege['id'] = self::MARQUEUR_COMMUNE.':'.$point['wgs84_latitude'].'|'.$point['wgs84_longitude']; |
$point_allege['type_emplacement'] = 'communes'; |
$point_allege['nom'] = self::formaterNomStation($point, 'communes'); |
$point_allege['lat'] = (float)$point['wgs84_latitude']; |
$point_allege['lng'] = (float)$point['wgs84_longitude']; |
$point = $point_allege; |
} else { |
$point_allege = array(); |
$point_allege['id'] = self::MARQUEUR_STATION.':'.$point['latitude'].'|'.$point['longitude']; |
$point_allege['type_emplacement'] = 'stations'; |
$point_allege['nom'] = self::formaterNomStation($point, 'stations'); |
$point_allege['lat'] = (float)$point['latitude']; |
$point_allege['lng'] = (float)$point['longitude']; |
$point = $point_allege; |
} |
return $point['type_emplacement']; |
} |
private function obtenirCadranPourPoint($latCentre,$lngCentre, &$point) { |
if ($point['lng'] < $lngCentre) { |
if ($point['lat'] > $latCentre) { |
$cadran = 'A'; |
} else { |
$cadran = 'D'; |
} |
} else { |
if ($point['lat'] > $latCentre) { |
$cadran = 'B'; |
} else { |
$cadran = 'C'; |
} |
} |
return $cadran; |
} |
private static function ajouterFils(&$noeud, $cadran, &$point) { |
if(!isset($noeud[$cadran])) { |
$noeud[$cadran] = array('points' => array(),'nbrePoints' => 0, 'latMoyenne' => 0, 'lngMoyenne' => 0); |
} |
$noeud[$cadran]['points'][] = $point; |
$noeud[$cadran]['nbrePoints']++; |
$noeud[$cadran]['latMoyenne'] += $point['lat']; |
$noeud[$cadran]['lngMoyenne'] += $point['lng']; |
} |
private static function ajouterGroupeOuPoint(&$noeud) { |
$groupe = array(); |
if ($noeud['nbrePoints'] > 1 && isset($noeud['latMoyenne']) && isset($noeud['lngMoyenne'])) { |
$groupe['lat'] = $noeud['latMoyenne']/$noeud['nbrePoints']; |
$groupe['lng'] = $noeud['lngMoyenne']/$noeud['nbrePoints']; |
$groupe['id'] = 'GROUPE:'.$groupe['lat'].';'.$groupe['lng']; |
$groupe['nbreMarqueur'] = $noeud['nbrePoints']; |
} else { |
$groupe = $noeud['points'][0]; |
} |
return $groupe; |
} |
private static function estUnParentFeuilles(&$noeud) { |
return self::estUneFeuille($noeud['A']) && |
self::estUneFeuille($noeud['B']) && |
self::estUneFeuille($noeud['C']) && |
self::estUneFeuille($noeud['D']); |
} |
private static function estUneFeuille(&$noeud) { |
return $noeud == null || |
(!isset($noeud['A']) || $noeud['A'] == null) && |
(!isset($noeud['B']) || $noeud['B'] == null) && |
(!isset($noeud['C']) || $noeud['C'] == null) && |
(!isset($noeud['D']) || $noeud['D'] == null); |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/Conteneur.php |
---|
New file |
0,0 → 1,79 |
<?php |
/** |
* Le conteneur encapsule les classes et les paramètres de config. |
* Il gère leur instanciation, ainsi que la récupération des paramètres depuis les fichiers de configuration. |
* |
* @category php 5.2 |
* @package cel |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org) |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version $Id$ |
*/ |
class Conteneur { |
protected $parametres = array(); |
protected $partages = array(); |
public function __construct(array $parametres = null) { |
$this->parametres = is_null($parametres) ? array() : $parametres; |
} |
public function getParametre($cle) { |
$valeur = isset($this->parametres[$cle]) ? $this->parametres[$cle] : null; |
if (is_null($valeur) && $this->etreParametreASection($cle)) { |
$valeur = $this->getParametreAvecSection($cle); |
} |
return $valeur; |
} |
private function etreParametreASection($cle) { |
return strpos($cle, '.') ? true : false; |
} |
private function getParametreAvecSection($cle) { |
$cleComposee = explode('.', $cle); |
$valeur = $this->parametres; |
foreach ($cleComposee as $cleCourrante) { |
$valeur = isset($valeur[$cleCourrante]) ? $valeur[$cleCourrante] : null; |
} |
return $valeur; |
} |
public function getParametreTableau($cle) { |
$tableau = array(); |
$parametre = $this->getParametre($cle); |
if (empty($parametre) === false) { |
$tableauPartiel = explode(',', $parametre); |
$tableauPartiel = array_map('trim', $tableauPartiel); |
foreach ($tableauPartiel as $champ) { |
if (strpos($champ, '=') === false) { |
$tableau[] = trim($champ); |
} else { |
list($cle, $val) = explode('=', $champ); |
$tableau[trim($cle)] = trim($val); |
} |
} |
} |
return $tableau; |
} |
public function setParametre($cle, $valeur) { |
$this->parametres[$cle] = $valeur; |
} |
public function getBdd() { |
if (!isset($this->partages['Bdd'])){ |
$this->partages['Bdd'] = new Bdd($this->getParametre('database_cel')); |
} |
return $this->partages['Bdd']; |
} |
public function getScript() { |
if (!isset($this->partages['Script'])){ |
$this->partages['Script'] = new Script(); |
} |
return $this->partages['Script']; |
} |
} |
?> |
/branches/v1.6-croc/jrest/lib/zip.php |
---|
New file |
0,0 → 1,190 |
<?php |
/* vim: set expandtab sw=4 ts=4 sts=4: */ |
/** |
* |
* @version $Id: zip.lib.php 10240 2007-04-01 11:02:46Z cybot_tm $ |
*/ |
/** |
* Zip file creation class. |
* Makes zip files. |
* |
* Based on : |
* |
* http://www.zend.com/codex.php?id=535&single=1 |
* By Eric Mueller <eric@themepark.com> |
* |
* http://www.zend.com/codex.php?id=470&single=1 |
* by Denis125 <webmaster@atlant.ru> |
* |
* a patch from Peter Listiak <mlady@users.sourceforge.net> for last modified |
* date and time of the compressed file |
* |
* Official ZIP file format: http://www.pkware.com/appnote.txt |
* |
* @access public |
*/ |
class zipfile |
{ |
/** |
* Array to store compressed data |
* |
* @var array $datasec |
*/ |
var $datasec = array(); |
/** |
* Central directory |
* |
* @var array $ctrl_dir |
*/ |
var $ctrl_dir = array(); |
/** |
* End of central directory record |
* |
* @var string $eof_ctrl_dir |
*/ |
var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; |
/** |
* Last offset position |
* |
* @var integer $old_offset |
*/ |
var $old_offset = 0; |
/** |
* Converts an Unix timestamp to a four byte DOS date and time format (date |
* in high two bytes, time in low two bytes allowing magnitude comparison). |
* |
* @param integer the current Unix timestamp |
* |
* @return integer the current date in a four byte DOS format |
* |
* @access private |
*/ |
function unix2DosTime($unixtime = 0) { |
$timearray = ($unixtime == 0) ? getdate() : getdate($unixtime); |
if ($timearray['year'] < 1980) { |
$timearray['year'] = 1980; |
$timearray['mon'] = 1; |
$timearray['mday'] = 1; |
$timearray['hours'] = 0; |
$timearray['minutes'] = 0; |
$timearray['seconds'] = 0; |
} // end if |
return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | |
($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1); |
} // end of the 'unix2DosTime()' method |
/** |
* Adds "file" to archive |
* |
* @param string file contents |
* @param string name of the file in the archive (may contains the path) |
* @param integer the current timestamp |
* |
* @access public |
*/ |
function addFile($data, $name, $time = 0) |
{ |
$name = str_replace('\\', '/', $name); |
$dtime = dechex($this->unix2DosTime($time)); |
$hexdtime = '\x' . $dtime[6] . $dtime[7] |
. '\x' . $dtime[4] . $dtime[5] |
. '\x' . $dtime[2] . $dtime[3] |
. '\x' . $dtime[0] . $dtime[1]; |
eval('$hexdtime = "' . $hexdtime . '";'); |
$fr = "\x50\x4b\x03\x04"; |
$fr .= "\x14\x00"; // ver needed to extract |
$fr .= "\x00\x00"; // gen purpose bit flag |
$fr .= "\x08\x00"; // compression method |
$fr .= $hexdtime; // last mod time and date |
// "local file header" segment |
$unc_len = strlen($data); |
$crc = crc32($data); |
$zdata = gzcompress($data); |
$zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug |
$c_len = strlen($zdata); |
$fr .= pack('V', $crc); // crc32 |
$fr .= pack('V', $c_len); // compressed filesize |
$fr .= pack('V', $unc_len); // uncompressed filesize |
$fr .= pack('v', strlen($name)); // length of filename |
$fr .= pack('v', 0); // extra field length |
$fr .= $name; |
// "file data" segment |
$fr .= $zdata; |
// "data descriptor" segment (optional but necessary if archive is not |
// served as file) |
// nijel(2004-10-19): this seems not to be needed at all and causes |
// problems in some cases (bug #1037737) |
//$fr .= pack('V', $crc); // crc32 |
//$fr .= pack('V', $c_len); // compressed filesize |
//$fr .= pack('V', $unc_len); // uncompressed filesize |
// add this entry to array |
$this -> datasec[] = $fr; |
// now add to central directory record |
$cdrec = "\x50\x4b\x01\x02"; |
$cdrec .= "\x00\x00"; // version made by |
$cdrec .= "\x14\x00"; // version needed to extract |
$cdrec .= "\x00\x00"; // gen purpose bit flag |
$cdrec .= "\x08\x00"; // compression method |
$cdrec .= $hexdtime; // last mod time & date |
$cdrec .= pack('V', $crc); // crc32 |
$cdrec .= pack('V', $c_len); // compressed filesize |
$cdrec .= pack('V', $unc_len); // uncompressed filesize |
$cdrec .= pack('v', strlen($name)); // length of filename |
$cdrec .= pack('v', 0); // extra field length |
$cdrec .= pack('v', 0); // file comment length |
$cdrec .= pack('v', 0); // disk number start |
$cdrec .= pack('v', 0); // internal file attributes |
$cdrec .= pack('V', 32); // external file attributes - 'archive' bit set |
$cdrec .= pack('V', $this -> old_offset); // relative offset of local header |
$this -> old_offset += strlen($fr); |
$cdrec .= $name; |
// optional extra field, file comment goes here |
// save to central directory |
$this -> ctrl_dir[] = $cdrec; |
} // end of the 'addFile()' method |
/** |
* Dumps out file |
* |
* @return string the zipped file |
* |
* @access public |
*/ |
function file() |
{ |
$data = implode('', $this -> datasec); |
$ctrldir = implode('', $this -> ctrl_dir); |
return |
$data . |
$ctrldir . |
$this -> eof_ctrl_dir . |
pack('v', sizeof($this -> ctrl_dir)) . // total # of entries "on this disk" |
pack('v', sizeof($this -> ctrl_dir)) . // total # of entries overall |
pack('V', strlen($ctrldir)) . // size of central dir |
pack('V', strlen($data)) . // offset to start of central dir |
"\x00\x00"; // .zip file comment length |
} // end of the 'file()' method |
} // end of the 'zipfile' class |
?> |
/branches/v1.6-croc/jrest/lib/Cel.php |
---|
New file |
0,0 → 1,772 |
<?php |
// ATTENTION ! Classe compatible uniquement avec nouveau format de bdd du cel // |
/** |
* Classe mère abstraite contenant les méthodes génériques des services. |
* Encodage en entrée : utf8 |
* Encodage en sortie : utf8 |
* |
* @author Jean-Pascal MILCENT <jpm@clapas.org> |
* @author Aurélien Peronnet <aurelien@tela-botanica.org> |
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt> |
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt> |
* @version $Id$ |
* @copyright © 2012, Tela Botanica |
*/ |
// TODO : supprimer la méthode protegerRequete() |
abstract class Cel { |
const TYPE_OBS = 'observation'; |
const TYPE_IMG = 'image'; |
const SQL_MODE_ASSOC = PDO::FETCH_ASSOC; |
const SQL_MODE_OBJET = PDO::FETCH_OBJ; |
const SQL_RETOUR_COMPLET = 'All'; |
const SQL_RETOUR_LIGNE = 'Row'; |
const SQL_RETOUR_COLONNE = 'Column'; |
const SQL_RETOUR_BRUT = 'Raw'; |
public $config; |
private $ressources; |
protected $parametres = array(); |
protected $bdd; |
protected $messages = array(); |
protected $debug = array(); |
public function __construct($config) { |
@session_start(); |
// Tableau contenant la config de Jrest |
$this->config = $config; |
// Réglages de PHP |
setlocale(LC_ALL, $this->config['settings']['locale']); |
date_default_timezone_set($this->config['settings']['fuseauHoraire']); |
// Connection à la base de données |
$this->bdd = $this->connecterPDO($this->config, 'database_cel'); |
// Nettoyage du _GET (sécurité) |
$this->collecterParametres();// Récupération de tous les parametres de _GET, nettoyage et mise dans $this->parametres |
$this->recupererParametresUrl();// Vidage de _GET et création d'attribut de la classe |
$this->definirParametresUrlParDefaut(); |
// Définition de variable générale dans la config |
$this->config['settings']['baseURLAbsoluDyn'] = 'http://'.$_SERVER['SERVER_NAME'].$this->config['settings']['baseURL'].'%s'; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION de la BASE de DONNÉES |
protected function connecterPDO($config, $base = 'database_cel') { |
$cfg = $config[$base]; |
// ATTENTION : la connexin à la bdd peut échouer si l'host vaut localhost. Utiliser 127.0.0.1 à la place. |
$dsn = $cfg['phptype'].':dbname='.$cfg['database'].';host='.$cfg['hostspec']; |
try { |
// Création de la connexion en UTF-8 à la BDD |
$PDO = new PDO($dsn, $cfg['username'], $cfg['password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'")); |
// Affiche les erreurs détectées par PDO (sinon mode silencieux => aucune erreur affiché) |
$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
} catch (PDOException $e) { |
echo 'La connexion à la base de donnée via PDO a échouée : ' .$dsn. $e->getMessage(); |
} |
return $PDO; |
} |
/** |
* Protège automatiquement toutes les chaines comprises entre deux caractères '|'. |
* Puis execute la requete. |
* @see protegerRequete() |
* @param unknown_type $requete |
*/ |
protected function requeter($requete, $retour = self::SQL_RETOUR_COMPLET, $mode = PDO::FETCH_ASSOC) { |
$requete = $this->protegerRequete($requete); |
return $this->executerRequete($requete, $retour, $mode); |
} |
/** |
* Protège automatiquement toutes les chaines comprises entre deux caractères '|'. |
* @see protegerRequete() |
* @param unknown_type $requete |
*/ |
protected function executer($requete) { |
$requete = $this->protegerRequete($requete); |
return $this->executerRequeteSimple($requete); |
} |
/** |
* Méthode permettant de rechercher dans une requete SQL sous forme de chaine (String) les chaines |
* à protéger. Cela évite de protéger chaque variable avant de l'insérer dans une requete SQL. |
* Par contre, il est important que les chaine à protéger ne contiennent pas le caractère '|'. |
* |
* @param $requete |
*/ |
protected function protegerRequete($requete) { |
if (substr_count($requete, '|') % 2 === 0) { |
if (preg_match_all('/\|([^|]*)\|/', $requete, $correspondances, PREG_SET_ORDER)) { |
foreach ($correspondances as $chaine) { |
$chaine_protegee = $this->bdd->quote($chaine[1]); |
$requete = str_replace($chaine[0], $chaine_protegee, $requete); |
} |
} |
} else { |
$this->messages[] = "La requête a protéger contient un nombre impair de caractère de protection '|'."; |
$requete = false; |
} |
return $requete; |
} |
protected function proteger($chaine) { |
return $this->bdd->quote($chaine); |
} |
protected function protegerTableau(Array $tableau) { |
foreach ($tableau as $id => $val) { |
$tableau[$id] = $this->proteger($val); |
} |
return $tableau; |
} |
protected function executerRequeteSimple($requete) { |
$resultat = false; |
try { |
$resultat = $this->bdd->exec($requete); |
if ($resultat === false) { |
$this->debug[] = "La requête a échoué : $requete"; |
} |
} catch (PDOException $e) { |
$this->debug[] = sprintf($this->getTxt('sql_erreur_requete'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete); |
} |
return $resultat; |
} |
protected function executerRequete($requete, $retour = self::SQL_RETOUR_COMPLET, $mode = PDO::FETCH_ASSOC) { |
$resultat = false; |
try { |
switch ($retour) { |
case self::SQL_RETOUR_COMPLET : |
$resultat = $this->bdd->query($requete)->fetchAll($mode);// Retourne toutes les lignes |
break; |
case self::SQL_RETOUR_LIGNE : |
$resultat = $this->bdd->query($requete)->fetch($mode);// Retourne la première ligne |
break; |
case self::SQL_RETOUR_COLONNE : |
$resultat = $this->bdd->query($requete)->fetchColumn();// Retourne la première colonne de la première ligne |
break; |
case self::SQL_RETOUR_BRUT : |
$resultat = $this->bdd->query($requete);// Retourne l'objet brut pour être utilisé dans une boucle de type foreach |
break; |
default: |
$this->debug[] = "Le type de retour '$retour' est inconnu."; |
} |
if ($resultat === false) { |
$this->debug[] = "La requête a retourné aucun résultat : $requete"; |
} |
} catch (PDOException $e) { |
$this->debug[] = sprintf($this->getTxt('sql_erreur_requete'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete); |
} |
return $resultat; |
} |
protected function getTxt($id) { |
$sortie = ''; |
switch ($id) { |
case 'sql_erreur' : $sortie = 'Requête echec. Fichier : "%s". Ligne : "%s". Message : %s'; break; |
case 'sql_erreur_requete' : $sortie = "Requête echec.\nFichier : %s.\nLigne : %s.\nMessage : %s.\nRequête : %s"; break; |
default : $sortie = $id; |
} |
return $sortie; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// TRAITEMENT des URLs et des PARAMÊTRES |
private function collecterParametres() { |
if (isset($_GET) && $_GET != '') { |
foreach ($_GET as $cle => $valeur) { |
$this->parametres[$cle] = rawurldecode($this->verifierSecuriteParametreUrl($valeur)); |
} |
} |
} |
private function recupererParametresUrl() { |
if (isset($_GET)) { |
$get_params = array('orderby', 'distinct', 'start', 'limit', 'formatRetour'); |
foreach ($get_params as $get) { |
if (isset($_GET[$get])) { |
$_GET[$get] = $this->verifierSecuriteParametreUrl($_GET[$get]); |
if ($_GET[$get] != '') { |
if (!isset($this->$get)) { |
$this->$get = $_GET[$get]; |
} else { |
$e = "Impossible d'ajouter l'attribut $get à la classe du service car elle possède déjà un attribut nommé : $get"; |
trigger_error($e, E_USER_WARNING); |
} |
} else { |
$_GET[$get] = null; |
} |
} |
} |
} |
} |
protected function verifierSecuriteParametreUrl($param) { |
//$verifier = array('NULL', "\n", "\r", "\\", "'", '"', "\x00", "\x1a", ';'); |
$param = strip_tags($param); |
return $param; |
} |
private function definirParametresUrlParDefaut() { |
if (!isset($this->start)) { |
$this->start = 0; |
} |
if (!isset($this->limit)) { |
$this->limit = 150; |
} |
} |
protected function traiterParametres($params_attendu, $params, $pourBDD = true) { |
$sortie = array(); |
foreach ($params_attendu as $num => $nom) { |
if (isset($params[$num]) && $params[$num] != '*') { |
if ($pourBDD) { |
$params[$num] = $this->bdd->quote($params[$num]); |
} |
$sortie[$nom] = $params[$num]; |
} |
} |
return $sortie; |
} |
protected function traiterNomMethodeGet($nom) { |
$methode = 'get'; |
$methode .= str_replace(' ', '', ucwords(str_replace('-', ' ', strtolower($nom)))); |
return $methode; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION de l'ENVOIE au NAVIGATEUR |
protected function envoyerJson($donnees, $encodage = 'utf-8') { |
$encodage_json = true; |
$this->envoyer($donnees, 'application/json', $encodage, $encodage_json); |
} |
protected function envoyerJsonVar($variable, $donnees = null, $encodage = 'utf-8') { |
$contenu = "var $variable = ".json_encode($donnees); |
$this->envoyer($contenu, 'text/html', $encodage); |
} |
protected function envoyerJsonp($donnees = null, $encodage = 'utf-8') { |
$contenu = $this->parametres['callback'].'('.json_encode($donnees).');'; |
$this->envoyer($contenu, 'text/html', $encodage); |
} |
protected function envoyer($donnees = null, $mime = 'text/html', $encodage = 'utf-8', $json = false) { |
// Traitements des messages d'erreurs et données |
if (count($this->messages) != 0) { |
header('HTTP/1.1 500 Internal Server Error'); |
$mime = 'application/json'; |
$json = true; |
$sortie = $this->messages; |
} else { |
$sortie = $donnees; |
if (is_null($donnees)) { |
$sortie = 'OK'; |
} |
} |
// Gestion de l'envoie du déboguage |
$this->envoyerDebogage(); |
// Encodage au format et JSON et envoie sur la sortie standard |
$contenu = $json ? json_encode($sortie) : $sortie; |
$this->envoyerContenu($encodage, $mime, $contenu); |
} |
private function envoyerDebogage() { |
if (!is_array($this->debug)) { |
$this->debug[] = $this->debug; |
} |
if (count($this->debug) != 0) { |
foreach ($this->debug as $cle => $val) { |
if (is_array($val)) { |
$this->debug[$cle] = print_r($val, true); |
} |
} |
header('X-DebugJrest-Data:'.json_encode($this->debug)); |
} |
} |
private function envoyerContenu($encodage, $mime, $contenu) { |
if (!is_null($mime) && !is_null($encodage)) { |
header("Content-Type: $mime; charset=$encodage"); |
} else if (!is_null($mime) && is_null($encodage)) { |
header("Content-Type: $mime"); |
} |
print $contenu; |
} |
private function envoyerAuth($message_accueil, $message_echec) { |
header('HTTP/1.0 401 Unauthorized'); |
header('WWW-Authenticate: Basic realm="'.mb_convert_encoding($message_accueil, 'ISO-8859-1', 'UTF-8').'"'); |
header('Content-type: text/plain; charset=UTF-8'); |
print $message_echec; |
exit(0); |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION DES CLASSES CHARGÉES À LA DEMANDE |
protected function getRestClient() { |
if (!isset($this->restClient)) { |
$this->restClient = new CelRestClient(); |
} |
return $this->restClient; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION DE L'IDENTIFICATION |
protected function getAuthIdentifiant() { |
$id = (isset($_SERVER['PHP_AUTH_USER'])) ? $_SERVER['PHP_AUTH_USER'] : null; |
return $id; |
} |
protected function getAuthMotDePasse() { |
$mdp = (isset($_SERVER['PHP_AUTH_PW'])) ? $_SERVER['PHP_AUTH_PW'] : null; |
return $mdp; |
} |
public function authentifierAdmin() { |
$message_accueil = "Veuillez vous identifier avec votre compte Tela Botanica."; |
$message_echec = "Accès limité aux administrateurs du CEL.\n". |
"Votre tentative d'identification a échoué.\n". |
"Actualiser la page pour essayer à nouveau si vous êtes bien inscrit comme administrateur."; |
return $this->authentifier($message_accueil, $message_echec, 'Admin'); |
} |
public function authentifierUtilisateur() { |
$message_accueil = "Veuillez vous identifier avec votre compte Tela Botanica."; |
$message_echec = "Accès limité aux utilisateur du CEL.\n". |
"Inscrivez vous http://www.tela-botanica.org/page:inscription pour le devenir.\n". |
"Votre tentative d'identification a échoué.\n". |
"Actualiser la page pour essayer à nouveau si vous êtes déjà inscrit ou contacter 'accueil@tela-botanica.org'."; |
return $this->authentifier($message_accueil, $message_echec, 'Utilisateur'); |
} |
public function isAdmin($id) { |
$admins = $this->config['jrest_admin']['admin']; |
$admin_tab = explode(',',$admins); |
if (in_array($id,$admin_tab)) { |
return true; |
} else { |
return false; |
} |
} |
public function controleUtilisateur($id) { |
if (isset($_SESSION['user']) && isset($_SESSION['user']['name']) && $_SESSION['user']['name'] == '') { |
//cas de la session temporaire, on ne fait rien de particulier |
} else { |
if (isset($_SESSION['user']) && isset($_SESSION['user']['name']) && !$this->isAdmin($_SESSION['user']['name']) && $_SESSION['user']['name'] != $id) { |
// cas d'usurpation d'identité |
print 'Accès interdit'; |
exit(); |
} |
} |
} |
public function controleAppelIpAutorisee() { |
$ips_autorisees = explode(',', $this->config['jrest_admin']['ip_autorisees']); |
$ip_appelante = $_SERVER['REMOTE_ADDR']; |
if(!in_array($ip_appelante, $ips_autorisees) && $ip_appelante != $_SERVER['SERVER_ADDR']) { |
header('HTTP/1.0 401 Unauthorized'); |
echo 'Accès interdit'; |
exit(0); |
} |
return true; |
} |
public function logger($index,$chaine) { |
if(!class_exists('Log')) { |
Log::getInstance(); |
} |
Log::setCheminLog($this->config['log']['cheminlog']); |
Log::setTimeZone($this->config['log']['timezone']); |
Log::setTailleMax($this->config['log']['taillemax']); |
Log::ajouterEntree($index,$chaine); |
} |
private function authentifier($message_accueil, $message_echec, $type) { |
$id = $this->getAuthIdentifiant(); |
if (!isset($id)) { |
$this->envoyerAuth($message_accueil, $message_echec); |
} else { |
if ($type == 'Utilisateur' && $this->getAuthMotDePasse() == 'debug') { |
$autorisation = true; |
} else { |
$methodeAutorisation = "etre{$type}Autorise"; |
$autorisation = $this->$methodeAutorisation(); |
} |
if ($autorisation == false) { |
$this->envoyerAuth($message_accueil, $message_echec); |
} |
} |
return true; |
} |
public function etreUtilisateurAutorise() { |
$identifiant = $this->getAuthIdentifiant(); |
$mdp = md5($this->getAuthMotDePasse()); |
$service = "TestLoginMdp/$identifiant/$mdp"; |
$url = sprintf($this->config['settings']['baseURLServicesAnnuaireTpl'], $service); |
$json = $this->getRestClient()->consulter($url); |
$existe = json_decode($json); |
$autorisation = (isset($existe) && $existe) ? true :false; |
return $autorisation; |
} |
public function etreAdminAutorise() { |
$identifiant = $this->getAuthIdentifiant(); |
$autorisation = ($this->etreUtilisateurAutorise() && $this->etreAdminCel($identifiant)) ? true : false; |
return $autorisation; |
} |
public function etreAdminCel($courriel) { |
$admins = $this->config['jrest_admin']['admin']; |
$courriels_autorises = explode(',', $admins); |
$autorisation = (in_array($courriel, $courriels_autorises)) ? true : false ; |
return $autorisation; |
} |
public function getInfosComplementairesUtilisateur($id_utilisateur) { |
$infos_utilisateur = array('prenom' => $id_utilisateur, 'nom' => $id_utilisateur, 'courriel' => $id_utilisateur); |
if(is_numeric($id_utilisateur)) { |
$requete_infos_utilisateur = 'SELECT prenom, nom, courriel FROM cel_utilisateurs '. |
'WHERE id_utilisateur = '.$this->proteger($id_utilisateur); |
$resultat_infos_utilisateur = $this->requeter($requete_infos_utilisateur); |
if($resultat_infos_utilisateur && is_array($resultat_infos_utilisateur) && count($resultat_infos_utilisateur) > 0) { |
$infos_utilisateur = $resultat_infos_utilisateur[0]; |
} |
} |
return $infos_utilisateur; |
} |
public function getInfosComplementairesUtilisateurPourMail($mail_utilisateur) { |
$infos_utilisateur = array('prenom' => $mail_utilisateur, 'nom' => $mail_utilisateur, 'courriel' => $mail_utilisateur); |
$requete_infos_utilisateur = 'SELECT id, prenom, nom FROM cel_utilisateurs '. |
'WHERE courriel = '.$this->proteger($mail_utilisateur); |
$resultat_infos_utilisateur = $this->requeter($requete_infos_utilisateur); |
if($resultat_infos_utilisateur && is_array($resultat_infos_utilisateur) && count($resultat_infos_utilisateur) > 0) { |
$infos_utilisateur = $resultat_infos_utilisateur; |
} |
return $infos_utilisateur; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION DE MÉTHODES COMMUNES ENTRE LES SERVICES |
protected function denullifierTableauValeurCel($tableau) { |
// Denullifiage |
foreach($tableau as $k=>$v) { |
if (($v=="null") || ($v=="000null")) { |
$row[$k]=""; |
} |
else { |
$row[$k]=utf8_decode($v); |
} |
} |
return $tableau; |
} |
protected function getUrlImage($id, $format = 'L') { |
$url_tpl = $this->config['settings']['celImgUrlTpl']; |
$id = sprintf('%09s', $id).$format; |
$url = sprintf($url_tpl, $id); |
return $url; |
} |
/** |
* Prend en paramêtre un tableau de courriels et retourne après avoir interrogé un service de l'annuaire |
* une tableau avec en clé le courriel et en valeur l'intitulé de la personne à afficher. |
* |
* @param array $courriels un tableau de courriels pour lesquels il faut rechercher les infos d'identité |
*/ |
protected function creerAuteurs(Array $courriels) { |
$auteurs = array(); |
if ($identites = $this->recupererUtilisateursIdentite($courriels)) { |
foreach ($identites as $courriel => $infos) { |
$auteurs[$courriel] = $infos['intitule']; |
} |
} |
return $auteurs; |
} |
protected function recupererUtilisateursIdentite(Array $courriels) { |
// Récupération des données au format Json |
$service = "utilisateur/identite-par-courriel/".implode(',', $courriels); |
$url = sprintf($this->config['settings']['baseURLServicesAnnuaireTpl'], $service); |
$json = file_get_contents($url); |
$utilisateurs = json_decode($json, true); |
$noms = array(); |
foreach ($courriels as $courriel) { |
$courriel = strtolower($courriel); |
$info = array('id' => null, 'intitule' => ''); |
if (isset($utilisateurs[$courriel])) { |
$info['intitule'] = $utilisateurs[$courriel]['intitule']; |
$info['id'] = $utilisateurs[$courriel]['id']; |
} else { |
$info['intitule'] = $this->tronquerCourriel($courriel); |
} |
$noms[$courriel] = $info; |
} |
return $noms; |
} |
protected function tronquerCourriel($courriel) { |
$courriel = preg_replace('/[^@]+$/i', '...', $courriel); |
return $courriel; |
} |
protected function nettoyerTableau(Array $tableau) { |
foreach ($tableau as $cle => $valeur) { |
if (is_array($valeur)) { |
$valeur = $this->nettoyerTableau($valeur); |
} else { |
$valeur = $this->nettoyerTexte($valeur); |
} |
$tableau[$cle] = $valeur; |
} |
return $tableau; |
} |
/** |
* Fonction nettoyant les caractères spéciaux (&,<) et les valeurs nulles du CEL dans un texte comprenant du HTML. |
*/ |
protected function nettoyerTexte($txt) { |
$txt = preg_replace('/&(?!([a-z]+|#[0-9]+|#x[0-9][a-f]+);)/i', '&', $txt); |
// TODO : trouver une regexp qui permet de remplacer les symboles < et > isolés |
//$txt = preg_replace('/<(?!([a-z][a-z0-9]*)\b[^>]*>(.*?)<\/\1>|\/\s*([a-z][a-z0-9]*)\s*>)/i', '<', $txt); |
//$txt = preg_replace('/(?!<([a-z][a-z0-9]*)\b[^>]*)>(?!(.*?)<\/\1>)/i', '>', $txt); |
$txt = preg_replace('/(?:000null|null)/i', '', $txt); |
return $txt; |
} |
/** |
* Fonction nettoyant les caractères spéciaux HTML pour les champs de saisie libre du CEL. |
*/ |
protected function protegerCaracteresHtmlDansChamps($donnees) { |
$champs = array('mots_cles_texte', 'commentaire', |
'zone_geo', 'lieudit', 'station', 'milieu', 'commentaire', 'nom_sel'); |
foreach ($champs as $champ) { |
if (isset($donnees[$champ])) { |
$donnees[$champ] = htmlspecialchars($donnees[$champ]); |
} |
} |
return $donnees; |
} |
protected function convertirDateHeureMysqlEnTimestamp($date_heure_mysql){ |
$val = explode(' ', $date_heure_mysql); |
$date = explode('-', $val[0]); |
$heure = explode(':', $val[1]); |
return mktime((int) $heure[0], (int) $heure[1], (int) $heure[2], (int) $date[1], (int) $date[2], (int) $date[0]); |
} |
protected function etreNull($valeur) { |
$etre_null = false; |
if ($valeur == '' || $valeur == null || $valeur == '000null' || $valeur == 'null' || $valeur == '*') { |
$etre_null = true; |
} |
return $etre_null; |
} |
protected function formaterDate($date_heure_mysql, $format = '%A %d %B %Y à %H:%M') { |
$date_formatee = ''; |
if (!$this->etreNull($date_heure_mysql)) { |
$timestamp = $this->convertirDateHeureMysqlEnTimestamp($date_heure_mysql); |
$date_formatee = strftime($format, $timestamp); |
} |
return $date_formatee; |
} |
protected function convertirCodeZoneGeoVersDepartement($code_zone_geo) { |
$code_departement = ''; |
if($this->estUnCodeInseeDepartement($code_zone_geo)) { |
$code_departement = substr(ltrim($code_zone_geo,'INSEE-C:'),0,2); |
} |
return $code_departement; |
} |
protected function estUnCodeInseeDepartement($code_a_tester) { |
return preg_match('/^INSEE-C:[0-9]{5}/',$code_a_tester); |
} |
protected function convertirCodeZoneGeoVersCodeInsee($code_zone_geo) { |
$code_departement = ''; |
if($this->estUnCodeInseeDepartement($code_zone_geo)) { |
$code_departement = ltrim($code_zone_geo,'INSEE-C:'); |
} |
return $code_departement; |
} |
protected function convertirCodeInseeVersCodeZoneGeo($code_insee) { |
return 'INSEE-C:'.$code_insee; |
} |
protected function obtenirCodeInseeCommunePourNomEtDepartement($nom_commune, $dpt) { |
$code_insee = $dpt; |
$requete = 'SELECT id_zone_geo FROM cel_zones_geo '. |
'WHERE nom LIKE '.$this->proteger($nom_commune).' '. |
'AND id_zone_geo LIKE "INSEE-C:'.$dpt.'%"'; |
$resultat = $this->requeter($requete); |
if(is_array($resultat) && count($resultat) > 0) { |
$code_insee = $resultat[0]['id_zone_geo']; |
} |
return $code_insee; |
} |
protected function encoderMotCle($mot_cle) { |
return md5(mb_strtolower(trim($mot_cle))); |
} |
protected function decoderMotsClesObs($utilisateur_id, $mots_cles) { |
return $this->decoderMotsCles($utilisateur_id, $mots_cles, self::TYPE_OBS); |
} |
protected function decoderMotsClesImg($utilisateur_id, $mots_cles) { |
return $this->decoderMotsCles($utilisateur_id, $mots_cles, self::TYPE_IMG); |
} |
private function decoderMotsCles($utilisateur_id, $mots_cles, $type) { |
$mots = array(); |
if (! $this->etreNull($mots_cles)) { |
$utilisateur_id = $this->bdd->quote($utilisateur_id); |
$mots_cles = $this->protegerMotsCles($mots_cles, $type); |
if (! $this->etreNull($mots_cles)) { |
$table = ($type == self::TYPE_IMG) ? 'cel_mots_cles_images' : 'cel_mots_cles_obs' ; |
$requete = 'SELECT cmc_mot_cle as mot_cle '. |
"FROM $table ". |
"WHERE cmc_id_mot_cle_utilisateur IN ($mots_cles) ". |
"AND cmc_id_proprietaire = $utilisateur_id "; |
$elements = $this->executerRequete($requete); |
if (is_array($elements)) { |
foreach ($elements as $mot) { |
$mots[] = $mot['mot_cle']; |
} |
} |
} |
} |
return $mots; |
} |
private function protegerMotsCles($mots_cles, $type) { |
$separateur = ($type == self::TYPE_IMG) ? ',' : ';' ; |
$mots_cles = $this->traiterValeursMultiples($mots_cles, $separateur); |
return $mots_cles; |
} |
protected function traiterValeursMultiples($valeurs, $separateur_entree = ',' , $separateur_sortie = ',') { |
if (! $this->etreNull($valeurs)) { |
$valeurs_a_proteger = explode($separateur_entree,trim(trim($valeurs), $separateur_entree)); |
foreach ($valeurs_a_proteger as $valeur) { |
$valeurs_protegees[] = $this->bdd->quote($valeur); |
} |
$valeurs = implode($separateur_sortie, $valeurs_protegees); |
} |
return ($this->etreNull($valeurs)) ? null : $valeurs; |
} |
//+----------------------------------------------------------------------------------------------------------------+ |
// GESTION DES SQUELETTES PHP |
/** |
* Méthode prenant en paramètre un chemin de fichier squelette et un tableau associatif de données, |
* en extrait les variables, charge le squelette et retourne le résultat des deux combinés. |
* |
* @param String $fichier le chemin du fichier du squelette |
* @param Array $donnees un tableau associatif contenant les variables a injecter dans le squelette. |
* |
* @return boolean false si le squelette n'existe pas, sinon la chaine résultat. |
*/ |
public static function traiterSquelettePhp($fichier, Array $donnees = array()) { |
$sortie = false; |
if (file_exists($fichier)) { |
// Extraction des variables du tableau de données |
extract($donnees); |
// Démarage de la bufferisation de sortie |
ob_start(); |
// Si les tags courts sont activés |
if ((bool) @ini_get('short_open_tag') === true) { |
// Simple inclusion du squelette |
include $fichier; |
} else { |
// Sinon, remplacement des tags courts par la syntaxe classique avec echo |
$html_et_code_php = self::traiterTagsCourts($fichier); |
// Pour évaluer du php mélangé dans du html il est nécessaire de fermer la balise php ouverte par eval |
$html_et_code_php = '?>'.$html_et_code_php; |
// Interprétation du html et du php dans le buffer |
echo eval($html_et_code_php); |
} |
// Récupèration du contenu du buffer |
$sortie = ob_get_contents(); |
// Suppression du buffer |
@ob_end_clean(); |
} else { |
$msg = "Le fichier du squelette '$fichier' n'existe pas."; |
trigger_error($msg, E_USER_WARNING); |
} |
// Retourne le contenu |
return $sortie; |
} |
/** |
* Fonction chargeant le contenu du squelette et remplaçant les tags court php (<?= ...) par un tag long avec echo. |
* |
* @param String $chemin_squelette le chemin du fichier du squelette |
* |
* @return string le contenu du fichier du squelette php avec les tags courts remplacés. |
*/ |
private static function traiterTagsCourts($chemin_squelette) { |
$contenu = file_get_contents($chemin_squelette); |
// Remplacement de tags courts par un tag long avec echo |
$contenu = str_replace('<?=', '<?php echo ', $contenu); |
// Ajout systématique d'un point virgule avant la fermeture php |
$contenu = preg_replace("/;*\s*\?>/", "; ?>", $contenu); |
return $contenu; |
} |
} |
?> |
/branches/v1.6-croc/jrest/scripts/ImagesMaintenance.php |
---|
New file |
0,0 → 1,120 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Réalise la maintenance des images. |
* Action : |
* - suppression_images_orphelines : supprime les images qui ne sont plus dans la bdd. |
* Utilisation : /opt/lampp/bin/php cli.php ImagesMaintenance suppression_images_orphelines |
* |
* @category php 5.2 |
* @package Cel/Scripts |
* @author Aurelien PERONNET <aurelien@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org) |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version $Id$ |
*/ |
class ImagesMaintenance { |
private $bdd = null; |
private $script = null; |
private $chemin_base_images = ''; |
private $nbFichiersSupprimes = 0; |
private $espaceLibere = 0; |
public function __construct(Conteneur $conteneur) { |
$this->chemin_base_images = $conteneur->getParametre('cel.chemin_images'); |
$this->bdd = $conteneur->getBdd(); |
$this->script = $conteneur->getScript(); |
} |
public function executer($arguments) { |
if (isset($arguments[0]) == false) { |
throw new Exception("Veuillez indiquer l'action à réaliser en paramètre.", E_USER_ERROR); |
} |
$action = $arguments[0]; |
switch ($action) { |
case 'suppression_images_orphelines' : |
$this->supprimerFichiersImagesOrphelins(); |
break; |
} |
} |
private function supprimerFichiersImagesOrphelins() { |
$profondeur = 1; |
$this->itererRecursivement($this->chemin_base_images, $profondeur); |
print "Suppression des images orphelines effectuées\n"; |
$fichiersSupprimes = $this->nbFichiersSupprimes; |
print "Fichiers orphelins détectés et supprimés : $fichiersSupprimes\n"; |
$espaceLibere = $this->convertirOctets($this->espaceLibere); |
print "Espace disque économisé : $espaceLibere \n"; |
} |
private function itererRecursivement($dossier, $profondeur) { |
$dossiersAIgnorer = array('export'); |
$iterateur = new DirectoryIterator($dossier); |
foreach ($iterateur as $element) { |
if ($element->isDot() || in_array($element->getBasename(), $dossiersAIgnorer)) { |
continue; |
} |
$indentation = str_repeat("\t", ($profondeur - 1)); |
if ($element->isDir()) { |
$profondeur_dossier_fils = $profondeur + 1; |
print "$indentation Analyse dossier : {$element->getPathname()}\n"; |
$this->itererRecursivement($element->getPathname(), $profondeur_dossier_fils); |
} else { |
print "$indentation Vérif fichier : {$element->getBasename()}\n"; |
$existe = $this->verifierPresenceImageDansBdd($element); |
if ($existe == false) { |
$this->supprimerFichierImage($element); |
} |
} |
} |
} |
private function verifierPresenceImageDansBdd($element) { |
$existe = true; |
$nom_fichier = $element->getFilename(); |
if (preg_match('/^([0-9]{3})_([0-9]{3})_([0-9]{3})_[^.]+[.](jpg|xml)$/', $nom_fichier, $match)) { |
$id_image = $match[1].$match[2].$match[3]; |
$id_image = ltrim($id_image, '0'); |
$requete = 'SELECT COUNT(ci_id_image) AS image_existe '. |
'FROM cel_images '. |
"WHERE ci_id_image = $id_image "; |
$imageExiste = $this->bdd->requeter($requete, Bdd::SQL_RETOUR_COLONNE); |
if ($imageExiste < 1) { |
print "Image $id_image introuvable dans la base de données\n"; |
$existe = false; |
} |
} |
return $existe; |
} |
private function supprimerFichierImage($element) { |
$fichier = $element->getPathname(); |
$fichierNom = $element->getBasename(); |
if (file_exists($fichier)) { |
$this->espaceLibere += $element->getSize(); |
if (unlink($fichier) === false) { |
throw new Exception("Problème lors de la suppression du fichier : $fichier \n", E_USER_ERROR); |
} else { |
$this->nbFichiersSupprimes++; |
print "Suppression du fichier : $fichierNom\n"; |
} |
} else { |
throw new Exception("Problème le fichier n'existe pas : $fichier\n", E_USER_ERROR); |
} |
} |
private function convertirOctets($taille) { |
$units = array('B', 'KB', 'MB', 'GB', 'TB'); |
for ($i = 0; $taille >= 1024 && $i < 4; $i++) $taille /= 1024; |
return round($taille, 2).' '.$units[$i]; |
} |
} |
?> |
/branches/v1.6-croc/jrest/scripts/ExtracteurMeta.php |
---|
New file |
0,0 → 1,183 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Script d'extration des métadonnées des images pour intégration dans la BDD v2. |
* Utilisation : /opt/lampp/bin/php cli.php ExtracteurMeta |
* |
* @category php 5.2 |
* @package Cel/Scripts |
* @author Aurelien PERONNET <aurelien@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org) |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version $Id$ |
*/ |
class ExtracteurMeta { |
const DROIT = 0705; |
private $chemin_images = ''; |
private $bdd = null; |
private $script = null; |
private $idImg = null; |
private $metaComplet = null; |
private $exif = null; |
private $iptc = null; |
private $xmp = null; |
private $makerNotes = null; |
private $metaAutres = null; |
public function __construct(Conteneur $conteneur) { |
$this->chemin_images = $conteneur->getParametre('cel.chemin_images'); |
$this->bdd = $conteneur->getBdd(); |
$this->script = $conteneur->getScript(); |
} |
public function executer($arguments) { |
echo "EXTRACTION des MÉTADONNÉES\n"; |
echo "Vérification config : ".$this->verifierConfig()."\n"; |
$images = $this->obtenirImagesEnBdd(); |
foreach ($images as $img) { |
$this->idImg = $img['id_image']; |
$cheminImage = $this->obtenirCheminImageOriginale($this->idImg); |
if (file_exists($cheminImage)) { |
$cmd = "exiftool -X -file:comment $cheminImage"; |
$metaFile = $this->executerCommandeSysteme($cmd); |
if ($this->neccessiterRemplacement($metaFile) === true) { |
//print "Remplacement : {$this->idImg} \n"; |
$cmd = "exiftool -X -D -U -b -c '%.6f' -d '%Y-%m-%d %H:%M:%S' -All $cheminImage"; |
$this->metaComplet = $this->executerCommandeSysteme($cmd); |
$cmd = "exiftool -X -D -c '%.6f' -d '%Y-%m-%d %H:%M:%S' -exif:all $cheminImage"; |
$this->exif = $this->executerCommandeSysteme($cmd); |
$cmd = "exiftool -X -D -c '%.6f' -d '%Y-%m-%d %H:%M:%S' -iptc:all $cheminImage"; |
$this->iptc = $this->executerCommandeSysteme($cmd); |
$cmd = "exiftool -X -D -c '%.6f' -d '%Y-%m-%d %H:%M:%S' -xmp:all $cheminImage"; |
$this->xmp = $this->executerCommandeSysteme($cmd); |
$cmd = "exiftool -X -D -c '%.6f' -d '%Y-%m-%d %H:%M:%S' -makernotes:all $cheminImage"; |
$this->makerNotes = $this->executerCommandeSysteme($cmd); |
$cmd = "exiftool -X -D -c '%.6f' -d '%Y-%m-%d %H:%M:%S' --exif:all --iptc:all --xmp:all --makernotes:all $cheminImage"; |
$this->metaAutres = $this->executerCommandeSysteme($cmd); |
$this->ecrireFichierRdf(); |
$this->mettreAJourBdd(); |
} |
} else { |
//print "Fichier image '{$this->idImg}' introuvable\n"; |
} |
$this->script->afficherAvancement("Analyse des images"); |
} |
print "\n"; |
} |
private function verifierConfig() { |
if (empty($this->chemin_images)) { |
$message = "Vous devez indiquer le dossier contenant la hiérarchie des images dans le paramètre : ". |
"[cel] chemin_images"; |
$code = (string) E_USER_ERROR; |
throw new Exception($message); |
} |
return 'OK'; |
} |
private function obtenirImagesEnBdd() { |
$requete = 'SELECT id_image FROM cel_images '; |
$images = $this->bdd->requeter($requete); |
return $images; |
} |
private function executerCommandeSysteme($commande) { |
$handle = popen($commande, 'r'); |
$metaXml = ''; |
while (!feof($handle)) { |
$metaXml .= fread($handle, 8192); |
} |
fclose($handle); |
return $metaXml; |
} |
private function obtenirCheminImageRDF() { |
return $this->obtenirCheminImage('RDF', 'xml'); |
} |
private function obtenirCheminImageOriginale() { |
return $this->obtenirCheminImage('O'); |
} |
private function obtenirCheminImage($format, $extension = 'jpg') { |
$nom = $this->convertirIdBddVersNomFichier($format, $extension); |
$cheminDossier = $this->obtenirDossierPourFormat($format); |
if (file_exists($cheminDossier) === false) { |
$this->creerDossier($cheminDossier); |
} |
return $cheminDossier.'/'.$nom; |
} |
private function convertirIdBddVersNomFichier($format, $extension) { |
$id_avec_zeros = sprintf('%09s', $this->idImg) ; |
$id_avec_zeros_underscores = wordwrap($id_avec_zeros, 3 , '_', true) ; |
$nom_fichier = $id_avec_zeros_underscores.'_'.$format.'.'.$extension; |
return $nom_fichier; |
} |
private function obtenirDossierPourFormat($format) { |
$id = sprintf('%09s', $this->idImg); |
$id = wordwrap($id, 3 , '_', true); |
list($dossierNiveau1, $dossierNiveau2) = explode('_', $id); |
$chemin_sur_serveur_final = $this->chemin_images.'/'.$dossierNiveau1.'/'.$dossierNiveau2.'/'.$format; |
return $chemin_sur_serveur_final; |
} |
private function creerDossier($cheminDossier) { |
umask(0); |
if (mkdir($cheminDossier, self::DROIT, true) === false) { |
$message = "Problème durant la création du dossier '$cheminDossier'."; |
throw new Exception($message); |
} |
} |
private function neccessiterRemplacement($metaXml) { |
$meta = new SimpleXMLElement($metaXml); |
$rdf = $meta->children('http://www.w3.org/1999/02/22-rdf-syntax-ns#'); |
$file = $rdf->children('http://ns.exiftool.ca/File/1.0/'); |
return strpos($file->Comment, "CREATOR: gd-jpeg") === false ? true : false; |
} |
private function ecrireFichierRdf() { |
$cheminRdf = $this->obtenirCheminImageRDF($this->idImg); |
file_put_contents($cheminRdf, $this->metaComplet); |
} |
private function mettreAJourBdd() { |
$idImg = $this->bdd->proteger($this->idImg); |
$exif = $this->bdd->proteger($this->exif); |
$iptc = $this->bdd->proteger($this->iptc); |
$xmp = $this->bdd->proteger($this->xmp); |
$makerNotes = $this->bdd->proteger($this->makerNotes); |
$autres = $this->bdd->proteger($this->metaAutres); |
$requete = 'UPDATE cel_images SET '. |
" meta_exif = $exif, ". |
" meta_iptc = $iptc, ". |
" meta_xmp = $xmp, ". |
" meta_makernote = $makerNotes, ". |
" meta_autres = $autres ". |
"WHERE id_image = $idImg "; |
$resultat = $this->bdd->executer($requete); |
echo "Mise à jour image '{$this->idImg}' : $resultat\n"; |
} |
} |
?> |
/branches/v1.6-croc/jrest/scripts/MigrationObs.php |
---|
New file |
0,0 → 1,635 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Script de migration des Observations de la version 1 de la base de données du CEL à la v2. |
* Utilisation : /opt/lampp/bin/php cli.php MigrationObs |
* |
* @category php 5.2 |
* @package Cel/Scripts |
* @author Aurelien PERONNET <aurelien@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org) |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version $Id$ |
*/ |
class MigrationObs { |
const truncate = true; //Doit on vider les tables de destination ? |
const dry_run = false; |
const PATTERN_LAT = '/^[+-]?(?:[1-9][0-9]|[0-9])(?:[.][0-9]+|)$/'; |
const PATTERN_LNG = '/^[+-]?(?:1[0-8][0-9]|[1-9][0-9]|[0-9])(?:[.][0-9]+|)$/'; |
private $bdd = null; |
private $script = null; |
public static $bdd_cel_migration; |
public static $bdd_utilisateurs; |
private $communesOubliees = array(); |
private $tableau_utilisateurs = array(); |
private $tableau_mots_cles = array(); |
private $tableau_zones_geo = array(); |
/** Tableau associatif permettant de stocker l'avancement dans une boucle. |
* La clé est un md5 du message à afficher au démarrage de la boucle. |
* @var array |
*/ |
private static $avancement = array(); |
private $tableau_nouveau_ancien = array( |
'id_observation' => 'id', |
'ordre' => 'ordre', |
'ce_utilisateur' => 'traiterIdentifiantUtilisateur', |
'prenom_utilisateur' => 'traiterPrenomUtilisateur', |
'nom_utilisateur' => 'traiterNomUtilisateur', |
'courriel_utilisateur' => 'traiterCourrielUtilisateur', |
'nom_sel' => 'nom_sel', |
'nom_sel_nn' => 'num_nom_sel', |
'nom_ret' => 'nom_ret', |
'nom_ret_nn' => 'num_nom_ret', |
'nt' => 'num_taxon', |
'famille' => 'famille', |
'nom_referentiel' => 'traiterReferentiel', |
'ce_zone_geo' => 'traiterIdentifiantZoneGeo', |
'zone_geo' => 'location', |
'lieudit' => 'lieudit', |
'station' => 'station', |
'milieu' => 'milieu', |
'latitude' => 'traiterLat', |
'longitude' => 'traiterLng', |
'geodatum' => 'traiterGeodatum', |
'date_observation' => 'date_observation', |
'mots_cles_texte' => 'traiterMotsClesTexte', |
'commentaire' => 'commentaire', |
'transmission' => 'transmission', |
'date_creation' => 'date_creation', |
'date_modification' => 'date_modification', |
'date_transmission' => 'date_transmission' |
); |
private $tableau_ancien_nouveau = array( |
'id' => 'id_observation', |
'identifiant' => '', |
'prenom_utilisateur' => 'prenom_utilisateur', |
'nom_utilisateur' => 'nom_utilisateur', |
'ordre' => 'ordre', |
'nom_sel' => 'nom_sel', |
'num_nom_sel' => 'nom_sel_nn', |
'nom_ret' => 'nom_ret', |
'num_nom_ret' => 'nom_ret_nn', |
'num_taxon' => 'nt', |
'famille' => 'famille', |
'location' => '', |
'id_location' => '', |
'date_observation' => 'date_observation', |
'lieu_dit' => 'lieudit', |
'station' => 'station', |
'milieu' => 'milieu', |
'commentaire' => 'commentaire', |
'transmission' => 'transmission', |
'date_creation' => 'date_creation', |
'date_modification' => 'date_modification', |
'date_transmission' => 'date_transmission', |
'mots_cles' => '', |
'coord_x' => 'latitude', |
'coord_y' => 'longitude', |
'ref_geo' => 'geodatum' |
); |
public function __construct(Conteneur $conteneur) { |
$bddMigration = $conteneur->getParametre('database_cel.database_migration'); |
if ($bddMigration == null || $bddMigration == '') { |
echo 'Attention la variable de configuration database_migration dans la section database_cel, contenant la base de données d\'arrivée, doit être remplie '."\n"; |
exit; |
} |
$bddIdentification = $conteneur->getParametre('database_ident.database'); |
if ($bddIdentification == null || $bddIdentification == '') { |
echo 'Attention la variable de configuration database dans la section database_ident, contenant la base de données utilisateurs, doit être remplie '."\n"; |
exit; |
} |
self::$bdd_cel_migration = $conteneur->getParametre('database_cel.database_migration'); |
self::$bdd_utilisateurs = $conteneur->getParametre('database_ident.database'); |
$this->bdd = $conteneur->getBdd(); |
$this->script = $conteneur->getScript(); |
} |
/** |
* Méthode appelée pour executer le script. |
*/ |
public function executer($params) { |
echo "--MIGRATION DES OBSERVATIONS --------------------------------------\n"; |
//1. TEMPORAIRE : vider les tables de destinations |
if (self::truncate) { |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 0. Vider les tables ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$nouvellesTables = array('cel_obs', 'cel_utilisateurs_infos', 'cel_zones_geo'); |
foreach ($nouvellesTables as $nomTable) { |
echo 'Vider la table '.$nomTable.'...'; |
$requeteTruncate = 'TRUNCATE TABLE '.self::$bdd_cel_migration.'.'.$nomTable; |
$resultatTruncate = $this->bdd->executer($requeteTruncate); |
echo "ok \n"; |
} |
} |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 1. Paramétrage ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->getUtilisateurs(); |
$this->getMotsCles(); |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 2. Migration des utilisateurs ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->migrerUtilisateurs(); |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 3. Migration des zone géographiques ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->migrerZonesGeo(); |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 4. Migration des observations ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->migrerObs(); |
$this->mettreANullPrenomNomVide(); |
$this->ordonnerObs(); |
} |
private function executerRequeteSimple($requete) { |
// Fonction de commodité pour afficher les requetes au lieu de les executer |
if (self::dry_run) { |
echo str_replace('),','),'."\n", $requete); |
return true; |
} else { |
return $this->bdd->executer($requete); |
} |
} |
private function getUtilisateurs() { |
echo "SELECTION DES UTILISATEURS\n"; |
$requete = 'SELECT DISTINCT u_id AS id, u_mail AS mail, u_name AS nom, u_surname AS prenom, u_passwd AS pass '. |
'FROM cel_inventory INNER JOIN '.self::$bdd_utilisateurs.'.annuaire_tela ON (u_mail = identifiant) '; |
$tableau_utilisateurs = $this->bdd->requeter($requete); |
foreach( $tableau_utilisateurs as &$utilisateur) { |
$this->tableau_utilisateurs[$utilisateur['mail']] = $utilisateur; |
} |
echo sizeof($this->tableau_utilisateurs)." utilisateurs sélectionnés\n"; |
} |
private function getMotsCles() { |
echo "SELECTION DES MOTS-CLES \n"; |
$requete = 'SELECT cmc_id_proprietaire as id_utilisateur, cmc_id_mot_cle_utilisateur as id_mot_cle, '. |
'cmc_mot_cle as mot_cle '. |
'FROM cel_mots_cles_obs '; |
$tableau_mots_cles = $this->bdd->requeter($requete); |
foreach( $tableau_mots_cles as &$mot_cle) { |
$this->tableau_mots_cles[$mot_cle['id_utilisateur']][$mot_cle['id_mot_cle']] = $mot_cle; |
} |
echo sizeof($this->tableau_mots_cles)." mots-clés sélectionnés\n"; |
} |
private function migrerUtilisateurs() { |
$requete = 'INSERT INTO '.self::$bdd_cel_migration.'.cel_utilisateurs_infos '. |
'(id_utilisateur) '. |
'VALUES '; |
$sous_requete = array(); |
foreach ($this->tableau_utilisateurs as $id => &$utilisateur) { |
$sous_requete[] = '('.$this->bdd->proteger($utilisateur['id']).')'; |
} |
$requete .= implode(',', $sous_requete); |
$migration_utilisateurs = $this->executerRequeteSimple($requete); |
if ($migration_utilisateurs) { |
echo "Migration utilisateurs : ".count($sous_requete); |
} else { |
exit('Erreur lors de la migration des utilisateurs '."\n"); |
} |
echo "\n"; |
} |
private function migrerZonesGeo() { |
$pas = 5000; |
//SELECTIONNER LE NOMBRE DE ZONE GEO |
$requete_nombreZonesGeo = 'SELECT count(*) as nb FROM locations'; |
$resultatNbZonesGeo = $this->bdd->requeter($requete_nombreZonesGeo, Bdd::SQL_RETOUR_COLONNE); |
$nbZones = (int) $resultatNbZonesGeo; |
$nbTotal = 0; |
for($i = 0; $i <= $nbZones ; $i += $pas) { |
$requete_selection_zones_geo = 'SELECT * FROM locations LIMIT '.$i.', '.$pas; |
$zones_geo = $this->bdd->requeter($requete_selection_zones_geo); |
$requete_insertion_nouvelles_zones_geo = 'INSERT INTO '.self::$bdd_cel_migration.'.cel_zones_geo '. |
'(id_zone_geo, code, nom, utm_secteur, utm_x, utm_y, wgs84_latitude, wgs84_longitude, date_modification) '. |
'VALUES '; |
$sous_requete_insertion_valeurs = ''; |
if(count($zones_geo) > 0) { |
foreach($zones_geo as $zone_geo) { |
$zone_geo['nouveau_code_geo'] = 'INSEE-C:'.$zone_geo['insee_code']; |
$lat_long = $this->convertirUtmVersLatLong($zone_geo['x_utm'],$zone_geo['y_utm'],$zone_geo['sector']); |
$indice_tableau_localites = $this->construireIndiceTableauLocalites($zone_geo['name'], $zone_geo['insee_code']); |
$this->tableau_zones_geo[$indice_tableau_localites] = $zone_geo; |
$sous_requete_insertion_valeurs .= '('.$this->bdd->proteger($zone_geo['nouveau_code_geo']).','. |
$this->bdd->proteger($zone_geo['insee_code']).','. |
$this->bdd->proteger($zone_geo['name']).','. |
$this->bdd->proteger($zone_geo['sector']).','. |
$this->bdd->proteger($zone_geo['x_utm']).','. |
$this->bdd->proteger($zone_geo['y_utm']).','. |
$this->bdd->proteger($lat_long['lat']).','. |
$this->bdd->proteger($lat_long['long']).','. |
$this->bdd->proteger($zone_geo['update_date']). |
'),'; |
} |
$sous_requete_insertion_valeurs = rtrim($sous_requete_insertion_valeurs,','); |
$requete_insertion_nouvelles_zones_geo .= $sous_requete_insertion_valeurs; |
$migration_zones_geo = $this->executerRequeteSimple($requete_insertion_nouvelles_zones_geo); |
} else { |
echo 'Fin de migration des zones géo '."\n"; |
return; |
} |
if ($migration_zones_geo) { |
$nbTotal ++; |
$this->script->afficherAvancement('Migration des zones (par '.$pas.')', $nbTotal); |
} else { |
exit('Erreur lors de la migration des zones géo '.$i.' à '.($i+$pas)."\n"); |
} |
} |
echo "\n"; |
} |
private function convertirUtmVersLatLong($x, $y, $sector) { |
$lat_long = array(); |
$convertisseur = new gPoint(); |
$convertisseur->setUTM($x, $y, $sector); |
$convertisseur->convertTMtoLL(); |
$lat_long['lat'] = str_replace(',','.',$convertisseur->Lat()); |
$lat_long['long'] = str_replace(',','.',$convertisseur->Long()); |
return $lat_long; |
} |
private function migrerObs() { |
$debut = 0; |
$pas = 1000; |
$nbTotal = 0; |
//Selectionner le nombre d'observations |
$requeteNbObs = "SELECT COUNT(*) as nb FROM cel_inventory"; |
$fin = $this->bdd->requeter($requeteNbObs, Bdd::SQL_RETOUR_COLONNE); |
for ($i = $debut; $i < $fin ; $i += $pas) { |
$requete_selection_obs = 'SELECT * '. |
'FROM cel_inventory '. |
'ORDER BY identifiant '. |
'LIMIT '.$i.','.$pas; |
$observations = $this->bdd->requeter($requete_selection_obs); |
$requete_insertion_observations = 'INSERT IGNORE INTO '.self::$bdd_cel_migration.'.cel_obs ('; |
foreach ($this->tableau_nouveau_ancien as $nouveau_champ => $ancien_champ) { |
$requete_insertion_observations .= $nouveau_champ.','; |
} |
$requete_insertion_observations = rtrim($requete_insertion_observations, ','); |
$requete_insertion_observations = $requete_insertion_observations.') VALUES '; |
if (count($observations) > 0) { |
foreach($observations as $observation) { |
$nouvelle_observation = $this->traiterLigneObservation($observation); |
$nouvelle_observation = array_map(array($this, 'protegerSiNonNull'), $nouvelle_observation); |
$requete_insertion_observations .= '('.join(',', array_values($nouvelle_observation)).'),'; |
} |
$requete_insertion_observations = rtrim($requete_insertion_observations, ','); |
$migration_observations = $this->executerRequeteSimple($requete_insertion_observations); |
} else { |
echo "Fin de migration des observations\n"; |
return; |
} |
if ($migration_observations) { |
$nbTotal ++; |
$this->script->afficherAvancement('Migration des observations (par '.$pas.')', $nbTotal); |
} else { |
exit('Erreur lors de la migration des observation de '.$i.' à '.($i+$pas)."\n"); |
} |
} |
echo "\n"; |
if (sizeof($this->communesOubliees) > 0) { |
echo "xxxxxxxxx Communes ignorées : ".sizeof($this->communesOubliees)." xxxxxxxxx \n"; |
} |
} |
private function ordonnerObs() { |
$requete = 'ALTER TABLE '.self::$bdd_cel_migration.'.cel_obs ORDER BY id_observation'; |
$this->executerRequeteSimple($requete); |
} |
private function traiterLigneObservation($obs) { |
$nouvelle_obs = array(); |
foreach($this->tableau_nouveau_ancien as $nouveau_champ_obs => $ancien_champ_obs) { |
if ($this->estUnChampATraiter($ancien_champ_obs)) { |
if (method_exists($this, $ancien_champ_obs)) { |
$nouvelle_obs[$nouveau_champ_obs] = $this->$ancien_champ_obs($obs); |
} else { |
$nouvelle_obs[$nouveau_champ_obs] = ''; |
} |
} else { |
if ($obs[$ancien_champ_obs] == '000null' || $obs[$ancien_champ_obs] == 'null' || trim($obs[$ancien_champ_obs]) == '') { |
$obs[$ancien_champ_obs] = 'NULL'; |
} |
if (($ancien_champ_obs == 'coord_x' || $ancien_champ_obs == 'coord_y') && ($obs[$ancien_champ_obs] == '0' || $obs[$ancien_champ_obs] == 0)) { |
$obs[$ancien_champ_obs] = 'NULL'; |
} |
$nouvelle_obs[$nouveau_champ_obs] = $obs[$ancien_champ_obs]; |
} |
} |
return $nouvelle_obs; |
} |
private function protegerSiNonNull($valeur) { |
if ($valeur != 'NULL') { |
$valeur = $this->bdd->proteger($valeur); |
} |
return $valeur; |
} |
private function estUnChampATraiter($champ) { |
return strpos($champ,'traiter') !== false; |
} |
private function traiterReferentiel($observation) { |
$retour = 'NULL'; |
if ($observation['num_nom_sel'] != '' && $observation['num_nom_sel'] != '0') { |
$retour = 'bdnff:4.02'; |
if (isset($observation['nom_referentiel'])) { |
$retour = ($observation['nom_referentiel'] == 'bdtfx:1.01') ? 'bdtfx:1.01' : 'bdnff:4.02'; |
} |
} |
return $retour; |
} |
private function traiterLat(&$observation) { |
if ($this->bdd->etreNull($observation['coord_x'])) { |
$observation['coord_x'] = 'NULL'; |
} else if (preg_match(self::PATTERN_LAT, $observation['coord_x']) == false) { |
$latNote = 'Latitude éronnée : '.$observation['coord_x']; |
if ($this->bdd->etreNull($observation['commentaire'])) { |
$observation['commentaire'] = $latNote; |
} else { |
$observation['commentaire'] .= "\n".$latNote; |
} |
$observation['coord_x'] = 'NULL'; |
} |
$retour = $observation['coord_x']; |
return $retour; |
} |
private function traiterLng(&$observation) { |
if ($this->bdd->etreNull($observation['coord_y'])) { |
$observation['coord_y'] = 'NULL'; |
} else if (preg_match(self::PATTERN_LNG, $observation['coord_y']) == false) { |
$lngNote = 'Longitude éronnée : '.$observation['coord_y']; |
if ($this->bdd->etreNull($observation['commentaire'])) { |
$observation['commentaire'] = $lngNote; |
} else { |
$observation['commentaire'] .= "\n".$lngNote; |
} |
$observation['coord_y'] = 'NULL'; |
} |
$retour = $observation['coord_y']; |
return $retour; |
} |
private function traiterGeodatum($observation) { |
$retour = 'NULL'; |
if ($observation['coord_x'] != 'NULL' && $observation['coord_y'] != 'NULL') { |
$retour = 'WGS84'; |
} |
return $retour; |
} |
private function traiterMotsClesTexte($ligne_observation) { |
$mail_observation = $ligne_observation['identifiant']; |
$retour = $ligne_observation['mots_cles']; |
if (isset($this->tableau_mots_cles[$mail_observation])) { |
$mots_cles_tableau = $this->parserMotsCles($mail_observation, $ligne_observation['mots_cles'], ';'); |
$retour = join(',', $mots_cles_tableau); |
$retour = ltrim($retour, ',,') ; |
} |
return $retour; |
} |
private function parserMotsCles($utilisateur, $mot_cles, $separateur = ',') { |
$tableau_mots_cles = explode($separateur,$mot_cles); |
$tableau_mots_cles_formates = array(); |
foreach ($tableau_mots_cles as $mot_cle) { |
$mot_cle = str_replace($separateur.$separateur,'',$mot_cle); |
$mot_cle = str_replace('null','',$mot_cle); |
if ($this->estUnIdentifiantMotCle($mot_cle)) { |
// certains mots clés mal formatés contiennent des virgules |
if (strpos($mot_cle,',') !== false) { |
$tab_mot_cle_mal_formate = explode(',',$mot_cle); |
foreach ($tab_mot_cle_mal_formate as $mot_cle_mal_formate) { |
if ($this->estUnIdentifiantMotCle($mot_cle_mal_formate)) { |
$tableau_mots_cles_formates[$mot_cle_mal_formate] = $this->tableau_mots_cles[$utilisateur][$mot_cle_mal_formate]['mot_cle']; |
} |
} |
} else { |
// on met le mot clé dans sa propre case afin d'éviter |
// facilement les doublons provoqués par de mauvais formatages |
if (isset($this->tableau_mots_cles[$utilisateur][$mot_cle]) && trim($this->tableau_mots_cles[$utilisateur][$mot_cle]['mot_cle']) != '') { |
$tableau_mots_cles_formates[$mot_cle] = $this->tableau_mots_cles[$utilisateur][$mot_cle]['mot_cle']; |
} |
} |
} |
} |
return $tableau_mots_cles_formates; |
} |
private function estUnIdentifiantMotCle($chaine) { |
return trim($chaine) != '' && preg_match('/[0-9A-Z]+\.[0-9A-Z]+/i', $chaine) ; |
} |
private function traiterIdentifiantUtilisateur($ligne_observation) { |
$mail_observation = $ligne_observation['identifiant']; |
$retour = $this->renvoyerIdPourMigration($mail_observation); |
return $retour; |
} |
private function traiterPrenomUtilisateur($ligne_observation) { |
$mail_observation = $ligne_observation['identifiant']; |
$retour = ''; |
if (isset($this->tableau_utilisateurs[$mail_observation])) { |
$prenom = $this->tableau_utilisateurs[$mail_observation]['prenom']; |
$retour = self::formaterMotPremiereLettreChaqueMotEnMajuscule($prenom); |
} |
return $retour; |
} |
private function traiterNomUtilisateur($ligne_observation) { |
$mail_observation = $ligne_observation['identifiant']; |
$retour = 'NULL'; |
if (isset($this->tableau_utilisateurs[$mail_observation])) { |
$nom = $this->tableau_utilisateurs[$mail_observation]['nom']; |
$retour = self::formaterMotEnMajuscule($nom); |
} |
return $retour; |
} |
private function traiterCourrielUtilisateur($observation) { |
$courriel = $observation['identifiant']; |
$retour = 'NULL'; |
if ($this->mailValide($courriel)) { |
$retour = $courriel; |
} |
return $retour; |
} |
public static function formaterMotPremiereLettreChaqueMotEnMajuscule($chaine, $encodage= 'UTF-8') { |
$chaine = str_replace('-', ' - ', $chaine); |
$chaine = mb_strtolower($chaine, $encodage); |
$chaine = mb_convert_case($chaine, MB_CASE_TITLE, $encodage); |
$chaine = str_replace(' - ', '-', $chaine); |
return $chaine; |
} |
public static function formaterMotEnMajuscule($chaine, $encodage= 'UTF-8') { |
return mb_convert_case($chaine, MB_CASE_UPPER, $encodage); |
} |
private function traiterZoneGeo($ligne_observation) { |
$zone_geo = $ligne_observation['location']; |
if ($ligne_observation['id_location'] != null && !is_numeric($ligne_observation['id_location']) && $ligne_observation['id_location'] != '000null') { |
$id_zone_geo_ancienne = $ligne_observation['id_location']; |
if ($zone_geo != '') { |
$id_zone_geo_ancienne = '('.$id_zone_geo_ancienne.')'; |
} |
$zone_geo .= $id_zone_geo_ancienne; |
} else if ($ligne_observation['location'] == null || $ligne_observation['location'] == "" || $ligne_observation['location'] == "000null") { |
if ($ligne_observation['id_location'] != '' && $ligne_observation['id_location'] != '000null') { |
$id_zone_geo_ancienne = $ligne_observation['id_location']; |
$id_zone_geo_ancienne = $id_zone_geo_ancienne; |
$zone_geo = $id_zone_geo_ancienne; |
} else { |
$zones_geo = 'NULL'; |
} |
} |
return $zone_geo; |
} |
private function traiterIdentifiantZoneGeo($ligne_observation) { |
$id_zone_geo = ''; |
if ($ligne_observation['id_location'] != '' && $ligne_observation['id_location'] != '000null') { |
$indice = $this->construireIndiceTableauLocalites($ligne_observation['location'], $ligne_observation['id_location']); |
if (isset($this->tableau_zones_geo[$indice])) { |
$id_zone_geo = $this->tableau_zones_geo[$indice]['nouveau_code_geo']; |
} else { |
if ($ligne_observation['location'] != "000null") { |
$this->communesOubliees[$indice] = false; |
} |
} |
} else { |
$id_zone_geo = 'NULL'; |
} |
return $id_zone_geo; |
} |
private function construireIndiceTableauLocalites($nom, $id) { |
$nom = htmlentities($nom, ENT_NOQUOTES, 'UTF-8'); |
$nom = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $nom); |
$nom = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $nom); // pour les ligatures e.g. 'œ' |
$nom = preg_replace('#&[^;]+;#', '', $nom); // supprime les autres caractères |
$nom = str_replace("'",'_',$nom); |
$nom = str_replace(' ','_',$nom); |
$nom = str_replace('-','_',$nom); |
$nom = str_replace(' ','_',$nom); |
$indice = strtolower($nom).substr($id, 0, 2); |
return $indice; |
} |
// Par défaut, on garde l'utilisateur tel quel (cas de la chaine de session des utilisateur anonymes) |
private function renvoyerIdPourMigration($utilisateur) { |
$retour = $utilisateur; |
// si le mail correspond a un utilisateur de la bdd |
if (isset($this->tableau_utilisateurs[$utilisateur])) { |
// on renvoie son id |
$retour = $this->tableau_utilisateurs[$utilisateur]['id']; |
} else if ($utilisateur != '') { |
// sinon si c'est un mail inconnu, on garde le md5 |
if ($this->mailValide($utilisateur)) { |
$retour = md5($utilisateur); |
} |
} else if ($utilisateur == '') { |
$retour = 'NULL'; |
} |
return $retour; |
} |
private function mailValide($mail) { |
// vérification bidon mais ça suffit pour ici |
return !(strpos($mail, '@') === false); |
} |
private function mettreANullPrenomNomVide() { |
$bdd = self::$bdd_cel_migration; |
$requete = "UPDATE $bdd.cel_obs ". |
'SET prenom_utilisateur = NULL '. |
"WHERE prenom_utilisateur = '' "; |
$this->bdd->executer($requete); |
$requete = "UPDATE $bdd.cel_obs ". |
'SET nom_utilisateur = NULL '. |
"WHERE nom_utilisateur = '' "; |
$this->bdd->executer($requete); |
} |
} |
/branches/v1.6-croc/jrest/scripts/MigrationReferentiel.php |
---|
New file |
0,0 → 1,190 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Réalise la migration des obs du référentiel bdnff vers le référentie bdtfx |
* |
* @category php 5.2 |
* @package Cel/Scripts |
* @author Aurelien PERONNET <aurelien@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org) |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version $Id$ |
*/ |
class MigrationReferentiel { |
private $bdd = null; |
private $script = null; |
private $table_eflore = 'tb_eflore.bdtfx_v1_01'; |
private $table_cel = 'tb_cel.cel_obs'; |
private $correspondance_nn_sel_nn_ret = null; |
private $infos_noms = array(); |
private $obs_sans_nn = array(); |
private $obs_a_modifier = array(); |
private $modif_douteuses = array(); |
private $modif_familles = 0; |
private $chemin_log = '/home/telabotap/www/tmp/migration_noms_log.csv'; |
private $fp = null; |
public function __construct(Conteneur $conteneur) { |
$this->bdd = $conteneur->getBdd(); |
$this->script = $conteneur->getScript(); |
$this->initialiserLog(); |
} |
public function executer($arguments) { |
if (isset($arguments[0]) == false) { |
throw new Exception("Veuillez indiquer l'action à réaliser en paramètre.", E_USER_ERROR); |
} |
$action = $arguments[0]; |
switch ($action) { |
case 'migration_referentiel' : |
$this->migrerReferentiel(); |
break; |
} |
fclose($this->fp); |
} |
private function migrerReferentiel() { |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 1. Paramétrage ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->chargerInfosNoms(); |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 2. Chargement des observations ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$requete_selection_obs = 'SELECT id_observation, nom_sel, nom_sel_nn, nom_ret, nom_ret_nn, nt, '. |
'famille, nom_referentiel FROM '.$this->table_cel; |
$liste_obs = $this->bdd->requeter($requete_selection_obs); |
echo sizeof($liste_obs)." observations sélectionnées \n"; |
foreach ($liste_obs as $obs) { |
if($this->doitChangerNomRetenu($obs)) { |
$nouveau_nom = $this->getInfosNouveauNumNomRetenu($obs); |
$this->obs_a_modifier[] = array( |
'id' => $obs['id_observation'], |
'nouveau_nom_sci_retenu' => $nouveau_nom['nom_complet'], |
'nouveau_nn_retenu' => $nouveau_nom['num_nom'], |
'nouveau_num_tax' => $nouveau_nom['num_taxonomique'], |
'nouvelle_famille' => $nouveau_nom['famille'] |
); |
$this->logger($obs, $nouveau_nom); |
} |
} |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 3. modification des observations ... \n"; |
echo "-------------------------------------------------------------------\n"; |
echo sizeof($this->obs_a_modifier)." obs doivent voir changer leur nom retenu \n"; |
echo $this->modif_familles." obs doivent voir changer leur famille \n"; |
echo sizeof($this->obs_sans_nn)." observations n'ont pas de num nom \n"; |
echo sizeof($this->modif_douteuses)." modifications sont douteuses et ne seront pas effectuées \n"; |
echo "\n"; |
$this->executerRequeteMiseAJour(); |
echo "\n"; |
echo "-------------------------------------------------------------------\n"; |
echo " Migration des noms terminée ... \n"; |
echo "-------------------------------------------------------------------\n"; |
} |
private function chargerInfosNoms() { |
$requete = 'SELECT num_nom, num_nom_retenu, nom_complet, num_taxonomique, famille FROM '.$this->table_eflore; |
$nums = $this->bdd->requeter($requete); |
foreach ($nums as $num) { |
$this->correspondance_nn_sel_nn_ret[$num['num_nom']] = $num['num_nom_retenu']; |
$this->infos_noms[$num['num_nom']] = $num; |
} |
echo sizeof($this->correspondance_nn_sel_nn_ret)." noms sélectionnés\n"; |
} |
private function doitChangerNomRetenu($obs) { |
$changement = false; |
$nn_retenu_obs = $obs['nom_ret_nn']; |
$nn_saisi_obs = $obs['nom_sel_nn']; |
$famille_saisie_obs = $obs['famille']; |
$sans_nn_retenu = false; |
if($nn_saisi_obs != '') { |
if(!isset($this->correspondance_nn_sel_nn_ret[$nn_saisi_obs]) || $this->correspondance_nn_sel_nn_ret[$nn_saisi_obs] == 0) { |
$this->obs_sans_nn[] = $obs['id_observation']; |
$sans_nn_retenu = true; |
} else { |
if($nn_retenu_obs != $this->correspondance_nn_sel_nn_ret[$nn_saisi_obs] && str_word_count($obs['nom_ret']) >= 1) { |
$changement = true; |
} |
} |
if(!$sans_nn_retenu && $famille_saisie_obs != $this->infos_noms[$nn_saisi_obs]['famille']) { |
$changement = true; |
$this->modif_familles++; |
} |
} |
if($changement && str_word_count($obs['nom_ret']) == 1) { |
$this->modif_douteuses[] = $obs; |
$changement = false; |
} |
return $changement; |
} |
private function getInfosNouveauNumNomRetenu($obs) { |
$nouveau_nn_ret = $this->correspondance_nn_sel_nn_ret[$obs['nom_sel_nn']]; |
return $this->infos_noms[$nouveau_nn_ret]; |
} |
private function executerRequeteMiseAJour() { |
$total = 0; |
foreach($this->obs_a_modifier as $valeurs) { |
$requete = $this->assemblerRequeteMiseAJour($valeurs); |
$migration_noms = $this->bdd->executer($requete); |
if ($migration_noms) { |
$total++; |
$this->script->afficherAvancement('Migration des noms (par 1)', $total); |
} else { |
echo $requete."\n"; |
exit('Erreur lors de la migration des noms de l\'observation '.$valeurs['id']."\n"); |
} |
} |
} |
private function proteger($valeur) { |
return $this->bdd->proteger($valeur); |
} |
private function assemblerRequeteMiseAJour($tableau) { |
$requete = 'UPDATE '.$this->table_cel.' '. |
'SET nom_ret = '.$this->proteger($tableau['nouveau_nom_sci_retenu']).', '. |
'nom_ret_nn = '.$this->proteger($tableau['nouveau_nn_retenu']).', '. |
'nt = '.$this->proteger($tableau['nouveau_num_tax']).', '. |
'famille = '.$this->proteger($tableau['nouvelle_famille']).', '. |
'nom_referentiel = "bdtfx:v1.01" '. |
'WHERE id_observation = '.$this->proteger($tableau['id']); |
return $requete; |
} |
private function initialiserLog() { |
$this->fp = fopen($this->chemin_log, 'w'); |
$colonnes = 'nom sélectionné, nn nom sélectionné, ancien nom retenu, nn ancien nom retenu, '. |
'nouveau nom sélectionné, nn nouveau nom sélectionné'."\n"; |
fwrite($this->fp, $colonnes); |
} |
private function logger($obs, $nouveau_nom) { |
$chaine = '"'.$obs['nom_sel'].'"'.','.'"'.$obs['nom_sel_nn'].'"'.','.'"'.$obs['nom_ret'].'"'.','. |
'"'.$obs['nom_ret_nn'].'"'.','.'"'.$nouveau_nom['nom_complet'].'"'.','. |
'"'.$nouveau_nom['num_nom'].'"'."\n"; |
fwrite($this->fp, $chaine); |
} |
} |
?> |
/branches/v1.6-croc/jrest/scripts/MigrationImages.php |
---|
New file |
0,0 → 1,1032 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Script de migration des Images de la version 1 de la base de données du CEL à la v2. |
* Utilisation : /opt/lampp/bin/php cli.php MigrationImages |
* |
* @category php 5.2 |
* @package Cel/Scripts |
* @author Aurelien PERONNET <aurelien@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org) |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version $Id$ |
*/ |
class MigrationImages { |
const dry_run = false; |
const truncate = true; //Doit on vider les tables de destination ? |
const separateur_champs_metadonnees = ';'; |
const separateur_valeurs_metadonnees = ':'; |
private $bdd = null; |
private $script = null; |
public static $bdd_cel_migration; |
public static $bdd_utilisateurs; |
private $cle_id_metadonnees = array(); |
private $tableau_utilisateurs = array(); |
private $tableau_observations = array(); |
private $tableau_mots_cles = array(); |
/** Tableau associatif permettant de stocker l'avancement dans une boucle. |
* La clé est un md5 du message à afficher au démarrage de la boucle. |
* @var array |
*/ |
private static $avancement = array(); |
private $tableau_nouveau_ancien = array( |
'id_image' => 'ci_id_image', |
'ordre' =>'ci_ordre', |
'ce_utilisateur' => 'traiterIdentifiantUtilisateur', |
'prenom_utilisateur' => 'traiterPrenomUtilisateur', |
'nom_utilisateur' => 'traiterNomUtilisateur', |
'courriel_utilisateur' => 'ci_ce_utilisateur', |
'hauteur' => 'ci_meta_height', |
'largeur' => 'ci_meta_width', |
'appareil_fabriquant' => 'ci_meta_make', |
'appareil_modele' => 'ci_meta_model', |
'date_prise_de_vue' => 'ci_meta_date_time', |
'note_qualite' => 'traiterNoteImage', |
'mots_cles_texte' => 'ci_meta_mots_cles', |
'commentaire' => 'ci_meta_comment', |
'nom_original' => 'ci_nom_original', |
'md5' => 'ci_md5', |
'meta_exif' => 'traiterExif', |
'meta_iptc' => 'traiterIptc', |
'meta_xmp' => 'traiterXmp', |
'meta_makernote' => 'traiterMakernote', |
'date_modification' => 'ci_meta_date', |
'date_creation' => 'ci_meta_date_ajout' |
); |
private $champs_exifs_non_gardes = array( |
'ci_meta_x_resolution', |
'ci_meta_y_resolution', |
'ci_meta_gps', |
'ci_meta_user_comment', |
'ci_meta_exif_exposure_time', |
'ci_meta_exif_f_number', |
'ci_meta_exif_exif_version', |
'ci_meta_exif_compressed_bits_per_pixel', |
'ci_meta_exif_shutter_speed_value', |
'ci_meta_exif_aperture_value', |
'ci_meta_exif_exposure_bias_value', |
'ci_meta_exif_max_aperture_value', |
'ci_meta_exif_metering_mode', |
'ci_meta_exif_light_source', |
'ci_meta_exif_flash', |
'ci_meta_exif_focal_length', |
'ci_meta_exif_flash_pix_version', |
'ci_meta_exif_color_space', |
'ci_meta_exif_interoperability_offset', |
'ci_meta_exif_focal_plane_x_resolution', |
'ci_meta_exif_focal_plane_y_resolution', |
'ci_meta_exif_focal_plane_resolution_unit', |
'ci_meta_exif_sensing_method', |
'ci_meta_exif_file_source', |
'ci_meta_exif_custom_rendered', |
'ci_meta_exif_exposure_mode', |
'ci_meta_exif_white_balance', |
'ci_meta_exif_digital_zoom_ratio', |
'ci_meta_exif_scene_capture_type', |
'ci_meta_exif_gain_control', |
'ci_meta_exif_contrast', |
'ci_meta_exif_saturation', |
'ci_meta_exif_sharpness', |
'ci_meta_exif_subject_distance_range' |
); |
private $champs_iptc_non_gardes = array( |
'ci_meta_iptc_category', |
'ci_meta_iptc_by_line', |
'ci_meta_iptc_by_line_title', |
'ci_meta_iptc_city', |
'ci_meta_iptc_sub_location', |
'ci_meta_iptc_province_state', |
'ci_meta_iptc_country_primary_location_code', |
'ci_meta_iptc_country_name', |
'ci_meta_iptc_headline', |
'ci_meta_iptc_credit', |
'ci_meta_iptc_copyright_notice', |
'ci_meta_iptc_contact' |
); |
private $champs_divers_non_gardes = array( |
'ci_publiable_eflore', |
'ci_meta_mots_cles' |
); |
private $ids_tags_exif = array( |
'InteropIndex' => array('id' => '1', 'tag' => 'InteropIndex', 'categorie' => 'InteropIFD'), |
'InteropVersion' => array('id' => '2', 'tag' => 'InteropVersion', 'categorie' => 'InteropIFD'), |
'ProcessingSoftware' => array('id' => '11', 'tag' => 'ProcessingSoftware', 'categorie' => 'IFD0'), |
'SubfileType' => array('id' => '254', 'tag' => 'SubfileType', 'categorie' => 'IFD0'), |
'OldSubfileType' => array('id' => '255', 'tag' => 'OldSubfileType', 'categorie' => 'IFD0'), |
'ImageWidth' => array('id' => '256', 'tag' => 'ImageWidth', 'categorie' => 'IFD0'), |
'ImageLength' => array('id' => '257', 'tag' => 'ImageHeight', 'categorie' => 'IFD0'), |
'BitsPerSample' => array('id' => '258', 'tag' => 'BitsPerSample', 'categorie' => 'IFD0'), |
'Compression' => array('id' => '259', 'tag' => 'Compression', 'categorie' => 'IFD0'), |
'PhotometricInterpretation' => array('id' => '262', 'tag' => 'PhotometricInterpretation', 'categorie' => 'IFD0'), |
'Thresholding' => array('id' => '263', 'tag' => 'Thresholding', 'categorie' => 'IFD0'), |
'CellWidth' => array('id' => '264', 'tag' => 'CellWidth', 'categorie' => 'IFD0'), |
'CellLength' => array('id' => '265', 'tag' => 'CellLength', 'categorie' => 'IFD0'), |
'FillOrder' => array('id' => '266', 'tag' => 'FillOrder', 'categorie' => 'IFD0'), |
'DocumentName' => array('id' => '269', 'tag' => 'DocumentName', 'categorie' => 'IFD0'), |
'ImageDescription' => array('id' => '270', 'tag' => 'ImageDescription', 'categorie' => 'IFD0'), |
'Make' => array('id' => '271', 'tag' => 'Make', 'categorie' => 'IFD0'), |
'Model' => array('id' => '272', 'tag' => 'Model', 'categorie' => 'IFD0'), |
'StripOffsets' => array('id' => '273', 'tag' => 'StripOffsets', 'categorie' => 'IFD0'), |
'Orientation' => array('id' => '274', 'tag' => 'Orientation', 'categorie' => 'IFD0'), |
'SamplesPerPixel' => array('id' => '277', 'tag' => 'SamplesPerPixel', 'categorie' => 'IFD0'), |
'RowsPerStrip' => array('id' => '278', 'tag' => 'RowsPerStrip', 'categorie' => 'IFD0'), |
'StripByteCounts' => array('id' => '279', 'tag' => 'StripByteCounts', 'categorie' => 'IFD0'), |
'MinSampleValue' => array('id' => '280', 'tag' => 'MinSampleValue', 'categorie' => 'IFD0'), |
'MaxSampleValue' => array('id' => '281', 'tag' => 'MaxSampleValue', 'categorie' => 'IFD0'), |
'XResolution' => array('id' => '282', 'tag' => 'XResolution', 'categorie' => 'IFD0'), |
'YResolution' => array('id' => '283', 'tag' => 'YResolution', 'categorie' => 'IFD0'), |
'PlanarConfiguration' => array('id' => '284', 'tag' => 'PlanarConfiguration', 'categorie' => 'IFD0'), |
'PageName' => array('id' => '285', 'tag' => 'PageName', 'categorie' => 'IFD0'), |
'XPosition' => array('id' => '286', 'tag' => 'XPosition', 'categorie' => 'IFD0'), |
'YPosition' => array('id' => '287', 'tag' => 'YPosition', 'categorie' => 'IFD0'), |
'FreeOffsets' => array('id' => '288', 'tag' => 'FreeOffsets', 'categorie' => 'Unknown'), |
'FreeByteCounts' => array('id' => '289', 'tag' => 'FreeByteCounts', 'categorie' => 'Unknown'), |
'GrayResponseUnit' => array('id' => '290', 'tag' => 'GrayResponseUnit', 'categorie' => 'IFD0'), |
'GrayResponseCurve' => array('id' => '291', 'tag' => 'GrayResponseCurve', 'categorie' => 'Unknown'), |
'T4Options' => array('id' => '292', 'tag' => 'T4Options', 'categorie' => 'Unknown'), |
'T6Options' => array('id' => '293', 'tag' => 'T6Options', 'categorie' => 'Unknown'), |
'ResolutionUnit' => array('id' => '296', 'tag' => 'ResolutionUnit', 'categorie' => 'IFD0'), |
'PageNumber' => array('id' => '297', 'tag' => 'PageNumber', 'categorie' => 'IFD0'), |
'ColorResponseUnit' => array('id' => '300', 'tag' => 'ColorResponseUnit', 'categorie' => 'Unknown'), |
'TransferFunction' => array('id' => '301', 'tag' => 'TransferFunction', 'categorie' => 'IFD0'), |
'Software' => array('id' => '305', 'tag' => 'Software', 'categorie' => 'IFD0'), |
'ModifyDate' => array('id' => '306', 'tag' => 'ModifyDate', 'categorie' => 'IFD0'), |
'DateTime' => array('id' => '306', 'tag' => 'ModifyDate', 'categorie' => 'IFD0'), |
'Artist' => array('id' => '315', 'tag' => 'Artist', 'categorie' => 'IFD0'), |
'HostComputer' => array('id' => '316', 'tag' => 'HostComputer', 'categorie' => 'IFD0'), |
'Predictor' => array('id' => '317', 'tag' => 'Predictor', 'categorie' => 'IFD0'), |
'WhitePoint' => array('id' => '318', 'tag' => 'WhitePoint', 'categorie' => 'IFD0'), |
'PrimaryChromaticities' => array('id' => '319', 'tag' => 'PrimaryChromaticities', 'categorie' => 'IFD0'), |
'ColorMap' => array('id' => '320', 'tag' => 'ColorMap', 'categorie' => 'Unknown'), |
'HalftoneHints' => array('id' => '321', 'tag' => 'HalftoneHints', 'categorie' => 'IFD0'), |
'TileWidth' => array('id' => '322', 'tag' => 'TileWidth', 'categorie' => 'IFD0'), |
'TileLength' => array('id' => '323', 'tag' => 'TileLength', 'categorie' => 'IFD0'), |
'TileOffsets' => array('id' => '324', 'tag' => 'TileOffsets', 'categorie' => 'Unknown'), |
'TileByteCounts' => array('id' => '325', 'tag' => 'TileByteCounts', 'categorie' => 'Unknown'), |
'BadFaxLines' => array('id' => '326', 'tag' => 'BadFaxLines', 'categorie' => 'Unknown'), |
'CleanFaxData' => array('id' => '327', 'tag' => 'CleanFaxData', 'categorie' => 'Unknown'), |
'ConsecutiveBadFaxLines' => array('id' => '328', 'tag' => 'ConsecutiveBadFaxLines', 'categorie' => 'Unknown'), |
'SubIFD' => array('id' => '330', 'tag' => 'SubIFD', 'categorie' => 'Unknown'), |
'InkSet' => array('id' => '332', 'tag' => 'InkSet', 'categorie' => 'IFD0'), |
'InkNames' => array('id' => '333', 'tag' => 'InkNames', 'categorie' => 'Unknown'), |
'NumberofInks' => array('id' => '334', 'tag' => 'NumberofInks', 'categorie' => 'Unknown'), |
'DotRange' => array('id' => '336', 'tag' => 'DotRange', 'categorie' => 'IFD0'), |
'TargetPrinter' => array('id' => '337', 'tag' => 'TargetPrinter', 'categorie' => 'Unknown'), |
'ExtraSamples' => array('id' => '338', 'tag' => 'ExtraSamples', 'categorie' => 'Unknown'), |
'SampleFormat' => array('id' => '339', 'tag' => 'SampleFormat', 'categorie' => 'Unknown'), |
'SMinSampleValue' => array('id' => '340', 'tag' => 'SMinSampleValue', 'categorie' => 'Unknown'), |
'SMaxSampleValue' => array('id' => '341', 'tag' => 'SMaxSampleValue', 'categorie' => 'Unknown'), |
'TransferRange' => array('id' => '342', 'tag' => 'TransferRange', 'categorie' => 'Unknown'), |
'ClipPath' => array('id' => '343', 'tag' => 'ClipPath', 'categorie' => 'Unknown'), |
'XClipPathUnits' => array('id' => '344', 'tag' => 'XClipPathUnits', 'categorie' => 'Unknown'), |
'YClipPathUnits' => array('id' => '345', 'tag' => 'YClipPathUnits', 'categorie' => 'Unknown'), |
'Indexed' => array('id' => '346', 'tag' => 'Indexed', 'categorie' => 'Unknown'), |
'JPEGTables' => array('id' => '347', 'tag' => 'JPEGTables', 'categorie' => 'Unknown'), |
'OPIProxy' => array('id' => '351', 'tag' => 'OPIProxy', 'categorie' => 'Unknown'), |
'GlobalParametersIFD' => array('id' => '400', 'tag' => 'GlobalParametersIFD', 'categorie' => 'Unknown'), |
'ProfileType' => array('id' => '401', 'tag' => 'ProfileType', 'categorie' => 'Unknown'), |
'FaxProfile' => array('id' => '402', 'tag' => 'FaxProfile', 'categorie' => 'Unknown'), |
'CodingMethods' => array('id' => '403', 'tag' => 'CodingMethods', 'categorie' => 'Unknown'), |
'VersionYear' => array('id' => '404', 'tag' => 'VersionYear', 'categorie' => 'Unknown'), |
'ModeNumber' => array('id' => '405', 'tag' => 'ModeNumber', 'categorie' => 'Unknown'), |
'Decode' => array('id' => '433', 'tag' => 'Decode', 'categorie' => 'Unknown'), |
'DefaultImageColor' => array('id' => '434', 'tag' => 'DefaultImageColor', 'categorie' => 'Unknown'), |
'T82Options' => array('id' => '435', 'tag' => 'T82Options', 'categorie' => 'Unknown'), |
'JPEGProc' => array('id' => '512', 'tag' => 'JPEGProc', 'categorie' => 'Unknown'), |
'ThumbnailOffset' => array('id' => '513', 'tag' => 'ThumbnailOffset', 'categorie' => 'IFD1'), |
'ThumbnailLength' => array('id' => '514', 'tag' => 'ThumbnailLength', 'categorie' => 'IFD1'), |
'JPEGRestartInterval' => array('id' => '515', 'tag' => 'JPEGRestartInterval', 'categorie' => 'Unknown'), |
'JPEGLosslessPredictors' => array('id' => '517', 'tag' => 'JPEGLosslessPredictors', 'categorie' => 'Unknown'), |
'JPEGPointTransforms' => array('id' => '518', 'tag' => 'JPEGPointTransforms', 'categorie' => 'Unknown'), |
'JPEGQTables' => array('id' => '519', 'tag' => 'JPEGQTables', 'categorie' => 'Unknown'), |
'JPEGDCTables' => array('id' => '520', 'tag' => 'JPEGDCTables', 'categorie' => 'Unknown'), |
'JPEGACTables' => array('id' => '521', 'tag' => 'JPEGACTables', 'categorie' => 'Unknown'), |
'YCbCrCoefficients' => array('id' => '529', 'tag' => 'YCbCrCoefficients', 'categorie' => 'IFD0'), |
'YCbCrSubSampling' => array('id' => '530', 'tag' => 'YCbCrSubSampling', 'categorie' => 'IFD0'), |
'YCbCrPositioning' => array('id' => '531', 'tag' => 'YCbCrPositioning', 'categorie' => 'IFD0'), |
'ReferenceBlackWhite' => array('id' => '532', 'tag' => 'ReferenceBlackWhite', 'categorie' => 'IFD0'), |
'StripRowCounts' => array('id' => '559', 'tag' => 'StripRowCounts', 'categorie' => 'Unknown'), |
'ApplicationNotes' => array('id' => '700', 'tag' => 'ApplicationNotes', 'categorie' => 'ExifIFD'), |
'USPTOMiscellaneous' => array('id' => '999', 'tag' => 'USPTOMiscellaneous', 'categorie' => 'Unknown'), |
'RelatedImageFileFormat' => array('id' => '4096', 'tag' => 'RelatedImageFileFormat', 'categorie' => 'InteropIFD'), |
'RelatedImageWidth' => array('id' => '4097', 'tag' => 'RelatedImageWidth', 'categorie' => 'InteropIFD'), |
'RelatedImageHeight' => array('id' => '4098', 'tag' => 'RelatedImageHeight', 'categorie' => 'InteropIFD'), |
'RelatedImageLength' => array('id' => '4098', 'tag' => 'RelatedImageHeight', 'categorie' => 'InteropIFD'), |
'Rating' => array('id' => '18246', 'tag' => 'Rating', 'categorie' => 'IFD0'), |
'XP_DIP_XML' => array('id' => '18247', 'tag' => 'XP_DIP_XML', 'categorie' => 'Unknown'), |
'StitchInfo' => array('id' => '18248', 'tag' => 'StitchInfo', 'categorie' => 'Unknown'), |
'RatingPercent' => array('id' => '18249', 'tag' => 'RatingPercent', 'categorie' => 'IFD0'), |
'ImageID' => array('id' => '32781', 'tag' => 'ImageID', 'categorie' => 'Unknown'), |
'WangTag1' => array('id' => '32931', 'tag' => 'WangTag1', 'categorie' => 'Unknown'), |
'WangAnnotation' => array('id' => '32932', 'tag' => 'WangAnnotation', 'categorie' => 'Unknown'), |
'WangTag3' => array('id' => '32933', 'tag' => 'WangTag3', 'categorie' => 'Unknown'), |
'WangTag4' => array('id' => '32934', 'tag' => 'WangTag4', 'categorie' => 'Unknown'), |
'Matteing' => array('id' => '32995', 'tag' => 'Matteing', 'categorie' => 'Unknown'), |
'DataType' => array('id' => '32996', 'tag' => 'DataType', 'categorie' => 'Unknown'), |
'ImageDepth' => array('id' => '32997', 'tag' => 'ImageDepth', 'categorie' => 'Unknown'), |
'TileDepth' => array('id' => '32998', 'tag' => 'TileDepth', 'categorie' => 'Unknown'), |
'Model2' => array('id' => '33405', 'tag' => 'Model2', 'categorie' => 'Unknown'), |
'CFARepeatPatternDim' => array('id' => '33421', 'tag' => 'CFARepeatPatternDim', 'categorie' => 'Unknown'), |
'CFAPattern2' => array('id' => '33422', 'tag' => 'CFAPattern2', 'categorie' => 'Unknown'), |
'BatteryLevel' => array('id' => '33423', 'tag' => 'BatteryLevel', 'categorie' => 'Unknown'), |
'KodakIFD' => array('id' => '33424', 'tag' => 'KodakIFD', 'categorie' => 'Unknown'), |
'Copyright' => array('id' => '33432', 'tag' => 'Copyright', 'categorie' => 'IFD0'), |
'ExposureTime' => array('id' => '33434', 'tag' => 'ExposureTime', 'categorie' => 'ExifIFD'), |
'FNumber' => array('id' => '33437', 'tag' => 'FNumber', 'categorie' => 'ExifIFD'), |
'MDFileTag' => array('id' => '33445', 'tag' => 'MDFileTag', 'categorie' => 'Unknown'), |
'MDScalePixel' => array('id' => '33446', 'tag' => 'MDScalePixel', 'categorie' => 'Unknown'), |
'MDColorTable' => array('id' => '33447', 'tag' => 'MDColorTable', 'categorie' => 'Unknown'), |
'MDLabName' => array('id' => '33448', 'tag' => 'MDLabName', 'categorie' => 'Unknown'), |
'MDSampleInfo' => array('id' => '33449', 'tag' => 'MDSampleInfo', 'categorie' => 'Unknown'), |
'MDPrepDate' => array('id' => '33450', 'tag' => 'MDPrepDate', 'categorie' => 'Unknown'), |
'MDPrepTime' => array('id' => '33451', 'tag' => 'MDPrepTime', 'categorie' => 'Unknown'), |
'MDFileUnits' => array('id' => '33452', 'tag' => 'MDFileUnits', 'categorie' => 'Unknown'), |
'PixelScale' => array('id' => '33550', 'tag' => 'PixelScale', 'categorie' => 'Unknown'), |
'AdventScale' => array('id' => '33589', 'tag' => 'AdventScale', 'categorie' => 'Unknown'), |
'AdventRevision' => array('id' => '33590', 'tag' => 'AdventRevision', 'categorie' => 'Unknown'), |
'UIC1Tag' => array('id' => '33628', 'tag' => 'UIC1Tag', 'categorie' => 'Unknown'), |
'UIC2Tag' => array('id' => '33629', 'tag' => 'UIC2Tag', 'categorie' => 'Unknown'), |
'UIC3Tag' => array('id' => '33630', 'tag' => 'UIC3Tag', 'categorie' => 'Unknown'), |
'UIC4Tag' => array('id' => '33631', 'tag' => 'UIC4Tag', 'categorie' => 'Unknown'), |
'IPTC-NAA' => array('id' => '33723', 'tag' => 'IPTC-NAA', 'categorie' => 'IFD0'), |
'IntergraphPacketData' => array('id' => '33918', 'tag' => 'IntergraphPacketData', 'categorie' => 'Unknown'), |
'IntergraphFlagRegisters' => array('id' => '33919', 'tag' => 'IntergraphFlagRegisters', 'categorie' => 'Unknown'), |
'IntergraphMatrix' => array('id' => '33920', 'tag' => 'IntergraphMatrix', 'categorie' => 'Unknown'), |
'INGRReserved' => array('id' => '33921', 'tag' => 'INGRReserved', 'categorie' => 'Unknown'), |
'ModelTiePoint' => array('id' => '33922', 'tag' => 'ModelTiePoint', 'categorie' => 'Unknown'), |
'Site' => array('id' => '34016', 'tag' => 'Site', 'categorie' => 'Unknown'), |
'ColorSequence' => array('id' => '34017', 'tag' => 'ColorSequence', 'categorie' => 'Unknown'), |
'IT8Header' => array('id' => '34018', 'tag' => 'IT8Header', 'categorie' => 'Unknown'), |
'RasterPadding' => array('id' => '34019', 'tag' => 'RasterPadding', 'categorie' => 'Unknown'), |
'BitsPerRunLength' => array('id' => '34020', 'tag' => 'BitsPerRunLength', 'categorie' => 'Unknown'), |
'BitsPerExtendedRunLength' => array('id' => '34021', 'tag' => 'BitsPerExtendedRunLength', 'categorie' => 'Unknown'), |
'ColorTable' => array('id' => '34022', 'tag' => 'ColorTable', 'categorie' => 'Unknown'), |
'ImageColorIndicator' => array('id' => '34023', 'tag' => 'ImageColorIndicator', 'categorie' => 'Unknown'), |
'BackgroundColorIndicator' => array('id' => '34024', 'tag' => 'BackgroundColorIndicator', 'categorie' => 'Unknown'), |
'ImageColorValue' => array('id' => '34025', 'tag' => 'ImageColorValue', 'categorie' => 'Unknown'), |
'BackgroundColorValue' => array('id' => '34026', 'tag' => 'BackgroundColorValue', 'categorie' => 'Unknown'), |
'PixelIntensityRange' => array('id' => '34027', 'tag' => 'PixelIntensityRange', 'categorie' => 'Unknown'), |
'TransparencyIndicator' => array('id' => '34028', 'tag' => 'TransparencyIndicator', 'categorie' => 'Unknown'), |
'ColorCharacterization' => array('id' => '34029', 'tag' => 'ColorCharacterization', 'categorie' => 'Unknown'), |
'HCUsage' => array('id' => '34030', 'tag' => 'HCUsage', 'categorie' => 'Unknown'), |
'TrapIndicator' => array('id' => '34031', 'tag' => 'TrapIndicator', 'categorie' => 'Unknown'), |
'CMYKEquivalent' => array('id' => '34032', 'tag' => 'CMYKEquivalent', 'categorie' => 'Unknown'), |
'SEMInfo' => array('id' => '34118', 'tag' => 'SEMInfo', 'categorie' => 'IFD0'), |
'AFCP_IPTC' => array('id' => '34152', 'tag' => 'AFCP_IPTC', 'categorie' => 'Unknown'), |
'PixelMagicJBIGOptions' => array('id' => '34232', 'tag' => 'PixelMagicJBIGOptions', 'categorie' => 'Unknown'), |
'ModelTransform' => array('id' => '34264', 'tag' => 'ModelTransform', 'categorie' => 'Unknown'), |
'WB_GRGBLevels' => array('id' => '34306', 'tag' => 'WB_GRGBLevels', 'categorie' => 'Unknown'), |
'LeafData' => array('id' => '34310', 'tag' => 'LeafData', 'categorie' => 'Unknown'), |
'PhotoshopSettings' => array('id' => '34377', 'tag' => 'PhotoshopSettings', 'categorie' => 'Unknown'), |
'ExifIFDPointer' => array('id' => '34665', 'tag' => 'ExifOffset', 'categorie' => 'Unknown'), |
'ICC_Profile' => array('id' => '34675', 'tag' => 'ICC_Profile', 'categorie' => 'Unknown'), |
'TIFF_FXExtensions' => array('id' => '34687', 'tag' => 'TIFF_FXExtensions', 'categorie' => 'Unknown'), |
'MultiProfiles' => array('id' => '34688', 'tag' => 'MultiProfiles', 'categorie' => 'Unknown'), |
'SharedData' => array('id' => '34689', 'tag' => 'SharedData', 'categorie' => 'Unknown'), |
'T88Options' => array('id' => '34690', 'tag' => 'T88Options', 'categorie' => 'Unknown'), |
'ImageLayer' => array('id' => '34732', 'tag' => 'ImageLayer', 'categorie' => 'Unknown'), |
'GeoTiffDirectory' => array('id' => '34735', 'tag' => 'GeoTiffDirectory', 'categorie' => 'Unknown'), |
'GeoTiffDoubleParams' => array('id' => '34736', 'tag' => 'GeoTiffDoubleParams', 'categorie' => 'Unknown'), |
'GeoTiffAsciiParams' => array('id' => '34737', 'tag' => 'GeoTiffAsciiParams', 'categorie' => 'Unknown'), |
'ExposureProgram' => array('id' => '34850', 'tag' => 'ExposureProgram', 'categorie' => 'ExifIFD'), |
'SpectralSensitivity' => array('id' => '34852', 'tag' => 'SpectralSensitivity', 'categorie' => 'ExifIFD'), |
'GPSIFDPointer' => array('id' => '34853', 'tag' => 'GPSInfo', 'categorie' => 'Unknown'), |
'ISO' => array('id' => '34855', 'tag' => 'ISO', 'categorie' => 'ExifIFD'), |
'ISOSpeedRatings' => array('id' => '34855', 'tag' => 'ISO', 'categorie' => 'ExifIFD'), |
'PhotographicSensitivity' => array('id' => '34855', 'tag' => 'ISO', 'categorie' => 'ExifIFD'), |
'Opto-ElectricConvFactor' => array('id' => '34856', 'tag' => 'Opto-ElectricConvFactor', 'categorie' => 'Unknown'), |
'OECF' => array('id' => '34856', 'tag' => 'Opto-ElectricConvFactor', 'categorie' => 'Unknown'), |
'Interlace' => array('id' => '34857', 'tag' => 'Interlace', 'categorie' => 'Unknown'), |
'TimeZoneOffset' => array('id' => '34858', 'tag' => 'TimeZoneOffset', 'categorie' => 'ExifIFD'), |
'SelfTimerMode' => array('id' => '34859', 'tag' => 'SelfTimerMode', 'categorie' => 'ExifIFD'), |
'SensitivityType' => array('id' => '34864', 'tag' => 'SensitivityType', 'categorie' => 'ExifIFD'), |
'StandardOutputSensitivity' => array('id' => '34865', 'tag' => 'StandardOutputSensitivity', 'categorie' => 'ExifIFD'), |
'RecommendedExposureIndex' => array('id' => '34866', 'tag' => 'RecommendedExposureIndex', 'categorie' => 'ExifIFD'), |
'ISOSpeed' => array('id' => '34867', 'tag' => 'ISOSpeed', 'categorie' => 'ExifIFD'), |
'ISOSpeedLatitudeyyy' => array('id' => '34868', 'tag' => 'ISOSpeedLatitudeyyy', 'categorie' => 'ExifIFD'), |
'ISOSpeedLatitudezzz' => array('id' => '34869', 'tag' => 'ISOSpeedLatitudezzz', 'categorie' => 'ExifIFD'), |
'FaxRecvParams' => array('id' => '34908', 'tag' => 'FaxRecvParams', 'categorie' => 'Unknown'), |
'FaxSubAddress' => array('id' => '34909', 'tag' => 'FaxSubAddress', 'categorie' => 'Unknown'), |
'FaxRecvTime' => array('id' => '34910', 'tag' => 'FaxRecvTime', 'categorie' => 'Unknown'), |
'LeafSubIFD' => array('id' => '34954', 'tag' => 'LeafSubIFD', 'categorie' => 'Unknown'), |
'ExifVersion' => array('id' => '36864', 'tag' => 'ExifVersion', 'categorie' => 'ExifIFD'), |
'DateTimeOriginal' => array('id' => '36867', 'tag' => 'DateTimeOriginal', 'categorie' => 'ExifIFD'), |
'CreateDate' => array('id' => '36868', 'tag' => 'CreateDate', 'categorie' => 'ExifIFD'), |
'DateTimeDigitized' => array('id' => '36868', 'tag' => 'CreateDate', 'categorie' => 'ExifIFD'), |
'ComponentsConfiguration' => array('id' => '37121', 'tag' => 'ComponentsConfiguration', 'categorie' => 'ExifIFD'), |
'CompressedBitsPerPixel' => array('id' => '37122', 'tag' => 'CompressedBitsPerPixel', 'categorie' => 'ExifIFD'), |
'ShutterSpeedValue' => array('id' => '37377', 'tag' => 'ShutterSpeedValue', 'categorie' => 'ExifIFD'), |
'ApertureValue' => array('id' => '37378', 'tag' => 'ApertureValue', 'categorie' => 'ExifIFD'), |
'BrightnessValue' => array('id' => '37379', 'tag' => 'BrightnessValue', 'categorie' => 'ExifIFD'), |
'ExposureBiasValue' => array('id' => '37380', 'tag' => 'ExposureCompensation', 'categorie' => 'ExifIFD'), |
'MaxApertureValue' => array('id' => '37381', 'tag' => 'MaxApertureValue', 'categorie' => 'ExifIFD'), |
'SubjectDistance' => array('id' => '37382', 'tag' => 'SubjectDistance', 'categorie' => 'ExifIFD'), |
'MeteringMode' => array('id' => '37383', 'tag' => 'MeteringMode', 'categorie' => 'ExifIFD'), |
'LightSource' => array('id' => '37384', 'tag' => 'LightSource', 'categorie' => 'ExifIFD'), |
'Flash' => array('id' => '37385', 'tag' => 'Flash', 'categorie' => 'ExifIFD'), |
'FocalLength' => array('id' => '37386', 'tag' => 'FocalLength', 'categorie' => 'ExifIFD'), |
'FlashEnergy' => array('id' => '37387', 'tag' => 'FlashEnergy', 'categorie' => 'Unknown'), |
'SpatialFrequencyResponse' => array('id' => '37388', 'tag' => 'SpatialFrequencyResponse', 'categorie' => 'Unknown'), |
'Noise' => array('id' => '37389', 'tag' => 'Noise', 'categorie' => 'Unknown'), |
'FocalPlaneXResolution' => array('id' => '37390', 'tag' => 'FocalPlaneXResolution', 'categorie' => 'Unknown'), |
'FocalPlaneYResolution' => array('id' => '37391', 'tag' => 'FocalPlaneYResolution', 'categorie' => 'Unknown'), |
'FocalPlaneResolutionUnit' => array('id' => '37392', 'tag' => 'FocalPlaneResolutionUnit', 'categorie' => 'Unknown'), |
'ImageNumber' => array('id' => '37393', 'tag' => 'ImageNumber', 'categorie' => 'ExifIFD'), |
'SecurityClassification' => array('id' => '37394', 'tag' => 'SecurityClassification', 'categorie' => 'ExifIFD'), |
'ImageHistory' => array('id' => '37395', 'tag' => 'ImageHistory', 'categorie' => 'ExifIFD'), |
'SubjectArea' => array('id' => '37396', 'tag' => 'SubjectArea', 'categorie' => 'ExifIFD'), |
'ExposureIndex' => array('id' => '37397', 'tag' => 'ExposureIndex', 'categorie' => 'Unknown'), |
'TIFF-EPStandardID' => array('id' => '37398', 'tag' => 'TIFF-EPStandardID', 'categorie' => 'Unknown'), |
'SensingMethod' => array('id' => '37399', 'tag' => 'SensingMethod', 'categorie' => 'Unknown'), |
'CIP3DataFile' => array('id' => '37434', 'tag' => 'CIP3DataFile', 'categorie' => 'Unknown'), |
'CIP3Sheet' => array('id' => '37435', 'tag' => 'CIP3Sheet', 'categorie' => 'Unknown'), |
'CIP3Side' => array('id' => '37436', 'tag' => 'CIP3Side', 'categorie' => 'Unknown'), |
'StoNits' => array('id' => '37439', 'tag' => 'StoNits', 'categorie' => 'Unknown'), |
'MakerNote' => array('id' => '37500', 'tag' => 'MakerNote', 'categorie' => 'ExifIFD'), |
'UserComment' => array('id' => '37510', 'tag' => 'UserComment', 'categorie' => 'ExifIFD'), |
'SubSecTime' => array('id' => '37520', 'tag' => 'SubSecTime', 'categorie' => 'ExifIFD'), |
'SubSecTimeOriginal' => array('id' => '37521', 'tag' => 'SubSecTimeOriginal', 'categorie' => 'ExifIFD'), |
'SubSecTimeDigitized' => array('id' => '37522', 'tag' => 'SubSecTimeDigitized', 'categorie' => 'ExifIFD'), |
'MSDocumentText' => array('id' => '37679', 'tag' => 'MSDocumentText', 'categorie' => 'Unknown'), |
'MSPropertySetStorage' => array('id' => '37680', 'tag' => 'MSPropertySetStorage', 'categorie' => 'Unknown'), |
'MSDocumentTextPosition' => array('id' => '37681', 'tag' => 'MSDocumentTextPosition', 'categorie' => 'Unknown'), |
'ImageSourceData' => array('id' => '37724', 'tag' => 'ImageSourceData', 'categorie' => 'IFD0'), |
'XPTitle' => array('id' => '40091', 'tag' => 'XPTitle', 'categorie' => 'IFD0'), |
'XPComment' => array('id' => '40092', 'tag' => 'XPComment', 'categorie' => 'IFD0'), |
'XPAuthor' => array('id' => '40093', 'tag' => 'XPAuthor', 'categorie' => 'IFD0'), |
'XPKeywords' => array('id' => '40094', 'tag' => 'XPKeywords', 'categorie' => 'IFD0'), |
'XPSubject' => array('id' => '40095', 'tag' => 'XPSubject', 'categorie' => 'IFD0'), |
'FlashPixVersion' => array('id' => '40960', 'tag' => 'FlashpixVersion', 'categorie' => 'ExifIFD'), |
'ColorSpace' => array('id' => '40961', 'tag' => 'ColorSpace', 'categorie' => 'ExifIFD'), |
'ExifImageWidth' => array('id' => '40962', 'tag' => 'ExifImageWidth', 'categorie' => 'ExifIFD'), |
'PixelXDimension' => array('id' => '40962', 'tag' => 'ExifImageWidth', 'categorie' => 'ExifIFD'), |
'ExifImageHeight' => array('id' => '40963', 'tag' => 'ExifImageHeight', 'categorie' => 'ExifIFD'), |
'PixelYDimension' => array('id' => '40963', 'tag' => 'ExifImageHeight', 'categorie' => 'ExifIFD'), |
'RelatedSoundFile' => array('id' => '40964', 'tag' => 'RelatedSoundFile', 'categorie' => 'ExifIFD'), |
'InteroperabilityOffset' => array('id' => '40965', 'tag' => 'InteropOffset', 'categorie' => 'Unknown'), |
'SubjectLocation' => array('id' => '41492', 'tag' => 'SubjectLocation', 'categorie' => 'ExifIFD'), |
'FileSource' => array('id' => '41728', 'tag' => 'FileSource', 'categorie' => 'ExifIFD'), |
'SceneType' => array('id' => '41729', 'tag' => 'SceneType', 'categorie' => 'ExifIFD'), |
'CFAPattern' => array('id' => '41730', 'tag' => 'CFAPattern', 'categorie' => 'ExifIFD'), |
'CustomRendered' => array('id' => '41985', 'tag' => 'CustomRendered', 'categorie' => 'ExifIFD'), |
'ExposureMode' => array('id' => '41986', 'tag' => 'ExposureMode', 'categorie' => 'ExifIFD'), |
'WhiteBalance' => array('id' => '41987', 'tag' => 'WhiteBalance', 'categorie' => 'ExifIFD'), |
'DigitalZoomRatio' => array('id' => '41988', 'tag' => 'DigitalZoomRatio', 'categorie' => 'ExifIFD'), |
'FocalLengthIn35mmFormat' => array('id' => '41989', 'tag' => 'FocalLengthIn35mmFormat', 'categorie' => 'ExifIFD'), |
'FocalLengthIn35mmFilm' => array('id' => '41989', 'tag' => 'FocalLengthIn35mmFormat', 'categorie' => 'ExifIFD'), |
'SceneCaptureType' => array('id' => '41990', 'tag' => 'SceneCaptureType', 'categorie' => 'ExifIFD'), |
'GainControl' => array('id' => '41991', 'tag' => 'GainControl', 'categorie' => 'ExifIFD'), |
'Contrast' => array('id' => '41992', 'tag' => 'Contrast', 'categorie' => 'ExifIFD'), |
'Saturation' => array('id' => '41993', 'tag' => 'Saturation', 'categorie' => 'ExifIFD'), |
'Sharpness' => array('id' => '41994', 'tag' => 'Sharpness', 'categorie' => 'ExifIFD'), |
'DeviceSettingDescription' => array('id' => '41995', 'tag' => 'DeviceSettingDescription', 'categorie' => 'Unknown'), |
'SubjectDistanceRange' => array('id' => '41996', 'tag' => 'SubjectDistanceRange', 'categorie' => 'ExifIFD'), |
'ImageUniqueID' => array('id' => '42016', 'tag' => 'ImageUniqueID', 'categorie' => 'ExifIFD'), |
'OwnerName' => array('id' => '42032', 'tag' => 'OwnerName', 'categorie' => 'ExifIFD'), |
'CameraOwnerName' => array('id' => '42032', 'tag' => 'OwnerName', 'categorie' => 'ExifIFD'), |
'SerialNumber' => array('id' => '42033', 'tag' => 'SerialNumber', 'categorie' => 'ExifIFD'), |
'BodySerialNumber' => array('id' => '42033', 'tag' => 'SerialNumber', 'categorie' => 'ExifIFD'), |
'LensInfo' => array('id' => '42034', 'tag' => 'LensInfo', 'categorie' => 'ExifIFD'), |
'LensSpecification' => array('id' => '42034', 'tag' => 'LensInfo', 'categorie' => 'ExifIFD'), |
'LensMake' => array('id' => '42035', 'tag' => 'LensMake', 'categorie' => 'ExifIFD'), |
'LensModel' => array('id' => '42036', 'tag' => 'LensModel', 'categorie' => 'ExifIFD'), |
'LensSerialNumber' => array('id' => '42037', 'tag' => 'LensSerialNumber', 'categorie' => 'ExifIFD'), |
'GDALMetadata' => array('id' => '42112', 'tag' => 'GDALMetadata', 'categorie' => 'Unknown'), |
'GDALNoData' => array('id' => '42113', 'tag' => 'GDALNoData', 'categorie' => 'Unknown'), |
'Gamma' => array('id' => '42240', 'tag' => 'Gamma', 'categorie' => 'ExifIFD'), |
'ExpandSoftware' => array('id' => '44992', 'tag' => 'ExpandSoftware', 'categorie' => 'Unknown'), |
'ExpandLens' => array('id' => '44993', 'tag' => 'ExpandLens', 'categorie' => 'Unknown'), |
'ExpandFilm' => array('id' => '44994', 'tag' => 'ExpandFilm', 'categorie' => 'Unknown'), |
'ExpandFilterLens' => array('id' => '44995', 'tag' => 'ExpandFilterLens', 'categorie' => 'Unknown'), |
'ExpandScanner' => array('id' => '44996', 'tag' => 'ExpandScanner', 'categorie' => 'Unknown'), |
'ExpandFlashLamp' => array('id' => '44997', 'tag' => 'ExpandFlashLamp', 'categorie' => 'Unknown'), |
'PixelFormat' => array('id' => '48129', 'tag' => 'PixelFormat', 'categorie' => 'Unknown'), |
'Transformation' => array('id' => '48130', 'tag' => 'Transformation', 'categorie' => 'Unknown'), |
'Uncompressed' => array('id' => '48131', 'tag' => 'Uncompressed', 'categorie' => 'Unknown'), |
'ImageType' => array('id' => '48132', 'tag' => 'ImageType', 'categorie' => 'Unknown'), |
'ImageHeight' => array('id' => '48257', 'tag' => 'ImageHeight', 'categorie' => 'Unknown'), |
'WidthResolution' => array('id' => '48258', 'tag' => 'WidthResolution', 'categorie' => 'Unknown'), |
'HeightResolution' => array('id' => '48259', 'tag' => 'HeightResolution', 'categorie' => 'Unknown'), |
'ImageOffset' => array('id' => '48320', 'tag' => 'ImageOffset', 'categorie' => 'Unknown'), |
'ImageByteCount' => array('id' => '48321', 'tag' => 'ImageByteCount', 'categorie' => 'Unknown'), |
'AlphaOffset' => array('id' => '48322', 'tag' => 'AlphaOffset', 'categorie' => 'Unknown'), |
'AlphaByteCount' => array('id' => '48323', 'tag' => 'AlphaByteCount', 'categorie' => 'Unknown'), |
'ImageDataDiscard' => array('id' => '48324', 'tag' => 'ImageDataDiscard', 'categorie' => 'Unknown'), |
'AlphaDataDiscard' => array('id' => '48325', 'tag' => 'AlphaDataDiscard', 'categorie' => 'Unknown'), |
'OceScanjobDesc' => array('id' => '50215', 'tag' => 'OceScanjobDesc', 'categorie' => 'Unknown'), |
'OceApplicationSelector' => array('id' => '50216', 'tag' => 'OceApplicationSelector', 'categorie' => 'Unknown'), |
'OceIDNumber' => array('id' => '50217', 'tag' => 'OceIDNumber', 'categorie' => 'Unknown'), |
'OceImageLogic' => array('id' => '50218', 'tag' => 'OceImageLogic', 'categorie' => 'Unknown'), |
'Annotations' => array('id' => '50255', 'tag' => 'Annotations', 'categorie' => 'Unknown'), |
'PrintIM' => array('id' => '50341', 'tag' => 'PrintIM', 'categorie' => 'IFD0'), |
'USPTOOriginalContentType' => array('id' => '50560', 'tag' => 'USPTOOriginalContentType', 'categorie' => 'Unknown'), |
'DNGVersion' => array('id' => '50706', 'tag' => 'DNGVersion', 'categorie' => 'IFD0'), |
'DNGBackwardVersion' => array('id' => '50707', 'tag' => 'DNGBackwardVersion', 'categorie' => 'IFD0'), |
'UniqueCameraModel' => array('id' => '50708', 'tag' => 'UniqueCameraModel', 'categorie' => 'IFD0'), |
'LocalizedCameraModel' => array('id' => '50709', 'tag' => 'LocalizedCameraModel', 'categorie' => 'IFD0'), |
'CFAPlaneColor' => array('id' => '50710', 'tag' => 'CFAPlaneColor', 'categorie' => 'Unknown'), |
'CFALayout' => array('id' => '50711', 'tag' => 'CFALayout', 'categorie' => 'Unknown'), |
'LinearizationTable' => array('id' => '50712', 'tag' => 'LinearizationTable', 'categorie' => 'SubIFD'), |
'BlackLevelRepeatDim' => array('id' => '50713', 'tag' => 'BlackLevelRepeatDim', 'categorie' => 'SubIFD'), |
'BlackLevel' => array('id' => '50714', 'tag' => 'BlackLevel', 'categorie' => 'SubIFD'), |
'BlackLevelDeltaH' => array('id' => '50715', 'tag' => 'BlackLevelDeltaH', 'categorie' => 'Unknown'), |
'BlackLevelDeltaV' => array('id' => '50716', 'tag' => 'BlackLevelDeltaV', 'categorie' => 'Unknown'), |
'WhiteLevel' => array('id' => '50717', 'tag' => 'WhiteLevel', 'categorie' => 'SubIFD'), |
'DefaultScale' => array('id' => '50718', 'tag' => 'DefaultScale', 'categorie' => 'SubIFD'), |
'DefaultCropOrigin' => array('id' => '50719', 'tag' => 'DefaultCropOrigin', 'categorie' => 'SubIFD'), |
'DefaultCropSize' => array('id' => '50720', 'tag' => 'DefaultCropSize', 'categorie' => 'SubIFD'), |
'ColorMatrix1' => array('id' => '50721', 'tag' => 'ColorMatrix1', 'categorie' => 'IFD0'), |
'ColorMatrix2' => array('id' => '50722', 'tag' => 'ColorMatrix2', 'categorie' => 'IFD0'), |
'CameraCalibration1' => array('id' => '50723', 'tag' => 'CameraCalibration1', 'categorie' => 'IFD0'), |
'CameraCalibration2' => array('id' => '50724', 'tag' => 'CameraCalibration2', 'categorie' => 'IFD0'), |
'ReductionMatrix1' => array('id' => '50725', 'tag' => 'ReductionMatrix1', 'categorie' => 'IFD0'), |
'ReductionMatrix2' => array('id' => '50726', 'tag' => 'ReductionMatrix2', 'categorie' => 'IFD0'), |
'AnalogBalance' => array('id' => '50727', 'tag' => 'AnalogBalance', 'categorie' => 'IFD0'), |
'AsShotNeutral' => array('id' => '50728', 'tag' => 'AsShotNeutral', 'categorie' => 'IFD0'), |
'AsShotWhiteXY' => array('id' => '50729', 'tag' => 'AsShotWhiteXY', 'categorie' => 'IFD0'), |
'BaselineExposure' => array('id' => '50730', 'tag' => 'BaselineExposure', 'categorie' => 'IFD0'), |
'BaselineNoise' => array('id' => '50731', 'tag' => 'BaselineNoise', 'categorie' => 'IFD0'), |
'BaselineSharpness' => array('id' => '50732', 'tag' => 'BaselineSharpness', 'categorie' => 'IFD0'), |
'BayerGreenSplit' => array('id' => '50733', 'tag' => 'BayerGreenSplit', 'categorie' => 'SubIFD'), |
'LinearResponseLimit' => array('id' => '50734', 'tag' => 'LinearResponseLimit', 'categorie' => 'IFD0'), |
'CameraSerialNumber' => array('id' => '50735', 'tag' => 'CameraSerialNumber', 'categorie' => 'IFD0'), |
'DNGLensInfo' => array('id' => '50736', 'tag' => 'DNGLensInfo', 'categorie' => 'IFD0'), |
'ChromaBlurRadius' => array('id' => '50737', 'tag' => 'ChromaBlurRadius', 'categorie' => 'SubIFD'), |
'AntiAliasStrength' => array('id' => '50738', 'tag' => 'AntiAliasStrength', 'categorie' => 'SubIFD'), |
'ShadowScale' => array('id' => '50739', 'tag' => 'ShadowScale', 'categorie' => 'IFD0'), |
'SR2Private' => array('id' => '50740', 'tag' => 'SR2Private', 'categorie' => 'Unknown'), |
'MakerNoteSafety' => array('id' => '50741', 'tag' => 'MakerNoteSafety', 'categorie' => 'IFD0'), |
'RawImageSegmentation' => array('id' => '50752', 'tag' => 'RawImageSegmentation', 'categorie' => 'Unknown'), |
'CalibrationIlluminant1' => array('id' => '50778', 'tag' => 'CalibrationIlluminant1', 'categorie' => 'IFD0'), |
'CalibrationIlluminant2' => array('id' => '50779', 'tag' => 'CalibrationIlluminant2', 'categorie' => 'IFD0'), |
'BestQualityScale' => array('id' => '50780', 'tag' => 'BestQualityScale', 'categorie' => 'SubIFD'), |
'RawDataUniqueID' => array('id' => '50781', 'tag' => 'RawDataUniqueID', 'categorie' => 'IFD0'), |
'AliasLayerMetadata' => array('id' => '50784', 'tag' => 'AliasLayerMetadata', 'categorie' => 'Unknown'), |
'OriginalRawFileName' => array('id' => '50827', 'tag' => 'OriginalRawFileName', 'categorie' => 'IFD0'), |
'OriginalRawFileData' => array('id' => '50828', 'tag' => 'OriginalRawFileData', 'categorie' => 'IFD0'), |
'ActiveArea' => array('id' => '50829', 'tag' => 'ActiveArea', 'categorie' => 'SubIFD'), |
'MaskedAreas' => array('id' => '50830', 'tag' => 'MaskedAreas', 'categorie' => 'SubIFD'), |
'AsShotICCProfile' => array('id' => '50831', 'tag' => 'AsShotICCProfile', 'categorie' => 'IFD0'), |
'AsShotPreProfileMatrix' => array('id' => '50832', 'tag' => 'AsShotPreProfileMatrix', 'categorie' => 'IFD0'), |
'CurrentICCProfile' => array('id' => '50833', 'tag' => 'CurrentICCProfile', 'categorie' => 'IFD0'), |
'CurrentPreProfileMatrix' => array('id' => '50834', 'tag' => 'CurrentPreProfileMatrix', 'categorie' => 'IFD0'), |
'ColorimetricReference' => array('id' => '50879', 'tag' => 'ColorimetricReference', 'categorie' => 'IFD0'), |
'PanasonicTitle' => array('id' => '50898', 'tag' => 'PanasonicTitle', 'categorie' => 'IFD0'), |
'PanasonicTitle2' => array('id' => '50899', 'tag' => 'PanasonicTitle2', 'categorie' => 'IFD0'), |
'CameraCalibrationSig' => array('id' => '50931', 'tag' => 'CameraCalibrationSig', 'categorie' => 'IFD0'), |
'ProfileCalibrationSig' => array('id' => '50932', 'tag' => 'ProfileCalibrationSig', 'categorie' => 'IFD0'), |
'ProfileIFD' => array('id' => '50933', 'tag' => 'ProfileIFD', 'categorie' => 'Unknown'), |
'AsShotProfileName' => array('id' => '50934', 'tag' => 'AsShotProfileName', 'categorie' => 'IFD0'), |
'NoiseReductionApplied' => array('id' => '50935', 'tag' => 'NoiseReductionApplied', 'categorie' => 'SubIFD'), |
'ProfileName' => array('id' => '50936', 'tag' => 'ProfileName', 'categorie' => 'IFD0'), |
'ProfileHueSatMapDims' => array('id' => '50937', 'tag' => 'ProfileHueSatMapDims', 'categorie' => 'IFD0'), |
'ProfileHueSatMapData1' => array('id' => '50938', 'tag' => 'ProfileHueSatMapData1', 'categorie' => 'IFD0'), |
'ProfileHueSatMapData2' => array('id' => '50939', 'tag' => 'ProfileHueSatMapData2', 'categorie' => 'IFD0'), |
'ProfileToneCurve' => array('id' => '50940', 'tag' => 'ProfileToneCurve', 'categorie' => 'IFD0'), |
'ProfileEmbedPolicy' => array('id' => '50941', 'tag' => 'ProfileEmbedPolicy', 'categorie' => 'IFD0'), |
'ProfileCopyright' => array('id' => '50942', 'tag' => 'ProfileCopyright', 'categorie' => 'IFD0'), |
'ForwardMatrix1' => array('id' => '50964', 'tag' => 'ForwardMatrix1', 'categorie' => 'IFD0'), |
'ForwardMatrix2' => array('id' => '50965', 'tag' => 'ForwardMatrix2', 'categorie' => 'IFD0'), |
'PreviewApplicationName' => array('id' => '50966', 'tag' => 'PreviewApplicationName', 'categorie' => 'IFD0'), |
'PreviewApplicationVersion' => array('id' => '50967', 'tag' => 'PreviewApplicationVersion', 'categorie' => 'IFD0'), |
'PreviewSettingsName' => array('id' => '50968', 'tag' => 'PreviewSettingsName', 'categorie' => 'IFD0'), |
'PreviewSettingsDigest' => array('id' => '50969', 'tag' => 'PreviewSettingsDigest', 'categorie' => 'IFD0'), |
'PreviewColorSpace' => array('id' => '50970', 'tag' => 'PreviewColorSpace', 'categorie' => 'IFD0'), |
'PreviewDateTime' => array('id' => '50971', 'tag' => 'PreviewDateTime', 'categorie' => 'IFD0'), |
'RawImageDigest' => array('id' => '50972', 'tag' => 'RawImageDigest', 'categorie' => 'IFD0'), |
'OriginalRawFileDigest' => array('id' => '50973', 'tag' => 'OriginalRawFileDigest', 'categorie' => 'IFD0'), |
'SubTileBlockSize' => array('id' => '50974', 'tag' => 'SubTileBlockSize', 'categorie' => 'Unknown'), |
'RowInterleaveFactor' => array('id' => '50975', 'tag' => 'RowInterleaveFactor', 'categorie' => 'Unknown'), |
'ProfileLookTableDims' => array('id' => '50981', 'tag' => 'ProfileLookTableDims', 'categorie' => 'IFD0'), |
'ProfileLookTableData' => array('id' => '50982', 'tag' => 'ProfileLookTableData', 'categorie' => 'IFD0'), |
'OpcodeList1' => array('id' => '51008', 'tag' => 'OpcodeList1', 'categorie' => 'Unknown'), |
'OpcodeList2' => array('id' => '51009', 'tag' => 'OpcodeList2', 'categorie' => 'Unknown'), |
'OpcodeList3' => array('id' => '51022', 'tag' => 'OpcodeList3', 'categorie' => 'Unknown'), |
'NoiseProfile' => array('id' => '51041', 'tag' => 'NoiseProfile', 'categorie' => 'Unknown'), |
'Padding' => array('id' => '59932', 'tag' => 'Padding', 'categorie' => 'ExifIFD'), |
'OffsetSchema' => array('id' => '59933', 'tag' => 'OffsetSchema', 'categorie' => 'ExifIFD'), |
'Lens' => array('id' => '65002', 'tag' => 'Lens', 'categorie' => 'ExifIFD'), |
'KDC_IFD' => array('id' => '65024', 'tag' => 'KDC_IFD', 'categorie' => 'Unknown'), |
'RawFile' => array('id' => '65100', 'tag' => 'RawFile', 'categorie' => 'ExifIFD'), |
'Converter' => array('id' => '65101', 'tag' => 'Converter', 'categorie' => 'ExifIFD'), |
'Exposure' => array('id' => '65105', 'tag' => 'Exposure', 'categorie' => 'ExifIFD'), |
'Shadows' => array('id' => '65106', 'tag' => 'Shadows', 'categorie' => 'ExifIFD'), |
'Brightness' => array('id' => '65107', 'tag' => 'Brightness', 'categorie' => 'ExifIFD'), |
'Sharpness:65110' => array('id' => '65110', 'tag' => 'Sharpness', 'categorie' => 'ExifIFD'), |
'Smoothness' => array('id' => '65111', 'tag' => 'Smoothness', 'categorie' => 'ExifIFD'), |
'MoireFilter' => array('id' => '65112', 'tag' => 'MoireFilter', 'categorie' => 'ExifIFD'), |
'FileName' => array('id' => 'php:1', 'tag' => 'FileName', 'categorie' => 'PhpFile'), |
'FileDateTime' => array('id' => 'php:2', 'tag' => 'FileDateTime', 'categorie' => 'PhpFile'), |
'FileSize' => array('id' => 'php:3', 'tag' => 'FileSize', 'categorie' => 'PhpFile'), |
'FileType' => array('id' => 'php:4', 'tag' => 'FileType', 'categorie' => 'PhpFile'), |
'MimeType' => array('id' => 'php:5', 'tag' => 'MimeType', 'categorie' => 'PhpFile'), |
'SectionsFound' => array('id' => 'php:6', 'tag' => 'SectionsFound', 'categorie' => 'PhpFile'), |
'JPEGInterchangeFormat' => array('id' => 'php:7', 'tag' => 'JPEGInterchangeFormat', 'categorie' => 'PhpThumbail'), |
'JPEGInterchangeFormatLength' => array('id' => 'php:8', 'tag' => 'JPEGInterchangeFormatLength', 'categorie' => 'PhpThumbail'), |
'Thumbnail.FileType' => array('id' => 'php:9', 'tag' => 'ThumbnailFileType', 'categorie' => 'PhpThumbail'), |
'Thumbnail.MimeType' => array('id' => 'php:10', 'tag' => 'ThumbnailMimeType', 'categorie' => 'PhpThumbail'), |
'Html' => array('id' => 'php:11', 'tag' => 'Html', 'categorie' => 'PhpComputed'), |
'IsColor' => array('id' => 'php:12', 'tag' => 'IsColor', 'categorie' => 'PhpComputed'), |
'ByteOrderMotorola' => array('id' => 'php:13', 'tag' => 'ByteOrderMotorola', 'categorie' => 'PhpComputed'), |
'ApertureFNumber' => array('id' => 'php:14', 'tag' => 'ApertureFNumber', 'categorie' => 'PhpComputed'), |
'UserCommentEncoding' => array('id' => 'php:15', 'tag' => 'UserCommentEncoding', 'categorie' => 'PhpComputed'), |
'ExifImageLength' => array('id' => 'php:16', 'tag' => 'ExifImageLength', 'categorie' => 'PhpComputed'), |
'InterOperabilityIndex' => array('id' => 'php:17', 'tag' => 'InterOperabilityIndex', 'categorie' => 'PhpComputed'), |
'InterOperabilityVersion' => array('id' => 'php:18', 'tag' => 'InterOperabilityVersion', 'categorie' => 'PhpComputed'), |
'SpecialMode' => array('id' => 'php:19', 'tag' => 'SpecialMode', 'categorie' => 'PhpComputed'), |
'JPEGQuality' => array('id' => 'php:20', 'tag' => 'JPEGQuality', 'categorie' => 'PhpComputed'), |
'Macro' => array('id' => 'php:21', 'tag' => 'Macro ', 'categorie' => 'PhpComputed'), |
'DigitalZoom' => array('id' => 'php:22', 'tag' => 'DigitalZoom', 'categorie' => 'PhpComputed'), |
'SoftwareRelease' => array('id' => 'php:23', 'tag' => 'SoftwareRelease', 'categorie' => 'PhpComputed'), |
'PictureInfo' => array('id' => 'php:24', 'tag' => 'PictureInfo', 'categorie' => 'PhpComputed'), |
'CameraId' => array('id' => 'php:25', 'tag' => 'CameraId', 'categorie' => 'PhpComputed'), |
'Gps' => array('id' => 'php:26', 'tag' => 'Gps', 'categorie' => 'PhpComputed'), |
'ACDComment' => array('id' => 'php:27', 'tag' => 'ACDComment', 'categorie' => 'PhpComputed'), |
'NewSubFile' => array('id' => 'php:28', 'tag' => 'NewSubFile', 'categorie' => 'PhpComputed'), |
'Comments' => array('id' => 'php:29', 'tag' => 'Comments', 'categorie' => 'PhpComputed'), |
'TIFF/EPStandardID' => array('id' => 'php:30', 'tag' => 'TIFFEPStandardID', 'categorie' => 'PhpComputed'), |
'ModeArray' => array('id' => 'php:31', 'tag' => 'ModeArray', 'categorie' => 'PhpComputed'), |
'ImageInfo' => array('id' => 'php:32', 'tag' => 'ImageInfo', 'categorie' => 'PhpComputed'), |
'FirmwareVersion' => array('id' => 'php:33', 'tag' => 'FirmwareVersion', 'categorie' => 'PhpComputed'), |
'Camera' => array('id' => 'php:34', 'tag' => 'Camera', 'categorie' => 'PhpComputed'), |
'CustomFunctions' => array('id' => 'php:35', 'tag' => 'CustomFunctions', 'categorie' => 'PhpComputed'), |
'CCDWidth' => array('id' => 'php:36', 'tag' => 'CCDWidth', 'categorie' => 'PhpComputed'), |
'FocusDistance' => array('id' => 'php:37', 'tag' => 'FocusDistance', 'categorie' => 'PhpComputed'), |
'Keywords' => array('id' => 'php:38', 'tag' => 'Keywords', 'categorie' => 'PhpComputed'), |
'GPSVersion' => array('id' => 'php:39', 'tag' => 'GPSVersion', 'categorie' => 'PhpComputed') |
); |
private $ids_tags_iptc = array( |
'1#000' => array('id' => '0', 'tag' => 'ApplicationRecordVersion', 'categorie' => 'EnvelopeRecord'), |
'1#090' => array('id' => '90', 'tag' => 'CodedCharacterSet', 'categorie' => 'EnvelopeRecord'), |
'2#003' => array('id' => '3', 'tag' => 'ObjectTypeReference', 'categorie' => 'ApplicationRecord'), |
'2#004' => array('id' => '4', 'tag' => 'ObjectAttributeReference', 'categorie' => 'ApplicationRecord'), |
'2#005' => array('id' => '5', 'tag' => 'ObjectName', 'categorie' => 'ApplicationRecord'), |
'2#007' => array('id' => '7', 'tag' => 'EditStatus', 'categorie' => 'ApplicationRecord'), |
'2#008' => array('id' => '8', 'tag' => 'EditorialUpdate', 'categorie' => 'ApplicationRecord'), |
'2#010' => array('id' => '10', 'tag' => 'Urgency', 'categorie' => 'ApplicationRecord'), |
'2#012' => array('id' => '12', 'tag' => 'SubjectReference', 'categorie' => 'ApplicationRecord'), |
'Category' => array('id' => '15', 'tag' => 'Category', 'categorie' => 'ApplicationRecord'), |
'2#015' => array('id' => '15', 'tag' => 'Category', 'categorie' => 'ApplicationRecord'), |
'2#020' => array('id' => '20', 'tag' => 'SupplementalCategories', 'categorie' => 'ApplicationRecord'), |
'2#022' => array('id' => '22', 'tag' => 'FixtureIdentifier', 'categorie' => 'ApplicationRecord'), |
'MotsCles' => array('id' => '25', 'tag' => 'Keywords', 'categorie' => 'ApplicationRecord'), |
'2#026' => array('id' => '26', 'tag' => 'ContentLocationCode', 'categorie' => 'ApplicationRecord'), |
'2#027' => array('id' => '27', 'tag' => 'ContentLocationName', 'categorie' => 'ApplicationRecord'), |
'2#030' => array('id' => '30', 'tag' => 'ReleaseDate', 'categorie' => 'ApplicationRecord'), |
'2#035' => array('id' => '35', 'tag' => 'ReleaseTime', 'categorie' => 'ApplicationRecord'), |
'2#037' => array('id' => '37', 'tag' => 'ExpirationDate', 'categorie' => 'ApplicationRecord'), |
'2#038' => array('id' => '38', 'tag' => 'ExpirationTime', 'categorie' => 'ApplicationRecord'), |
'2#040' => array('id' => '40', 'tag' => 'SpecialInstructions', 'categorie' => 'ApplicationRecord'), |
'2#042' => array('id' => '42', 'tag' => 'ActionAdvised', 'categorie' => 'ApplicationRecord'), |
'2#045' => array('id' => '45', 'tag' => 'ReferenceService', 'categorie' => 'ApplicationRecord'), |
'2#047' => array('id' => '47', 'tag' => 'ReferenceDate', 'categorie' => 'ApplicationRecord'), |
'2#050' => array('id' => '50', 'tag' => 'ReferenceNumber', 'categorie' => 'ApplicationRecord'), |
'2#055' => array('id' => '55', 'tag' => 'DateCreated', 'categorie' => 'ApplicationRecord'), |
'2#060' => array('id' => '60', 'tag' => 'TimeCreated', 'categorie' => 'ApplicationRecord'), |
'2#062' => array('id' => '62', 'tag' => 'DigitalCreationDate', 'categorie' => 'ApplicationRecord'), |
'2#063' => array('id' => '63', 'tag' => 'DigitalCreationTime', 'categorie' => 'ApplicationRecord'), |
'2#065' => array('id' => '65', 'tag' => 'OriginatingProgram', 'categorie' => 'ApplicationRecord'), |
'2#070' => array('id' => '70', 'tag' => 'ProgramVersion', 'categorie' => 'ApplicationRecord'), |
'2#075' => array('id' => '75', 'tag' => 'ObjectCycle', 'categorie' => 'ApplicationRecord'), |
'ByLine' => array('id' => '80', 'tag' => 'By-line', 'categorie' => 'ApplicationRecord'), |
'ByLineTitle' => array('id' => '85', 'tag' => 'By-lineTitle', 'categorie' => 'ApplicationRecord'), |
'City' => array('id' => '90', 'tag' => 'City', 'categorie' => 'ApplicationRecord'), |
'SubLocation' => array('id' => '92', 'tag' => 'Sub-location', 'categorie' => 'ApplicationRecord'), |
'ProvinceState' => array('id' => '95', 'tag' => 'Province-State', 'categorie' => 'ApplicationRecord'), |
'CountryPrimaryLocationCode' => array('id' => '100', 'tag' => 'Country-PrimaryLocationCode', 'categorie' => 'ApplicationRecord'), |
'CountryName' => array('id' => '101', 'tag' => 'Country-PrimaryLocationName', 'categorie' => 'ApplicationRecord'), |
'2#103' => array('id' => '103', 'tag' => 'OriginalTransmissionReference', 'categorie' => 'ApplicationRecord'), |
'Headline' => array('id' => '105', 'tag' => 'Headline', 'categorie' => 'ApplicationRecord'), |
'Credit' => array('id' => '110', 'tag' => 'Credit', 'categorie' => 'ApplicationRecord'), |
'2#115' => array('id' => '115', 'tag' => 'Source', 'categorie' => 'ApplicationRecord'), |
'CopyrightNotice' => array('id' => '116', 'tag' => 'CopyrightNotice', 'categorie' => 'ApplicationRecord'), |
'Contact' => array('id' => '118', 'tag' => 'Contact', 'categorie' => 'ApplicationRecord'), |
'2#120' => array('id' => '120', 'tag' => 'Caption-Abstract', 'categorie' => 'ApplicationRecord'), |
'2#121' => array('id' => '121', 'tag' => 'LocalCaption', 'categorie' => 'ApplicationRecord'), |
'2#122' => array('id' => '122', 'tag' => 'Writer-Editor', 'categorie' => 'ApplicationRecord'), |
'2#125' => array('id' => '125', 'tag' => 'RasterizedCaption', 'categorie' => 'ApplicationRecord'), |
'2#130' => array('id' => '130', 'tag' => 'ImageType', 'categorie' => 'ApplicationRecord'), |
'2#131' => array('id' => '131', 'tag' => 'ImageOrientation', 'categorie' => 'ApplicationRecord'), |
'2#135' => array('id' => '135', 'tag' => 'LanguageIdentifier', 'categorie' => 'ApplicationRecord'), |
'2#150' => array('id' => '150', 'tag' => 'AudioType', 'categorie' => 'ApplicationRecord'), |
'2#151' => array('id' => '151', 'tag' => 'AudioSamplingRate', 'categorie' => 'ApplicationRecord'), |
'2#152' => array('id' => '152', 'tag' => 'AudioSamplingResolution', 'categorie' => 'ApplicationRecord'), |
'2#153' => array('id' => '153', 'tag' => 'AudioDuration', 'categorie' => 'ApplicationRecord'), |
'2#154' => array('id' => '154', 'tag' => 'AudioOutcue', 'categorie' => 'ApplicationRecord'), |
'2#184' => array('id' => '184', 'tag' => 'JobID', 'categorie' => 'ApplicationRecord'), |
'2#185' => array('id' => '185', 'tag' => 'MasterDocumentID', 'categorie' => 'ApplicationRecord'), |
'2#186' => array('id' => '186', 'tag' => 'ShortDocumentID', 'categorie' => 'ApplicationRecord'), |
'2#187' => array('id' => '187', 'tag' => 'UniqueDocumentID', 'categorie' => 'ApplicationRecord'), |
'2#188' => array('id' => '188', 'tag' => 'OwnerID', 'categorie' => 'ApplicationRecord'), |
'2#200' => array('id' => '200', 'tag' => 'ObjectPreviewFileFormat', 'categorie' => 'ApplicationRecord'), |
'2#201' => array('id' => '201', 'tag' => 'ObjectPreviewFileVersion', 'categorie' => 'ApplicationRecord'), |
'2#202' => array('id' => '202', 'tag' => 'ObjectPreviewData', 'categorie' => 'ApplicationRecord'), |
'2#221' => array('id' => '221', 'tag' => 'Prefs', 'categorie' => 'ApplicationRecord'), |
'2#225' => array('id' => '225', 'tag' => 'ClassifyState', 'categorie' => 'ApplicationRecord'), |
'2#228' => array('id' => '228', 'tag' => 'SimilarityIndex', 'categorie' => 'ApplicationRecord'), |
'2#230' => array('id' => '230', 'tag' => 'DocumentNotes', 'categorie' => 'ApplicationRecord'), |
'2#231' => array('id' => '231', 'tag' => 'DocumentHistory', 'categorie' => 'ApplicationRecord'), |
'2#232' => array('id' => '232', 'tag' => 'ExifCameraInfo', 'categorie' => 'ApplicationRecord'), |
'2#242' => array('id' => '242', 'tag' => 'Unknown242', 'categorie' => 'Unknown'), |
'2#254' => array('id' => '254', 'tag' => 'Unknown254', 'categorie' => 'Unknown'), |
'2#255' => array('id' => '255', 'tag' => 'CatalogSets', 'categorie' => 'ApplicationRecord') |
); |
public function __construct(Conteneur $conteneur) { |
$bddMigration = $conteneur->getParametre('database_cel.database_migration'); |
if ($bddMigration == null || $bddMigration == '') { |
echo 'Attention la variable de configuration database_migration dans la section database_cel, contenant la base de données d\'arrivée, doit être remplie '."\n"; |
exit; |
} |
$bddIdentification = $conteneur->getParametre('database_ident.database'); |
if ($bddIdentification == null || $bddIdentification == '') { |
echo 'Attention la variable de configuration database dans la section database_ident, contenant la base de données utilisateurs, doit être remplie '."\n"; |
exit; |
} |
self::$bdd_cel_migration = $conteneur->getParametre('database_cel.database_migration'); |
self::$bdd_utilisateurs = $conteneur->getParametre('database_ident.database'); |
$this->bdd = $conteneur->getBdd(); |
$this->script = $conteneur->getScript(); |
$this->cle_id_metadonnees = array_merge($this->ids_tags_exif, $this->ids_tags_iptc); |
} |
/** |
* Méthode appelée pour executer le script. |
*/ |
public function executer($params) { |
echo "--MIGRATION DES IMAGES --------------------------------------\n"; |
//1. TEMPORAIRE : vider les tables de destinations |
if (self::truncate) { |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 0. Vider les tables ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$nouvellesTables = array('cel_images', 'cel_obs_images'); |
foreach ($nouvellesTables as $nomTable) { |
echo 'Vider la table '.$nomTable.'...'; |
$requeteTruncate = 'TRUNCATE TABLE '.self::$bdd_cel_migration.'.'.$nomTable; |
$resultatTruncate = $this->bdd->executer($requeteTruncate); |
echo "ok \n"; |
} |
} |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 1. Paramétrage ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->getUtilisateurs(); |
$this->getObservations(); |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 2. Migration des images ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->migrerImages(); |
$this->mettreANullPrenomNomVide(); |
$this->ordonnerImages(); |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 3. migration des liaisons obs images ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->migrerLiaisonsObsImages(); |
} |
private function getUtilisateurs() { |
echo "SELECTION DES UTILISATEURS\n"; |
$requete = 'SELECT U_ID as id, U_MAIL as mail, U_NAME as nom, U_SURNAME as prenom, U_PASSWD as pass '. |
'FROM '.self::$bdd_utilisateurs.'.annuaire_tela'; |
$tableau_utilisateurs = $this->bdd->requeter($requete); |
foreach ($tableau_utilisateurs as &$utilisateur) { |
$this->tableau_utilisateurs[$utilisateur['mail']] = $utilisateur; |
} |
echo sizeof($this->tableau_utilisateurs)." utilisateurs sélectionnés\n"; |
} |
private function getObservations() { |
$pas = 5000; |
$nObs = 'SELECT COUNT(*) AS nb FROM cel_inventory'; |
$resultatNbObs = $this->bdd->requeter($nObs, Bdd::SQL_RETOUR_COLONNE); |
$nbObs = $resultatNbObs; |
$maxLimite = $nbObs + $pas; |
for ($i = 0; $i < $maxLimite; $i += $pas ) { |
$requete_selection_observations = "SELECT id, ordre, identifiant FROM cel_inventory LIMIT $i,$pas "; |
$tableau_observations = $this->bdd->requeter($requete_selection_observations); |
foreach ($tableau_observations as &$obs) { |
$this->tableau_observations[$obs['identifiant']][$obs['ordre']] = $obs['id']; |
} |
$this->script->afficherAvancement('Selection des observations (par '.$pas.' )'); |
} |
echo "\n"; |
} |
private function migrerImages() { |
$pas = 100; |
//Selectionner le nombre d'images |
$requeteNbImg = "SELECT COUNT(*) as nb FROM cel_images"; |
$fin = $this->bdd->requeter($requeteNbImg, BDD::SQL_RETOUR_COLONNE); |
$maxLimite = $fin + $pas; |
for ($i = 0; $i <= $maxLimite ; $i += $pas) { |
$requete = "SELECT * FROM cel_images ORDER BY ci_id_image ASC LIMIT $i,$pas "; |
$images = $this->bdd->requeter($requete); |
if (is_array($images)) { |
$imagesNouvelles = array(); |
foreach ($images as $image) { |
$image = $this->traiterLigneImage($image); |
$image = array_map(array($this, 'protegerSiNonNull'), $image); |
$imagesNouvelles[] = '('.implode(',', array_values($image)).')'; |
} |
$bdd = self::$bdd_cel_migration; |
$champs = implode(', ', array_keys($this->tableau_nouveau_ancien)); |
$values = implode(',', $imagesNouvelles); |
$requete = "INSERT INTO $bdd.cel_images ($champs) VALUES $values "; |
$migration_images = $this->executerRequeteSimple($requete); |
if (!$migration_images) { |
echo 'La migration des images '.$i.' à '.($i + count($images)).' a échoué '."\n"; |
file_put_contents('/home/jpm/requete.sql', $requete); |
} else { |
$this->script->afficherAvancement('Migration des images (par '.$pas.' )'); |
} |
} |
if (count($images) < $pas) { |
echo "\n"; |
return; |
} |
} |
} |
private function ordonnerImages() { |
$requete = 'ALTER TABLE '.self::$bdd_cel_migration.'.cel_images ORDER BY id_image'; |
$this->executerRequeteSimple($requete); |
} |
private function executerRequeteSimple($requete) { |
// Fonction de commodité pour afficher les requetes au lieu de les executer |
if (self::dry_run) { |
echo str_replace('),','),'."\n", $requete)."\n"; |
return true; |
} else { |
return $this->bdd->executer($requete); |
} |
} |
private function traiterLigneImage($image) { |
$nouvelle_image = array(); |
foreach ($this->tableau_nouveau_ancien as $nouveau_champ_image => $ancien_champ_image) { |
if ($this->estUnChampATraiter($ancien_champ_image)) { |
if (method_exists($this,$ancien_champ_image)) { |
$nouvelle_image[$nouveau_champ_image] = $this->$ancien_champ_image($image); |
} else { |
echo 'methode manquante : '.$ancien_champ_image."\n"; |
$nouvelle_image[$nouveau_champ_image] = ''; |
} |
} else { |
$nouvelle_image[$nouveau_champ_image] = $image[$ancien_champ_image]; |
} |
} |
return $nouvelle_image; |
} |
private function estUnChampATraiter($champ) { |
return strpos($champ, 'traiter') !== false; |
} |
private function protegerSiNonNull($valeur) { |
if ($valeur != 'NULL') { |
$valeur = $this->bdd->proteger($valeur); |
} |
return $valeur; |
} |
private function traiterIdentifiantUtilisateur($ligne_image) { |
$mail_image = $ligne_image['ci_ce_utilisateur']; |
$retour = $this->renvoyerIdPourMigration($mail_image); |
return $retour; |
} |
private function renvoyerIdPourMigration($utilisateur) { |
// si tout les test suivant échouent, on garde l'utilisateur tel quel (cas de la chaine de session des utilisateur anonymes) |
$retour = $utilisateur; |
// si le mail correspond a un utilisateur de la bdd |
if (isset($this->tableau_utilisateurs[$utilisateur])) { |
// on renvoie son id |
$retour = $this->tableau_utilisateurs[$utilisateur]['id']; |
} else { |
// sinon si c'est un mail inconnu, on garde le md5 |
if($this->mailValide($utilisateur)) { |
$retour = md5($utilisateur); |
} |
} |
return $retour; |
} |
private function mailValide($mail) { |
// vérification bidon mais ça suffit pour ici |
return !(strpos($mail, '@') === false); |
} |
private function traiterPrenomUtilisateur($ligne_image) { |
$mail_image = $ligne_image['ci_ce_utilisateur']; |
$retour = $mail_image; |
if (isset($this->tableau_utilisateurs[$mail_image])) { |
$retour = self::formaterMotPremiereLettreChaqueMotEnMajuscule($this->tableau_utilisateurs[$mail_image]['prenom']); |
} else { |
$retour = ''; |
} |
return $retour; |
} |
public static function formaterMotPremiereLettreChaqueMotEnMajuscule($chaine, $encodage= 'UTF-8') { |
$chaine = str_replace('-', ' - ', $chaine); |
$chaine = mb_strtolower($chaine, $encodage); |
$chaine = mb_convert_case($chaine, MB_CASE_TITLE, $encodage); |
$chaine = str_replace(' - ', '-', $chaine); |
return $chaine; |
} |
private function traiterNomUtilisateur($ligne_image) { |
$mail_image = $ligne_image['ci_ce_utilisateur']; |
$retour = $mail_image; |
if (isset($this->tableau_utilisateurs[$mail_image])) { |
$retour = self::formaterMotEnMajuscule($this->tableau_utilisateurs[$mail_image]['nom']); |
} else { |
$retour = ''; |
} |
return $retour; |
} |
public static function formaterMotEnMajuscule($chaine, $encodage= 'UTF-8') { |
return mb_convert_case($chaine, MB_CASE_UPPER, $encodage); |
} |
private function traiterNoteImage($image) { |
$retour = $image['ci_note_image']; |
if ($image['ci_note_image'] == '-1') { |
$retour = 'NULL'; |
} |
return $retour; |
} |
private function traiterExif($ligne_image) { |
$metadonnees_autres = $this->decoderTableauMetaDonnees($ligne_image['ci_meta_exif_autres']); |
$metadonnees = array_intersect_key($ligne_image, array_flip($this->champs_exifs_non_gardes))+$metadonnees_autres; |
$retour = 'NULL'; |
if ($xml = $this->convertirTableauMetadonneesEnXml($metadonnees)) { |
$retour = '<?xml version="1.0" encoding="UTF-8" ?>'."\n". |
'<exif>'."\n".$xml.'</exif>'; |
} |
return $retour; |
} |
private function traiterIptc($ligne_image) { |
$metadonnees_autres = $this->decoderTableauMetaDonnees($ligne_image['ci_meta_iptc_autres']); |
$metadonnees = array_intersect_key($ligne_image, array_flip($this->champs_iptc_non_gardes)) + $metadonnees_autres; |
$retour = 'NULL'; |
if ($xml = $this->convertirTableauMetadonneesEnXml($metadonnees)) { |
$retour = '<?xml version="1.0" encoding="UTF-8" ?>'."\n". |
'<iptc>'."\n".$xml.'</iptc>'; |
} |
return $retour; |
} |
private function traiterXmp($ligne_image) { |
$retour = 'NULL'; |
return $retour; |
} |
private function traiterMakernote($ligne_image) { |
$retour = 'NULL'; |
return $retour; |
} |
private function decoderTableauMetaDonnees($chaine) { |
$tableau_valeurs_decodees = array(); |
if (trim($chaine) != '') { |
$tableau_meta = explode(self::separateur_champs_metadonnees, $chaine); |
foreach ($tableau_meta as &$chaine_meta) { |
if (strpos($chaine_meta, 'UndefinedTag:') !== false) { |
$chaine_meta = str_replace('UndefinedTag:', 'UndefinedTag', $chaine_meta); |
} |
$cle_valeur = explode(self::separateur_valeurs_metadonnees, $chaine_meta, 2); |
if (is_array($cle_valeur) && count($cle_valeur) == 2) { |
$cle = ltrim($cle_valeur[0], ' '); |
$tableau_valeurs_decodees[$cle] = $cle_valeur[1]; |
} |
} |
} |
return $tableau_valeurs_decodees; |
} |
private function convertirTableauMetadonneesEnXml($tableau) { |
$xml = ''; |
foreach ($tableau as $cle => $valeur) { |
$cle = str_replace('ci_meta_exif_', '', $cle); |
$cle = str_replace('ci_meta_iptc_', '', $cle); |
$cle = str_replace('ci_meta_', '', $cle); |
$cle = str_replace('_', ' ', $cle); |
$cle = ucwords($cle); |
$cle = str_replace(' ', '', $cle); |
$valeur = str_replace("\0", '', $valeur); |
if (isset($this->cle_id_metadonnees[$cle])) { |
$id = $this->cle_id_metadonnees[$cle]['id']; |
$tag = $this->cle_id_metadonnees[$cle]['tag']; |
$categorie = $this->cle_id_metadonnees[$cle]['categorie']; |
$xml .= '<'.$tag.' id="'.$id.'" categorie="'.$categorie.'">'.$valeur.'</'.$tag.'>'."\n"; |
} else { |
$xml .= '<'.$cle.' categorie="Undefined">'.$valeur.'</'.$cle.'>'."\n"; |
} |
} |
return $xml; |
} |
private function migrerLiaisonsObsImages() { |
$pas = 500; |
$liaisons_obs_inexistantes = 0; |
//Selectionner le nombre de liaisons |
$requeteNbImgObs = "SELECT COUNT(*) AS nb FROM cel_obs_images"; |
$fin = $this->bdd->requeter($requeteNbImgObs, Bdd::SQL_RETOUR_COLONNE); |
echo "Nbre de liaisons à migrer : $fin\n"; |
for ($i = 0; $i <= $fin ; $i += $pas) { |
$requete = "SELECT * FROM cel_obs_images LIMIT $i,$pas "; |
$tableau_liaisons = $this->bdd->requeter($requete); |
if (is_array($tableau_liaisons)) { |
$liaisonsNouvelles = array(); |
foreach ($tableau_liaisons as $liaison) { |
$mail_utilisateur = $liaison['coi_ce_utilisateur']; |
$ordre_obs = $liaison['coi_ce_observation']; |
if (isset($this->tableau_observations[$mail_utilisateur][$ordre_obs])) { |
$id_obs = $this->bdd->proteger($this->tableau_observations[$mail_utilisateur][$ordre_obs]); |
$id_image = $this->bdd->proteger($liaison['coi_ce_image']); |
$date_liaison = $this->bdd->proteger($liaison['coi_date_liaison']); |
$liaisonsNouvelles[] = "($id_image, $id_obs, $date_liaison)"; |
} else { |
// cas d'une observation inexistante, la liaison est ignorée |
$liaisons_obs_inexistantes++; |
} |
} |
if (count($liaisonsNouvelles) != 0) { |
$sousRequete = implode(',', $liaisonsNouvelles); |
$requete = 'INSERT INTO '.self::$bdd_cel_migration.'.cel_obs_images '. |
'(id_image, id_observation, date_liaison) '. |
"VALUES $sousRequete "; |
$migration_liaison = $this->executerRequeteSimple($requete); |
if (!$migration_liaison) { |
echo 'La migration des liaisons obs images de '.$i.' à '.($i+$pas).' a échoué ! '."\n<br />"; |
} else { |
$this->script->afficherAvancement('Migration des liaisons obs images (par '.$pas.' )'); |
} |
} |
} |
} |
echo "\n"; |
echo $liaisons_obs_inexistantes ? $liaisons_obs_inexistantes." liaisons image obs ont été ignorées car les obs sont absentes\n" : '' ; |
} |
private function mettreANullPrenomNomVide() { |
$bdd = self::$bdd_cel_migration; |
$requete = "UPDATE $bdd.cel_images ". |
'SET prenom_utilisateur = NULL '. |
"WHERE prenom_utilisateur = '' "; |
$this->bdd->executer($requete); |
$requete = "UPDATE $bdd.cel_images ". |
'SET nom_utilisateur = NULL '. |
"WHERE nom_utilisateur = '' "; |
$this->bdd->executer($requete); |
} |
} |
/branches/v1.6-croc/jrest/scripts/MigrationMotsCles.php |
---|
New file |
0,0 → 1,392 |
<?php |
// declare(encoding='UTF-8'); |
/** |
* Script de migration des Mots Clés de la version 1 de la base de données du CEL à la v2. |
* Utilisation : /opt/lampp/bin/php cli.php MigrationMotsCles |
* |
* @category php 5.2 |
* @package Cel/Scripts |
* @author Aurelien PERONNET <aurelien@tela-botanica.org> |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Copyright (c) 2012, Tela Botanica (accueil@tela-botanica.org) |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version $Id$ |
*/ |
class MigrationMotsCles { |
const SEPARATEUR_MOT_CLE_TEXTE = ','; |
const truncate = true; //Doit on vider les tables de destination ? |
const dry_run = false; |
private $bdd = null; |
private $script = null; |
private $nouvellesTables = array('cel_mots_cles_obs', 'cel_mots_cles_images', 'cel_images_mots_cles', 'cel_obs_mots_cles'); |
public static $bdd_cel_migration; |
public static $bdd_utilisateurs; |
private $tableau_utilisateurs = array(); |
/** Tableau associatif permettant de stocker l'avancement dans une boucle. |
* La clé est un md5 du message à afficher au démarrage de la boucle. |
* @var array |
*/ |
private static $avancement = array(); |
public function __construct(Conteneur $conteneur) { |
$bddMigration = $conteneur->getParametre('database_cel.database_migration'); |
if ($bddMigration == null || $bddMigration == '') { |
echo 'Attention la variable de configuration database_migration dans la section database_cel, contenant la base de données d\'arrivée, doit être remplie '."\n"; |
exit; |
} |
$bddIdentification = $conteneur->getParametre('database_ident.database'); |
if ($bddIdentification == null || $bddIdentification == '') { |
echo 'Attention la variable de configuration database dans la section database_ident, contenant la base de données utilisateurs, doit être remplie '."\n"; |
exit; |
} |
self::$bdd_cel_migration = $conteneur->getParametre('database_cel.database_migration'); |
self::$bdd_utilisateurs = $conteneur->getParametre('database_ident.database'); |
$this->bdd = $conteneur->getBdd(); |
$this->script = $conteneur->getScript(); |
} |
/** |
* Méthode appelée pour executer le script. |
*/ |
public function executer($params) { |
echo "--MIGRATION DES MOTS CLES --------------------------------------\n"; |
if (self::truncate) { |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 0. Vider les tables ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->viderTables(); |
} |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 1. Paramétrage ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->getUtilisateurs(); |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 2. Migration des mots clés ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->migrerTableMotsClesObs(); |
$this->migrerTableMotsClesImages(); |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 3. Migration des liaisons mots clés ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->migrerLiaisonsMotsClesObs(); |
$this->migrerLiaisonsMotsClesImages(); |
echo "-------------------------------------------------------------------\n"; |
echo " ETAPE 4. Génération des index des mots clés ... \n"; |
echo "-------------------------------------------------------------------\n"; |
$this->genererIndexTexteMotsClesObs(); |
$this->genererIndexTexteMotsClesImages(); |
$this->mettreANullMotsClesTxtVide(); |
} |
private function viderTables() { |
foreach ($this->nouvellesTables as $nomTable) { |
echo 'Vider la table '.$nomTable.'...'; |
$requete = 'TRUNCATE TABLE '.self::$bdd_cel_migration.'.'.$nomTable; |
$resultat = $this->bdd->executer($requete); |
echo "ok \n"; |
} |
} |
private function executerRequeteSimple($requete) { |
// Fonction de commodité pour afficher les requetes au lieu de les executer |
if (self::dry_run) { |
echo str_replace('),','),'."\n", $requete); |
return true; |
} else { |
return $this->bdd->executer($requete); |
} |
} |
private function getUtilisateurs() { |
echo "SELECTION DES UTILISATEURS\n"; |
$requete = 'SELECT U_ID as id, U_MAIL as mail, U_NAME as nom, U_SURNAME as prenom, U_PASSWD as pass '. |
'FROM '.self::$bdd_utilisateurs.'.annuaire_tela'; |
$tableau_utilisateurs = $this->bdd->requeter($requete); |
foreach( $tableau_utilisateurs as &$utilisateur) { |
$this->tableau_utilisateurs[$utilisateur['mail']] = $utilisateur; |
} |
echo count($this->tableau_utilisateurs)." utilisateurs sélectionnés \n"; |
} |
private function migrerTableMotsClesObs() { |
$this->migrerTableMotsCles('obs'); |
} |
private function migrerTableMotsClesImages() { |
$this->migrerTableMotsCles('images'); |
} |
private function migrerTableMotsCles($image_ou_obs) { |
echo "MIGRATION DES MOTS CLES $image_ou_obs\n"; |
$pas = 1; |
//limite des mots clés |
$requeteNbMotsCles = 'SELECT count(*) as nb FROM cel_mots_cles_'.$image_ou_obs; |
$nbMotsCles = (int) $this->bdd->requeter($requeteNbMotsCles, Bdd::SQL_RETOUR_COLONNE); |
for ($i = 0; $i < $nbMotsCles; $i += $pas) { |
$requete = 'SELECT * '. |
'FROM cel_mots_cles_'.$image_ou_obs.' '. |
'ORDER BY cmc_niveau '. |
"LIMIT $i,$pas "; |
$arbres_mots_cles = $this->bdd->requeter($requete); |
if (count($arbres_mots_cles) > 0) { |
$champ_parent = ($image_ou_obs == "obs") ? 'ce_mot_cle_obs_parent' : 'ce_mot_cle_image_parent'; |
$champ_id = ($image_ou_obs == "obs") ? 'id_mot_cle_obs' : 'id_mot_cle_image'; |
$requete = 'INSERT INTO '.self::$bdd_cel_migration.".cel_mots_cles_$image_ou_obs ". |
"($champ_id, id_utilisateur, mot_cle, md5, bg, bd, niveau, $champ_parent) ". |
'VALUES '; |
$sous_requete = array(); |
foreach ($arbres_mots_cles as $arbre_mot_cle) { |
$sous_requete[] = $this->construireSousRequeteInsertionArbresMotsCles('cmc_', $arbre_mot_cle); |
} |
$sous_requete = implode(',', $sous_requete); |
$requete .= $sous_requete; |
$migration = $this->executerRequeteSimple($requete); |
if (!$migration) { |
echo "La migration des mots cles $image_ou_obs a échoué ! "."\n"; |
} else { |
$this->script->afficherAvancement("Migration des mots clés $image_ou_obs (par $pas)"); |
} |
} |
} |
echo "\n"; |
} |
private function construireSousRequeteInsertionArbresMotsCles($prefixe, $ligne) { |
$id_proprietaire_mot_cle = $ligne[$prefixe.'id_proprietaire']; |
$id_proprietaire_mot_cle = $this->renvoyerIdPourMigration($id_proprietaire_mot_cle); |
$sous_requete = '('.$this->bdd->proteger($ligne[$prefixe.'id_mot_cle_utilisateur']).','. |
$this->bdd->proteger($id_proprietaire_mot_cle).','. |
$this->bdd->proteger($ligne[$prefixe.'mot_cle']).','. |
$this->bdd->proteger($ligne[$prefixe.'id_mot_cle_general']).','. |
$this->bdd->proteger($ligne[$prefixe.'bg']).','. |
$this->bdd->proteger($ligne[$prefixe.'bd']).','. |
$this->bdd->proteger($ligne[$prefixe.'niveau']).','. |
$this->bdd->proteger($ligne[$prefixe.'id_parent']). |
')'; |
return $sous_requete; |
} |
private function renvoyerIdPourMigration($utilisateur) { |
// si tout les test suivant échouent, on garde l'utilisateur tel quel |
// (cas de la chaine de session des utilisateur anonymes) |
$retour = $utilisateur; |
// si le mail correspond a un utilisateur de la bdd |
if (isset($this->tableau_utilisateurs[$utilisateur])) { |
// on renvoie son id |
$retour = $this->tableau_utilisateurs[$utilisateur]['id']; |
} else { |
// sinon si c'est un mail inconnu, on garde le md5 |
if ($this->mailValide($utilisateur)) { |
$retour = md5($utilisateur); |
} |
} |
return $retour; |
} |
private function mailValide($mail) { |
// vérification bidon mais ça suffit pour ici |
return !(strpos($mail, '@') === false); |
} |
private function migrerLiaisonsMotsClesObs() { |
$requete = 'SELECT mots_cles AS mots_cles, id AS id, identifiant AS id_utilisateur '. |
'FROM cel_inventory '. |
'WHERE mots_cles != "" '. |
' AND mots_cles != "NULL" '. |
' AND mots_cles != "null" '. |
' AND mots_cles IS NOT NULL '. |
'ORDER BY identifiant '; |
$mots_cles_obs = $this->bdd->requeter($requete); |
$requete = 'INSERT INTO '.self::$bdd_cel_migration.'.cel_obs_mots_cles '. |
'(id_observation, id_mot_cle_obs, id_utilisateur) '. |
'VALUES '. |
$this->construireSousRequeteInsertionLiaisons($mots_cles_obs, ';'); |
$insertion = $this->executerRequeteSimple($requete); |
if (!$insertion) { |
echo 'La migration des mots cles obs a échoué ! '."\n"; |
} else { |
echo "Migration des mots cles obs : OK\n"; |
} |
} |
private function migrerLiaisonsMotsClesImages() { |
$requete = 'SELECT ci_meta_mots_cles AS mots_cles, ci_id_image AS id, ci_ce_utilisateur AS id_utilisateur '. |
'FROM cel_images '. |
'WHERE ci_meta_mots_cles != "" '. |
' AND ci_meta_mots_cles != "NULL" '. |
' AND ci_meta_mots_cles != "null" '. |
' AND ci_meta_mots_cles IS NOT NULL '. |
'ORDER BY ci_ce_utilisateur'; |
$mots_cles_images = $this->bdd->requeter($requete); |
$requete = 'INSERT INTO '.self::$bdd_cel_migration.'.cel_images_mots_cles '. |
'(id_image, id_mot_cle_image, id_utilisateur) '. |
'VALUES '. |
$this->construireSousRequeteInsertionLiaisons($mots_cles_images, ','); |
$insertion = $this->executerRequeteSimple($requete); |
if (!$insertion) { |
echo 'La migration des mots cles images a échoué ! '."\n"; |
} else { |
echo "Migration des mots cles images : OK\n"; |
} |
} |
private function construireSousRequeteInsertionLiaisons($tableau_mots_cles, $separateur) { |
$sous_requete = array(); |
foreach ($tableau_mots_cles as $element) { |
$mots_cles_ids = $this->parserMotsCles($element['mots_cles'], $separateur); |
foreach ($mots_cles_ids as $mot_cle_id) { |
$id = $this->bdd->proteger($element['id']); |
$id_mot_cle = $this->bdd->proteger($mot_cle_id); |
$id_utilisateur = $this->bdd->proteger($this->renvoyerIdPourMigration($element['id_utilisateur'])); |
$sous_requete[] = "($id, $id_mot_cle, $id_utilisateur)"; |
} |
} |
$sous_requete_chaine = implode(',', $sous_requete); |
return $sous_requete_chaine; |
} |
private function parserMotsCles($mot_cles, $separateur = ',') { |
$mot_cles = trim($mot_cles, $separateur); |
$tableau_mots_cles = explode($separateur, $mot_cles); |
$tableau_mots_cles_formates = array(); |
foreach ($tableau_mots_cles as $mot_cle) { |
$mot_cle = str_replace($separateur.$separateur, '', $mot_cle); |
$mot_cle = str_replace('null', '', $mot_cle); |
$mot_cle = trim($mot_cle); |
if ($this->estUnIdentifiantMotCle($mot_cle)) { |
// certains mots clés mal formatés contiennent des virgules |
if (strpos($mot_cle, ',') !== false) { |
$tab_mot_cle_mal_formate = explode(',', $mot_cle); |
foreach ( $tab_mot_cle_mal_formate as $mot_cle_mal_formate) { |
if ($this->estUnIdentifiantMotCle($mot_cle_mal_formate)) { |
$tableau_mots_cles_formates[$mot_cle_mal_formate] = $mot_cle_mal_formate; |
} |
} |
} else { |
// on met le mot clé dans sa propre case afin d'éviter |
// facilement les doublons provoqués par de mauvais formatages |
$tableau_mots_cles_formates[$mot_cle] = $mot_cle; |
} |
} else if ($mot_cle != '') { |
echo "N'est pas un mot clé : $mot_cle\n"; |
} |
} |
return $tableau_mots_cles_formates; |
} |
private function estUnIdentifiantMotCle($chaine) { |
return preg_match('/^(?:[-][0-9]+[.][0-9]+|[-_a-z0-9]+(?:[.][-_a-z0-9]+)*)$/i', $chaine); |
} |
private function genererIndexTexteMotsClesObs() { |
$requete = 'SELECT DISTINCT id_observation, id_utilisateur '. |
'FROM '.self::$bdd_cel_migration.'.cel_obs_mots_cles '; |
$obs_a_mots_cles = $this->bdd->requeter($requete); |
foreach ($obs_a_mots_cles as $obs) { |
$mots_cles_texte = $this->obtenirMotsClesTexte($obs['id_observation'], $obs['id_utilisateur'], 'obs'); |
if (is_array($mots_cles_texte) && count($mots_cles_texte) > 0) { |
$mots_cles_texte_chaine = implode(',', $mots_cles_texte); |
$mise_a_jour_index = $this->executerRequeteMiseAJourMotCleTexte($mots_cles_texte_chaine, $obs['id_observation'], $obs['id_utilisateur'], 'obs'); |
$this->script->afficherAvancement('Génération des index mots clés obs (par 1)'); |
} |
} |
echo "\n"; |
} |
private function genererIndexTexteMotsClesImages() { |
$requete = 'SELECT DISTINCT id_image, id_utilisateur '. |
'FROM '.self::$bdd_cel_migration.'.cel_images_mots_cles '; |
$images_a_mots_cles = $this->bdd->requeter($requete); |
foreach ($images_a_mots_cles as $image) { |
$mots_cles_texte = $this->obtenirMotsClesTexte($image['id_image'], $image['id_utilisateur'], 'images'); |
$mots_cles_texte_chaine = ''; |
if (is_array($mots_cles_texte) && count($mots_cles_texte) > 0) { |
$mots_cles_texte_chaine = implode(',', $mots_cles_texte); |
$mise_a_jour_index = $this->executerRequeteMiseAJourMotCleTexte($mots_cles_texte_chaine, $image['id_image'], $image['id_utilisateur'], 'images'); |
$this->script->afficherAvancement('Génération des index mots clés images (par 1)'); |
} |
} |
echo "\n"; |
} |
private function obtenirMotsClesTexte($id_image_ou_obs, $id_utilisateur, $mode) { |
$bdd = self::$bdd_cel_migration; |
$champ_id_mot_cle = ($mode == 'obs') ? 'id_mot_cle_obs' : 'id_mot_cle_image'; |
$champ_id_obs_ou_img = ($mode == 'obs') ? 'id_observation' : 'id_image'; |
$id_image_ou_obs = $this->bdd->proteger($id_image_ou_obs); |
$id_utilisateur = $this->bdd->proteger($id_utilisateur); |
$requete = 'SELECT mot_cle '. |
"FROM $bdd.cel_mots_cles_$mode AS a ". |
" INNER JOIN $bdd.cel_{$mode}_mots_cles AS b ". |
" ON (a.$champ_id_mot_cle = b.$champ_id_mot_cle AND a.id_utilisateur = b.id_utilisateur) ". |
"WHERE b.$champ_id_obs_ou_img = $id_image_ou_obs ". |
" AND a.id_utilisateur = $id_utilisateur "; |
$resultats = $this->bdd->requeter($requete); |
$mots_cles = array(); |
foreach ($resultats as $resultat) { |
$mots_cles[] = $resultat['mot_cle']; |
} |
return $mots_cles; |
} |
private function executerRequeteMiseAJourMotCleTexte($mots_cles_texte_chaine, $id_image_ou_obs, $id_utilisateur, $mode_image_ou_obs) { |
$bdd = self::$bdd_cel_migration; |
$table = ($mode_image_ou_obs == 'obs') ? 'cel_obs' : 'cel_images'; |
$chp_id_obs_ou_img = ($mode_image_ou_obs == 'obs') ? 'id_observation' : 'id_image'; |
$id_image_ou_obs = $this->bdd->proteger($id_image_ou_obs); |
$mots_cles_texte = $this->bdd->proteger($mots_cles_texte_chaine); |
$ce_utilisateur = $this->bdd->proteger($id_utilisateur); |
$requete = "UPDATE $bdd.$table ". |
"SET mots_cles_texte = $mots_cles_texte ". |
"WHERE $chp_id_obs_ou_img = $id_image_ou_obs ". |
" AND ce_utilisateur = $ce_utilisateur "; |
return $this->bdd->executer($requete); |
} |
private function mettreANullMotsClesTxtVide() { |
$bdd = self::$bdd_cel_migration; |
$tables = array('cel_obs', 'cel_images'); |
foreach ($tables as $table) { |
$requete = "UPDATE $bdd.$table ". |
'SET mots_cles_texte = NULL '. |
"WHERE mots_cles_texte = '' "; |
$this->bdd->executer($requete); |
} |
} |
} |
/branches/v1.6-croc/jrest/.htaccess |
---|
New file |
0,0 → 1,7 |
#AddHandler x-httpd-php5 .php |
AddDefaultCharset UTF-8 |
RewriteEngine On |
RewriteCond %{REQUEST_FILENAME} !-d |
RewriteCond %{REQUEST_FILENAME} !-f |
RewriteRule ^.*$ index.php/ |
/branches/v1.6-croc/jrest/migrationBdd.sh |
---|
New file |
0,0 → 1,4 |
#!/bin/bash |
/opt/lampp/bin/php cli.php MigrationObs |
/opt/lampp/bin/php cli.php MigrationImages |
/opt/lampp/bin/php cli.php MigrationMotsCles |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/v1.6-croc/jrest/JRest.php |
---|
New file |
0,0 → 1,308 |
<?php |
// In : utf8 url_encoded (get et post) |
// Out : utf8 |
// TODO : gerer les retours : dans ce controleur : code retour et envoi ... |
class JRest { |
/** Parsed configuration file */ |
private $config; |
/** The HTTP request method used. */ |
private $method = 'GET'; |
/** The HTTP request data sent (if any). */ |
private $requestData = NULL; |
/** Array of strings to convert into the HTTP response. */ |
private $output = array(); |
/** Nom resource. */ |
private $resource = NULL; |
/** Identifiant unique resource. */ |
private $uid = NULL; |
/** |
* Constructor. Parses the configuration file "JRest.ini", grabs any request data sent, records the HTTP |
* request method used and parses the request URL to find out the requested resource |
* @param str iniFile Configuration file to use |
*/ |
public function JRest($iniFile = 'jrest.ini.php') { |
$this->config = parse_ini_file($iniFile, TRUE); |
if (isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && isset($_SERVER['QUERY_STRING'])) { |
if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 0) { |
$this->requestData = ''; |
$httpContent = fopen('php://input', 'r'); |
while ($data = fread($httpContent, 1024)) { |
$this->requestData .= $data; |
} |
fclose($httpContent); |
} |
if (strlen($_SERVER['QUERY_STRING']) == 0) { |
$len = strlen($_SERVER['REQUEST_URI']); |
} else { |
$len = -(strlen($_SERVER['QUERY_STRING']) + 1); |
} |
$urlString = ''; |
if (substr_count($_SERVER['REQUEST_URI'], $this->config['settings']['baseURL']) > 0) { |
$urlString = substr($_SERVER['REQUEST_URI'], strlen($this->config['settings']['baseURL']), $len); |
} else if (substr_count($_SERVER['REQUEST_URI'], $this->config['settings']['baseAlternativeURL']) > 0) { |
$urlString = substr($_SERVER['REQUEST_URI'], strlen($this->config['settings']['baseAlternativeURL']), $len); |
} |
$urlParts = explode('/', $urlString); |
if (isset($urlParts[0])) $this->resource = $urlParts[0]; |
if (count($urlParts) > 1 && $urlParts[1] != '') { |
array_shift($urlParts); |
foreach ($urlParts as $uid) { |
if ($uid != '') { |
$this->uid[] = urldecode($uid); |
} |
} |
} |
$this->method = $_SERVER['REQUEST_METHOD']; |
} else { |
trigger_error('I require the server variables REQUEST_URI, REQUEST_METHOD and QUERY_STRING to work.', E_USER_ERROR); |
} |
} |
/** |
* Execute the request. |
*/ |
function exec() { |
switch ($this->method) { |
case 'GET': |
$this->get(); |
break; |
case 'POST': |
$this->post(); |
break; |
case 'DELETE': |
$this->delete(); |
break; |
case 'PUT': |
$this->add(); |
break; |
} |
} |
/** |
* Execute a GET request. A GET request fetches a list of resource when no resource name is given, a list of element |
* when a resource name is given, or a resource element when a resource and resource unique identifier are given. It does not change the |
* database contents. |
*/ |
private function get() { |
if ($this->resource) { |
$resource_file = 'services/'.ucfirst($this->resource).'.php'; |
$resource_class = ucfirst($this->resource); |
if (file_exists($resource_file)) { |
include_once $resource_file; |
if (class_exists($resource_class)) { |
$service = new $resource_class($this->config); |
if ($this->uid) { // get a resource element |
if (method_exists($service, 'getElement')) { |
$service->getElement($this->uid); |
} |
} elseif (method_exists($service, 'getRessource')) { // get all elements of a ressource |
$service->getRessource(); |
} |
} |
} |
} else { // get resources |
// include set.jrest.php, instanticiation et appel |
} |
} |
private function post() { |
$pairs = array(); |
// Récupération des paramètres passés dans le contenu de la requête HTTP (= POST) |
if ($this->requestData) { |
$pairs = $this->parseRequestData(); |
} |
// Ajout des informations concernant l'upload de fichier passées dans la variable $_FILE |
if(isset($_FILES)) { |
foreach ($_FILES as $v) { |
$pairs[$v['name']] = $v; |
} |
// Ne pas effacer cette ligne ! Elle est indispensable pour les services du Carnet en ligne |
// qui n'utilisent que le tableau pairs dans les posts |
$pairs = array_merge($pairs, $_POST); |
} |
// gestion du contenu du post |
if(isset($_POST)) |
{ |
// Safari ne sait pas envoyer des DELETE avec gwt... |
// Nous utilisons le parametre "action" passé dans le POST qui doit contenir DELETE pour lancer la supression |
if (isset($pairs['action']) && $pairs['action'] == 'DELETE') { |
$this->delete(); |
return; |
} |
if (count($pairs) != 0) { |
if ($this->uid) { // get a resource element |
$resource_file = 'services/'.ucfirst($this->resource).'.php'; |
$resource_class = ucfirst($this->resource); |
if (file_exists($resource_file)) { |
include_once $resource_file; |
if (class_exists($resource_class)) { |
$service = new $resource_class($this->config); |
if (method_exists($service,'updateElement')) { // Update element |
// TODO : a voir le retour ... |
if ($service->updateElement($this->uid, $pairs)) { |
$this->created(); |
} |
} |
} |
} |
} else { // get all elements of a ressource |
$this->add($pairs); |
} |
} else { |
$this->lengthRequired(); |
} |
} |
} |
private function delete() { |
$resource_file = 'services/'.ucfirst($this->resource).'.php'; |
$resource_class = ucfirst($this->resource); |
if (file_exists($resource_file)) { |
include_once $resource_file; |
if (class_exists($resource_class)) { |
$service = new $resource_class($this->config); |
if ($this->uid) { // get a resource element |
if (method_exists($service, 'deleteElement')) { // Delete element |
if ($service->deleteElement($this->uid)) { |
$this->noContent(); |
} |
} |
} |
} |
} |
} |
private function add($pairs = null) { |
if (is_null($pairs)) { |
$pairs = array(); |
// Récupération des paramètres passés dans le contenu de la requête HTTP (= POST) |
// FIXME : vérifier que l'on récupère bien les données passées par PUT |
if ($this->requestData) { |
$pairs = $this->parseRequestData(); |
} |
} |
if (count($pairs) != 0) { |
$resource_file = 'services/'.ucfirst($this->resource).'.php'; |
$resource_class = ucfirst($this->resource); |
if (file_exists($resource_file)) { |
include_once $resource_file; |
if (class_exists($resource_class)) { |
$service = new $resource_class($this->config); |
if (method_exists($service,'createElement')) { // Create a new element |
if ($service->createElement($pairs)) { |
$this->created(); |
} |
} |
} |
} |
} else { |
$this->lengthRequired(); |
} |
} |
/** |
* Parse the HTTP request data. |
* @return str[] Array of name value pairs |
*/ |
private function parseRequestData() { |
$values = array(); |
$pairs = explode('&', $this->requestData); |
foreach ($pairs as $pair) { |
$parts = explode('=', $pair); |
if (isset($parts[0]) && isset($parts[1])) { |
$parts[1] = rtrim(urldecode($parts[1])); |
$values[$parts[0]] = $parts[1]; |
} |
} |
return $values; |
} |
/** |
* Send a HTTP 201 response header. |
*/ |
private function created($url = FALSE) { |
header('HTTP/1.0 201 Created'); |
if ($url) { |
header('Location: '.$url); |
} |
} |
/** |
* Send a HTTP 204 response header. |
*/ |
private function noContent() { |
header('HTTP/1.0 204 No Content'); |
} |
/** |
* Send a HTTP 400 response header. |
*/ |
private function badRequest() { |
header('HTTP/1.0 400 Bad Request'); |
} |
/** |
* Send a HTTP 401 response header. |
*/ |
private function unauthorized($realm = 'JRest') { |
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) { |
header('WWW-Authenticate: Basic realm="'.$realm.'"'); |
} |
header('HTTP/1.0 401 Unauthorized'); |
} |
/** |
* Send a HTTP 404 response header. |
*/ |
private function notFound() { |
header('HTTP/1.0 404 Not Found'); |
} |
/** |
* Send a HTTP 405 response header. |
*/ |
private function methodNotAllowed($allowed = 'GET, HEAD') { |
header('HTTP/1.0 405 Method Not Allowed'); |
header('Allow: '.$allowed); |
} |
/** |
* Send a HTTP 406 response header. |
*/ |
private function notAcceptable() { |
header('HTTP/1.0 406 Not Acceptable'); |
echo join(', ', array_keys($this->config['renderers'])); |
} |
/** |
* Send a HTTP 411 response header. |
*/ |
private function lengthRequired() { |
header('HTTP/1.0 411 Length Required'); |
} |
/** |
* Send a HTTP 500 response header. |
*/ |
private function internalServerError() { |
header('HTTP/1.0 500 Internal Server Error'); |
} |
} |
?> |
/branches/v1.6-croc/jrest/cli.php |
---|
New file |
0,0 → 1,82 |
<?php |
/** |
* Script principal d'appel aux script de jrest par ligne de commande. |
* Pour le moment ne supporte pas correctement les méthodes ayant des paramètres. |
*/ |
/** |
* 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) { |
if (class_exists($classe)) { |
return null; |
} |
$chemins = array('', 'scripts/', 'lib/'); |
foreach ($chemins as $chemin) { |
$chemin = $chemin.$classe.'.php'; |
if (file_exists($chemin)) { |
require_once $chemin; |
} |
} |
} |
/** |
* Configure PHP en fonction des paramètres du fichier de config. |
* @param array $config le tableau de paramètres extraits du fichier ini. |
*/ |
function parametrer($config) { |
// Réglages de PHP |
setlocale(LC_ALL, $config['settings']['locale']); |
date_default_timezone_set($config['settings']['fuseauHoraire']); |
} |
try { |
if (php_sapi_name() == 'cli') { |
if ($_SERVER['argc'] < 2){ |
$message = "Erreur: vous n'avez pas indiqué le nom du script à appeler."; |
throw new Exception($message, E_USER_ERROR); |
} |
// suppression du premier paramètre qui est le nom de ce fichier |
array_shift($argv); |
if ($_SERVER['argc'] == 0){ |
$message = "Erreur: vous n'avez pas indiqué le nom du script à lancer"; |
throw new Exception($message, E_USER_ERROR); |
} |
// récupération du nom du script à lancer |
$nomScript = array_shift($argv); |
$params = $argv; |
$_SERVER['SERVER_NAME'] = 'localhost'; |
$config = parse_ini_file('jrest.ini.php', TRUE); |
parametrer($config); |
$conteneur = new Conteneur($config); |
$script = new $nomScript($conteneur); |
if (!is_callable(array($script, 'executer'))) { |
$message = "Erreur: la méthode 'executer' du script '$nomScript' n'existe pas ou n'est pas accessible"; |
throw new Exception($message, E_USER_ERROR); |
} |
$script->executer($params); |
} else { |
$message = "Erreur: ce fichier est destiné a être appelé en ligne de commande."; |
throw new Exception($message, E_USER_ERROR); |
} |
} catch (Exception $e) { |
$tps = date('Y-m-j H:i:s'); |
$message = $e->getMessage(); |
$code = $e->getCode(); |
echo "$tps - $code : $message\n"; |
} |
exit(0); |
?> |
/branches/v1.6-croc/jrest/index.php |
---|
New file |
0,0 → 1,26 |
<?php |
/** |
* 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) { |
if (class_exists($classe)) { |
return null; |
} |
$chemins = array('', 'services/', 'lib/'); |
foreach ($chemins as $chemin) { |
$chemin = $chemin.$classe.'.php'; |
if (file_exists($chemin)) { |
require_once $chemin; |
} |
} |
} |
$jRest = new JRest(); |
$jRest->exec(); |
?> |
/branches/v1.6-croc/jrest/. |
---|
New file |
Property changes: |
Added: svn:ignore |
+lib |
+services_li |
+util |
+.directory |
+.htaccess |
+.htaccess.defaut |
+.project |
+dump.txt |
+index.php |
+jrest.ini.php |
+jrest.ini.php.defaut |
+JRest.php |
+tagsbdd.txt |
+.buildpath |
+.settings |