Recherche sur le blog

jeudi 28 avril 2016

[WD21] Envoyer un email (II)

Nous avions vu il y a presque un an comment envoyer un email à l'aide de Windev. Cette fois nous allons utiliser les structures mises à notre disposition pour faciliter la programmation. C'est surtout au niveau de la connexion qu'il va y avoir du changement.

Connexion

Nous allons utiliser une structure de type EmailSessionSMTP. On va alors passer toutes les options à l'aide des différentes propriétés, puis appeler la fonction EmailOuvreSession() en passant cette unique variable.
MaSession est un EmailSessionSMTP
MaSession..AdresseServeur = GP_Param_s_SMTPServer
MaSession..Port = GP_Param_i_SMTPPort
MaSession..Nom  = GP_Param_s_SMTPUsername
MaSession..MotDePasse = GP_Param_s_SMTPPassword
MaSession..Option = emailOptionSécuriséTLS
bOpenSessMail = EmailOuvreSession(MaSession)
Il faudra ensuite tester le booléen pour voir si la session est ouverte.

Préparer le message

Pour le coup, rien ne change. On construit le message à l'aide d'une variable de type Email.
MonMessage est un Email
MonMessage..AdresseExpéditeur = GP_Param_s_SMTPExpe
MonMessage..Expediteur  = "Nom <" + GP_Param_s_SMTPExpe + ">"
MonMessage..Sujet = "Reporting du 28/4/2016"
MonMessage..Message = "Contenu du message au format brut"
Il faut bien entendu spécifier les destinataires (à, Cc, Cci) :
Ajoute(MonMessage..Destinataire,sDesti)
Ajoute(MonMessage..Cc,GP_Param_s_SMTPCopyTo)
Ajoute(MonMessage..Cci,GP_Param_s_SMTPCopyTo2)
Ou une pièce jointe (par exemple un fichier PDF) :
monAttache..Nom=fExtraitChemin(sFile,fFichier+fExtension)
monAttache..Contenu=fChargeTexte(sFile)
monAttache..ContentType="application/pdf"
monAttache..ContentDescription="PDF Document"
Ajoute(MonMessage..Attache, monAttache)
Une fois que c'est fait, on peut envoyer...

Envoyer

Notre message est prêt : c'est parti ! Nous allons maintenant l'envoyer et puis fermer la session précédemment ouverte (voir plus haut). Nous allons utiliser la fonction EmailEnvoieMessage(). 2 paramètres doivent être passés en entrée : la structure contenant les infos de la session, et celle contenant les informations du message.
SI PAS EmailEnvoieMessage(MaSession,MonMessage) ALORS
 Erreur(ErreurInfo(errMessage))
SINON
 Utility.displayGreenToast("Email envoyé")
FIN
Ensuite, fermer la session...
EmailFermeSession(MaSession)
Et voilà ;-)

mardi 26 avril 2016

[WB21] AWP et contextes

J'ai récemment eu l'opportunité de suivre deux formations pour apprendre à utiliser Webdev. Il s'agit du logiciel développé par PC SOFT qui permet de réaliser des sites internet assez rapidement.

Lorsqu'on crée un site dynamique, le moteur WD210AWP.EXE va automatiquement instancier les contextes et la session de l'utilisateur. L'avantage est que toutes les variables et les connexions à la base de données sont persistantes tout au long de la session. Cependant, si la session est fermée, il faut impérativement en relancer une autre à l'aide de la fonction SiteDynamiqueAffiche() ou re-valider l'URL dans la barre d'adresses, sinon une erreur s'affiche lors des appels de page. Un comportement que l'on peut trouver rébarbatif.

Dans ce mode, il n'est pas possible de "structurer" le site ; toutes les pages sont appelées comme si elles se trouvaient à la racine du répertoire virtuel. De plus le référencement est impossible. On l'utilisera plus pour réaliser une application de type intranet.

L'autre solution consiste à utiliser les pages AWP. Ce sont des pages totalement indépendantes, un peu à l'image des pages PHP au final, et les contextes doivent être instanciés par le développeur. Cela nécessite bien sûr plus de manipulations mais cela entraine une grande liberté dans la gestion des sessions et des connexions utilisateur. Par exemple, cela vous permet de gérer votre espace membres sans avoir à utiliser le Groupware Utilisateur Intégré

Les autres avantages sont les suivants :
  • La page existe physiquement en tant que fichier, pas de timeout lors de son appel.
  • Il n'y a pas de ressources consommée en continu sur le serveur.
  • Le référencement est possible. 
  • Une page peut être mise à jour sans que tout le site ne doive être déployé à nouveau.
Bien sûr, comme ces pages ne permettent pas d'avoir une connexion permanente à la base de données, le positionnement dans les tables est perdu lors des appels suivants. 

Variables globales

On va déclarer dans l'Initialisation du projet, des variables globales qui seront réutilisées partout sur notre site (par exemple, un identifiant de session que l'on générera, l'ID de l'utilisateur connecté, etc).

Configuration du contexte

Il faut alors demander à configurer le contexte ; cela se fait dans l'Initialisation du projet à nouveau (après connexion au site => permet d'éviter les soucis rencontrés avec les sessions prélancées). 
ConfigureContexteAWP(ctxDisque,ctxIDCookieURL)
On demande à Webdev d'utiliser le contexte sur disque plutôt que par cookie. On va alors spécifier qu'on veut transmettre l'identifiant prioritairement par l'intermédiaire du cookie puis de l'URL. Nous n'utiliserons cependant pas cet identifiant.

On va ensuite indiquer à Webdev les variables à déclarer dans le contexte pour qu'elles soient réutilisées à chaque fois lors d'un changement de page. La fonction DéclareContexteAWP(var) doit être utilisée dans l'Initialisation du projet s'il s'agit de variables globales au projet, ou dans les pages s'il s'agit de variables globales aux pages. En règle général il faut donc l'utiliser là où on déclare et instance ces variables.
DéclareContexteAWP(gsSessionId)
DéclareContexteAWP(gsUsername)
DéclareContexteAWP(gsKey)
DéclareContexteAWP(gsIP)
DéclareContexteAWP(gdhSessionDt)
Après, toujours dans l'initialisation, on peut imaginer la connexion à notre base de données.
// Initialiser la connexion.
gcMaConnexion..Provider  = hAccèsHFClientServeur
gcMaConnexion..BaseDeDonnées  = "MonSiteAwp"
gcMaConnexion..Utilisateur  = "admin"
gcMaConnexion..MotDePasse  = "password"
gcMaConnexion..Serveur   = "MONPC"
SI HOuvreConnexion(gcMaConnexion) ALORS
  gbDbConn = True
  SI HChangeConnexion("*",gcMaConnexion) ALORS
    gproc_initSession()
  SINON
    ...
  FIN
FIN
Une fois la connexion établie on a donc demandé à ouvrir la session. Dans cette fonction nous allons regarder à chaque fois si l'identifiant de session personnalisé n'est pas déjà défini (gsSessionId). Si celui-ci est vide, le contexte a été détruit (session fermée), sinon la session est considérée comme toujours active.
  • Si la variable est vide, on recrée tout simplement un identifiant de session et on écrit dans la base de données.  Celui-ci doit bien sûr être unique.
  • Si ce n'est pas vide, on vérifie les variables utiles (IP, utilisateur, date de création) et on réagit en conséquence - soit suppression dans la base de données puis recréation, soit modification de la date de dernière action.
Les variables pour lesquelles on a déclaré le contexte peuvent être utilisées dans toutes les pages.

Quelques notes à propos de Webdev

En mode AWP on s'affranchit du surplus de Javascript dans les menus, dans les liens, ce qui peut assurer une meilleure compatibilité si l'utilisateur désactive l'exécution des scripts dans son navigateur.

Bien que l'outil soit très pratique dans l'ensemble, et que le résultat soit plutôt convaincant, on peut être dubitatif quant au code généré. En effet, le moteur crée de nombreuses tables en guise de layout, ce qui n'est pas recommandé en HTML5. On retrouve également dans ces éléments "table" de nombreux attributs "style" (notamment avec la hauteur définie à 100%). Tout cela fait penser à un code un peu... historique.

Une option dans la description du projet permet le positionnement par balise "div". Celle-ci ne semble être prise en compte que pour les pages sans zone extensible. Dans mon projet l'activation de cette option n'a eu aucun effet, ce qui signifierait que mon layout actuel ne rentre pas dans les conditions. On pourrait aussi s'interroger sur la mention "déconseillé" placée juste à côté de la case à cocher. On peut supposer que cela entraine des problèmes lors de la disposition des différents éléments.

mercredi 6 avril 2016

[OWA] Impossible de traiter votre demande

Si vous obtenez plusieurs fois l'erreur "Impossible de traiter votre demande" sur votre boite mail lorsque vous tentez de l'utiliser via OWA, suivi d'un message d'erreur "Une erreur est survenue lorsque vous tentiez d'utiliser votre boite mail", pensez à vérifier les éléments suivants : 
  • Si votre serveur n'utilise pas SSL, ouvrez le dossier C:\Program Files\Microsoft\Exchange Server\V14\ClientAccess\owa, ensuite éditez à l'aide du bloc-notes le fichier "Web.Config". A la ligne 41 plus ou moins vous trouverez un élément de configuration pour les cookies. Modifiez le paramètre "requireSSL" à false, puis relancez l'application OWA ou IIS (source : Microsoft Community).
<httpCookies httpOnlyCookies="false" 
  requireSSL="false" domain="" />
  • Si cela ne fonctionne toujours pas, ouvrez l'éditeur de registre sur le serveur Exchange et effectuez les manipulations suivantes :
    • Naviguez jusqu'à la clé HKLM\SYSTEM\CurrentControlSet\services\MSExchangeIS\ParametersSystem
    • Créez un paramètre de type DWORD (32 bits) nommé "Maximum Allowed Service Sessions Per User
    • Définissez la valeur 24 ou 32 en décimal. 
    • Ce paramètre peut éventuellement aider à résoudre l'événement #9646.
    • Plus la valeur est élevée, plus il y a de risques que les performances se dégradent (voir Documentation Technet). 
  • Vérifiez également dans la configuration IIS que les redirections HTTP sont désactivées au niveau du répertoire virtuel "owa".