Initial commit

Functional, without SSO
This commit is contained in:
Jimmy Monin
2016-09-18 11:03:26 +02:00
commit 57708e3169
253 changed files with 30787 additions and 0 deletions

View File

@ -0,0 +1,6 @@
<?php
if ($auth->getUsername() != "admin") {
header("HTTP/1.1 403 Forbidden");
exit;
}

View File

@ -0,0 +1,21 @@
<?php
$user = new \App\User\User();
$errors = array();
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (!isset($_POST["username"]) || !trim($_POST["username"])) {
$errors["username"] = "Veuillez indiquer un nom d'utilisateur.";
} else {
$user->setUsername(trim($_POST["username"]));
}
if (empty($_POST["password"])) {
$errors["password"] = "Veuillez indiquer un mot de passe.";
} elseif (empty($_POST["password"]) || $_POST["password"] != $_POST["confirmPassword"]) {
$errors["confirmPassword"] = "Les deux mots de passe ne correspondent pas.";
}
if (empty($errors)) {
$user->setPassword(sha1($_POST["password"]));
$userStorage->save($user);
header("LOCATION: ?mod=admin&a=users");
exit;
}
}

View File

@ -0,0 +1,15 @@
<?php
if (!isset($_GET["username"]) || !$user = $userStorage->fetchByUsername($_GET["username"])) {
header("LOCATION: ?mod=admin&a=users");
exit;
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$userStorage->delete($user);
$configAlert = DOCUMENT_ROOT."/var/configs/".$user->getUsername().".csv";
if (is_file($configAlert)) {
unlink($configAlert);
}
header("LOCATION: ?mod=admin&a=users");
exit;
}

View File

@ -0,0 +1,12 @@
<?php
$filename = DOCUMENT_ROOT."/var/log/info.log";
$lines = array();
if (is_file($filename)) {
$lines = file($filename);
if (count($lines) > 200) {
$lines = array_slice($lines, count($lines)-200);
}
}

View File

@ -0,0 +1,76 @@
<?php
$errors = array();
$options = array(
"host" => "", "port" => "",
"username" => "", "password" => "",
"secure" => "",
"from" => "",
"testMail" => ""
);
if ($config->hasSection("mailer")) {
if ($smtp = $config->get("mailer", "smtp", array())) {
$options = array_merge($options, $smtp);
}
if ($from = $config->get("mailer", "from", null)) {
$options["from"] = $from;
}
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$options = array_merge($options, array_map("trim", $_POST));
if (isset($_POST["testSMTP"])) {
require_once "PHPMailer/class.phpmailer.php";
$mailer = new PHPMailer($exceptions=true);
$mailer->setLanguage("fr", DOCUMENT_ROOT."/lib/PHPMailer/language/");
$mailer->CharSet = "utf-8";
if (!empty($options["host"])) {
$mailer->Host = $options["host"];
$mailer->isSMTP();
}
if (!empty($options["port"])) {
$mailer->Port = $options["port"];
$mailer->isSMTP();
}
if (!empty($options["username"])) {
$mailer->SMTPAuth = true;
$mailer->Username = $options["username"];
}
if (!empty($options["password"])) {
$mailer->SMTPAuth = true;
$mailer->Password = $options["password"];
}
if (!empty($options["secure"])) {
$mailer->SMTPSecure = $options["secure"];
}
if (!empty($options["from"])) {
$mailer->Sender = $options["from"];
$mailer->From = $options["from"];
}
if (empty($_POST["testMail"])) {
$errors["testMail"] = "Indiquez une adresse e-mail pour l'envoi du test.";
} else {
$mailer->clearAddresses();
$mailer->addAddress($_POST["testMail"]);
if ($options["from"]) {
$mailer->FromName = $options["from"];
}
$mailer->Subject = "Test d'envoi de mail";
$mailer->Body = "Bravo.\nVotre configuration mail est validée.";
try {
$mailer->send();
$testSended = true;
} catch (phpmailerException $e) {
$testError = $e->getMessage();
}
}
} else {
$config->set("mailer", "smtp", array(
"host" => $options["host"], "port" => $options["port"],
"username" => $options["username"], "password" => $options["password"],
"secure" => $options["secure"]
));
$config->set("mailer", "from", $options["from"]);
$config->save();
header("LOCATION: ?mod=admin&a=mail");
exit;
}
}

View File

@ -0,0 +1,46 @@
<?php
$errors = array();
$options = array(
"proxy_ip" => $config->get("proxy", "ip", ""),
"proxy_port" => $config->get("proxy", "port", ""),
"proxy_user" => $config->get("proxy", "user", ""),
"proxy_password" => $config->get("proxy", "password", "")
);
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$options = array_merge(array(
"proxy_ip" => "",
"proxy_port" => "",
"proxy_user" => ""
), array_map("trim", $_POST));
if (isset($options["proxy_ip"])) {
$options["proxy_ip"] = $options["proxy_ip"];
if (isset($options["proxy_port"])) {
$options["proxy_port"] = $options["proxy_port"];
}
}
if (isset($_POST["testProxy"])) {
$client->setProxyIp($options["proxy_ip"])
->setProxyPort($options["proxy_port"])
->setProxyUser($options["proxy_user"]);
if (!empty($options["proxy_password"])) {
$client->setProxyPassword($options["proxy_password"]);
}
$errors["test"] = array();
if (false === $client->request("http://portail.free.fr")) {
$errors["test"]["site"] = $client->getError();
}
if (false === $client->request("https://www.leboncoin.fr")) {
$errors["test"]["lbc"] = $client->getError();
}
} else {
$config->set("proxy", "ip", $options["proxy_ip"]);
$config->set("proxy", "port", $options["proxy_port"]);
$config->set("proxy", "user", $options["proxy_user"]);
if (!empty($options["proxy_password"])) {
$config->set("proxy", "password", $options["proxy_password"]);
}
$config->save();
header("LOCATION: ?mod=admin&a=proxy");
exit;
}
}

View File

@ -0,0 +1,102 @@
<?php
$storageType = $config->get("storage", "type", "files");
$currentStorage = array(
"type" => $config->get("storage", "type", "files"),
"options" => $config->get("storage", "options", array())
);
$errors = array();
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (!isset($_POST["type"]) || !trim($_POST["type"])
|| !in_array($_POST["type"], array("files", "db"))) {
$errors["type"] = "Type de stockage invalide.";
}
$currentStorage = array(
"type" => isset($_POST["type"]) ? $_POST["type"] : $currentStorage["type"],
"options" => array_merge($currentStorage["options"],
isset($_POST["options"]) && is_array($_POST["options"]) ? $_POST["options"] : array())
);
if ($_POST["type"] == "db") {
if (!isset($_POST["options"]["password"])) {
$_POST["options"]["password"] = "";
}
if (empty($_POST["options"]["host"])) {
$errors["host"] = "Nom d'hôte invalide.";
}
if (empty($_POST["options"]["user"])) {
$errors["user"] = "Spécifiez un nom d'utilisateur.";
}
if (empty($_POST["options"]["dbname"])) {
$errors["dbname"] = "Spécifiez une base de données.";
}
if (!empty($_POST["options"]["user"]) && !empty($_POST["options"]["dbname"])) {
// test de connexion
$dbConnection = new mysqli(
$_POST["options"]["host"], $_POST["options"]["user"],
$_POST["options"]["password"], $_POST["options"]["dbname"]);
if ($dbConnection->connect_error) {
$errors["host"] = "Connexion impossible à la base de données.";
}
}
}
if (empty($errors)) {
if ($_POST["type"] == "db") {
$config->set("storage", "type", "db");
$config->set("storage", "options", array(
"host" => $_POST["options"]["host"],
"user" => $_POST["options"]["user"],
"password" => $_POST["options"]["password"],
"dbname" => $_POST["options"]["dbname"],
));
} else {
$config->set("storage", "type", "files");
}
$config->save();
if ($_POST["type"] == "db" && !empty($_POST["importtodb"])) {
// installation de la base
require DOCUMENT_ROOT."/others/install/schema.php";
$userStorageDb = new \App\Storage\Db\User($dbConnection);
$users = array();
$usersDb = $userStorageDb->fetchAll(); // utilisateurs actuellement en BDD
foreach ($usersDb AS $user) {
$users[$user->getUsername()] = $user;
}
unset($usersDb);
$userStorageFiles = new \App\Storage\File\User(DOCUMENT_ROOT."/var/users.db");
$usersFiles = $userStorageFiles->fetchAll();
foreach ($usersFiles AS $user) {
if (!isset($users[$user->getUsername()])) {
$userStorageDb->save($user);
}
}
$users = $userStorageDb->fetchAll();
foreach ($users AS $user) {
$file = DOCUMENT_ROOT."/var/configs/".$user->getUsername().".csv";
if (!is_file($file)) {
continue;
}
$storageFiles = new \App\Storage\File\Alert($file);
$storageDb = new \App\Storage\Db\Alert($userStorageDb->getDbConnection(), $user);
$alerts = $storageFiles->fetchAll();
foreach ($alerts AS $alert) {
$storageDb->save($alert, $forceinsert=true);
}
}
}
header("LOCATION: ?mod=admin&a=storage&success=1");
exit;
}
}

View File

@ -0,0 +1,76 @@
<?php
$updater = new \App\Updater();
if ($url = $config->get("general", "url_version", "")) {
$updater->setUrlVersion($url);
}
if ($url = $config->get("general", "url_archive", "")) {
$updater->setUrlArchive($url);
}
if (isset($_POST["checkVersion"])) {
unset($_SESSION["lbcLastVersion"], $_SESSION["lbcLastVersionTime"]);
header("LOCATION: ?mod=admin&a=upgrade");
exit;
}
if ($_SERVER["REQUEST_METHOD"] == "POST" || empty($_SESSION["lbcLastVersion"]) || empty($_SESSION["lbcLastVersionTime"])) {
try {
$_SESSION["lbcLastVersion"] = $updater->getLastVersion();
$_SESSION["lbcLastVersionTime"] = time();
} catch (Exception $e) {
}
}
$lastVersion = "";
if (!empty($_SESSION["lbcLastVersion"])) {
$lastVersion = $_SESSION["lbcLastVersion"];
}
$errors = array();
$allow_update = true;
if (!is_writable(DOCUMENT_ROOT."/version.php")) {
$allow_update = false;
$errors[] = "Le fichier version.php est en lecture seule, la mise à jour automatique ne peut être effectuée.".
"<br />Vérifiez que tous les fichiers soient accéssibles en écriture (pas seulement le fichier version.php).";
} elseif (is_file(DOCUMENT_ROOT."/var/.lock")) {
$allow_update = false;
$errors[] = "Une vérification de nouvelle annonce est en cours, veuillez attendre la fin de celle-ci pour mettre à jour.";
}
$currentVersion = $config->get("general", "version");
$upgradeStarted = version_compare($currentVersion, APPLICATION_VERSION, "<");
$upgradeAvailable = version_compare($currentVersion, $lastVersion, "<");
if ($upgradeStarted && !empty($_POST["upgrade"])) {
$updater->update($currentVersion, $lastVersion);
// mise à jour du numéro de version dans la config.
$config->set("general", "version", $lastVersion);
$config->save();
header("LOCATION: ?mod=admin&a=upgrade");
exit;
} elseif ($allow_update && $upgradeAvailable && !empty($_POST["upgrade"])) {
file_put_contents(DOCUMENT_ROOT."/var/.lock_update", time());
try {
$updater->installFiles($lastVersion);
} catch (Exception $e) {
$errors[] = $e->getMessage();
}
$version = require DOCUMENT_ROOT."/version.php";
if ($version != $lastVersion) {
$errors[] = "La mise à jour semble avoir échouée.";
} else {
$updater->update($currentVersion, $lastVersion);
// mise à jour du numéro de version dans la config.
$config->set("general", "version", $lastVersion);
$config->save();
}
unlink(DOCUMENT_ROOT."/var/.lock_update");
if (!$errors) {
header("LOCATION: ?mod=admin&a=upgrade");
exit;
}
}

View File

@ -0,0 +1,2 @@
<?php
$users = $userStorage->fetchAll();

View File

@ -0,0 +1,30 @@
<form action="" method="post" autocomplete="off">
<h2>Ajouter un utilisateur</h2>
<dl>
<dt><label for="username">Nom d'utilisateur</label></dt>
<dd>
<input type="text" id="username" name="username" value="<?php
echo htmlspecialchars($user->getUsername());
?>" />
<?php if (isset($errors["username"])) : ?>
<p class="error"><?php echo $errors["username"]; ?></p>
<?php endif; ?>
</dd>
<dt><label for="password">Mot de passe</label></dt>
<dd>
<input type="password" id="password" name="password" />
<?php if (isset($errors["password"])) : ?>
<p class="error"><?php echo $errors["password"]; ?></p>
<?php endif; ?>
</dd>
<dt><label for="confirmPassword">Confirmez le mot de passe</label></dt>
<dd>
<input type="password" id="confirmPassword" name="confirmPassword" />
<?php if (isset($errors["confirmPassword"])) : ?>
<p class="error"><?php echo $errors["confirmPassword"]; ?></p>
<?php endif; ?>
</dd>
</dl>
<p><input type="submit" value="Enregistrer" />
| <a href="?mod=admin&amp;a=users">annuler</a></p>
</form>

View File

@ -0,0 +1,6 @@
<form action="" method="post">
<p>
Supprimer l'utilisateur "<?php echo htmlspecialchars($user->getUsername()); ?>" ?<br />
<input type="submit" value="Oui" /> | <a href="?mod=admin&amp;a=users">non</a>
</p>
</form>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<title>Alerte mail pour Leboncoin.fr</title>
<meta charset="utf-8">
<meta name="robots" content="none">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="static/styles.css?v=<?php echo APPLICATION_VERSION; ?>" />
</head>
<body>
<?php if ($userAuthed) : ?>
<header>
<h1><a href="./">Système d'alerte Leboncoin</a></h1>
<ul class="topmenu">
<li<?php echo $action === "users"?' class="active"':''; ?>><a href="?mod=admin&amp;a=users">Utilisateurs</a></li>
<li<?php echo $action === "storage"?' class="active"':''; ?>><a href="?mod=admin&amp;a=storage">Stockage</a></li>
<li<?php echo $action === "proxy"?' class="active"':''; ?>><a href="?mod=admin&amp;a=proxy">Proxy</a></li>
<li<?php echo $action === "mail"?' class="active"':''; ?>><a href="?mod=admin&amp;a=mail">Mail</a></li>
<li<?php echo $action === "upgrade"?' class="active"':''; ?>><a href="?mod=admin&amp;a=upgrade">Mise à jour</a></li>
<li<?php echo $action === "log"?' class="active"':''; ?>><a href="?mod=admin&amp;a=log">Log</a></li>
<li style="float: right;"><a href="?a=logout">Déconnexion <span>(<?php echo htmlspecialchars($userAuthed->getUsername()); ?>)</span></a></li>
</ul>
</header>
<?php endif; ?>
<div class="content">
<?php echo $content; ?>
</div>
<?php if ($userAuthed) : ?>
<footer>
<?php if ($userAuthed->getUsername() == "admin") : ?>
<a href="?mod=admin&amp;a=users" style="color: #EF0000;">Administration</a> |
<?php endif; ?>
Version <?php echo APPLICATION_VERSION; ?>
| <a href="https://github.com/Blount/LBCAlerte/issues">Rapporter un bug</a>
</footer>
<?php endif; ?>
</body>
</html>

View File

@ -0,0 +1,19 @@
<h2>Fichier jounal</h2>
<p>Voici les dernières lignes du fichier log: <?php
echo htmlspecialchars($filename, null, "UTF-8"); ?></p>
<ul id="lastlog" class="lastlog">
<?php if (0 == count($lines)) : ?>
<li>Rien à signaler.</li>
<?php else: ?>
<?php foreach ($lines AS $line) : ?>
<li<?php
if (strpos($line, "ERROR")) {
echo ' class="lastlog-error"';
}
?>><?php echo htmlspecialchars($line, null, "UTF-8"); ?></li>
<?php endforeach; ?>
<?php endif; ?>
</ul>
<script type="text/javascript">
document.getElementById("lastlog").scrollTop = 50000;
</script>

View File

@ -0,0 +1,84 @@
<?php if (empty($errors) && isset($_POST["testSMTP"])) : ?>
<div style="width: 680px; border: 1px solid #666666; margin-bottom: 10px; padding: 10px;">
<h2>Test d'envoi de mail</h2>
<?php if (isset($testSended)) : ?>
<p style="font-weight: bold; color: #333399;">Vous devriez recevoir un mail de test à l'adresse suivante : <?php
echo htmlspecialchars($options["testMail"]);
?></p>
<?php elseif (isset($testError)): ?>
<p style="font-weight: bold; color: #993333;">Erreur de l'envoi du mail : <?php
echo htmlspecialchars($testError);
?></p>
<?php endif; ?>
</div>
<?php endif; ?>
<form action="" method="post" autocomplete="off">
<h2>Configuration de l'envoi des mails</h2>
<dl>
<dt style="clear: both;"><label for="from">Adresse e-mail à indiquer comme expéditeur</label></dt>
<dd>
<input type="text" id="from" name="from" value="<?php
echo htmlspecialchars($options["from"]);
?>" size="40" />
</dd>
<dt style="margin-bottom: 5px;"><label>Serveur SMTP externe</label></dt>
<dd style="float: left;">
&nbsp;<label for="host">Hôte / IP :</label><br />
<input type="text" id="host" name="host" value="<?php
echo htmlspecialchars($options["host"]);
?>" />
</dd>
<dd style="float: left; margin-left: 10px;">
&nbsp;<label for="port">Port :</label><br />
<input type="text" id="port" name="port" value="<?php
echo htmlspecialchars($options["port"]);
?>" size="10" />
<?php if (isset($errors["server"])) : ?>
<p class="error"><?php echo $errors["server"]; ?></p>
<?php endif; ?>
</dd>
<dt style="clear: both; margin-bottom: 5px;">
<label>Utilisateur et mot de passe SMTP si une identification est nécessaire</label>
</dt>
<dd style="float: left;">
&nbsp;<label for="username">Utilisateur :</label><br />
<input type="text" id="username" name="username" value="<?php
echo htmlspecialchars($options["username"]);
?>" />
</dd>
<dd style="float: left; margin-left: 10px;">
&nbsp;<label for="password">Mot de passe :</label><br />
<input type="password" id="password" name="password" value="<?php
echo htmlspecialchars($options["password"]);
?>" />
<?php if (isset($errors["password"])) : ?>
<p class="error"><?php echo $errors["password"]; ?></p>
<?php endif; ?>
</dd>
<dt style="clear: both;"><label for="secure">Sécurité de la connexion</label></dt>
<dd>
<select name="secure">
<option value=""<?php echo empty($options["secure"])?' selected="selected"':''; ?>>Aucune</option>
<option value="tls"<?php echo $options["secure"] == "tls"?' selected="selected"':''; ?>>TLS</option>
<option value="ssl"<?php echo $options["secure"] == "ssl"?' selected="selected"':''; ?>>SSL</option>
</select>
</dd>
<dt style="clear: both;">
<label for="testMail">Pour tester l'envoi des mails, entrez une adresse et cliquez sur "Tester"</label>
</dt>
<dd>
<input type="text" id="testMail" name="testMail" value="<?php
echo htmlspecialchars($options["testMail"]);
?>" size="40" />
<?php if (isset($errors["testMail"])) : ?>
<p class="error"><?php echo $errors["testMail"]; ?></p>
<?php endif; ?>
<p class="description">Un mail de test sera envoyé à cette adresse</p>
</dd>
</dl>
<p>
<input type="submit" value="Enregistrer" />
<input type="submit" name="testSMTP" value="Tester" />
</p>
</form>

View File

@ -0,0 +1,62 @@
<?php if (isset($_POST["testProxy"])) : ?>
<div style="width: 680px; border: 1px solid #666666; margin-bottom: 10px; padding: 10px;">
<h2>Test de connexion</h2>
<ul>
<?php if (!$client->hasProxy()) : ?>
<li>aucun proxy configuré.</li>
<?php else: ?>
<li>utilisation d'un proxy pour la connexion.</li>
<?php endif; ?>
<li>Connexion à <a href="http://portail.free.fr">portail.free.fr</a> :
<?php if (isset($errors["test"]["site"])) : ?>
<span style="color: red;">échec</span>
(erreur: <?php echo htmlspecialchars($errors["test"]["site"]); ?>)
<?php else: ?>
<span style="color: #009900;">réussi</span>
<?php endif; ?>
</li>
<li>Connexion à <a href="https://www.leboncoin.fr">Leboncoin</a> :
<?php if (isset($errors["test"]["lbc"])) : ?>
<span style="color: red;">échec</span>
(erreur: <?php echo htmlspecialchars($errors["test"]["lbc"]); ?>)
<?php else: ?>
<span style="color: #009900;">réussi</span>
<?php endif; ?>
</li>
</ul>
</div>
<?php endif; ?>
<h2>Configuration d'un serveur proxy</h2>
<p>
Vous pouvez configurer ici un proxy de connexion qui sera
utilisé pour se connecter à Leboncoin.
</p>
<form action="" method="post" autocomplete="off">
<h2>Paramètres du proxy</h2>
<dl>
<dt><label for="proxy_ip">Adresse du proxy</label></dt>
<dd><input type="text" id="proxy_ip" name="proxy_ip" value="<?php
echo htmlspecialchars($options["proxy_ip"]);
?>" /></dd>
<dt><label for="proxy_port">Port</label></dt>
<dd><input type="text" id="proxy_port" name="proxy_port" value="<?php
echo htmlspecialchars($options["proxy_port"]);
?>" size="7" /></dd>
</dl>
<h2>Le serveur proxy requiert une identification ?</h2>
<dl>
<dt><label for="proxy_user">Utilisateur</label></dt>
<dd><input type="text" id="proxy_user" name="proxy_user" value="<?php
echo htmlspecialchars($options["proxy_user"]);
?>" />
</dd>
<dt><label for="proxy_password">Mot de passe</label></dt>
<dd><input type="password" id="proxy_password" name="proxy_password"<?php
echo !empty($options["proxy_password"])?' placeholder="Valeur masquée"':""; ?> /></dd>
</dl>
<p>
<input type="submit" value="Enregistrer" />
<input type="submit" name="testProxy" value="Tester la connexion" />
</p>
</form>

View File

@ -0,0 +1,102 @@
<?php if (isset($_GET["success"])) : ?>
<p style="color: #001FA6;"><strong>Mise à jour de la configuration effectuée.</strong></p>
<?php endif; ?>
<p>Vous pouvez choisir de stocker les données de l'application
(utilisateurs, alertes, options, etc.)
dans des fichiers ou en base de données (MySQL).</p>
<form action="?mod=admin&amp;a=storage" method="post" autocomplete="off">
<h2>Configuration du stockage des données</h2>
<dl>
<dt><label>Type de stockage :</label></dt>
<dd>
<label for="typefiles">
<input type="radio" id="typefiles" name="type" value="files"<?php
echo "files" == $currentStorage["type"] ? ' checked="checked"' : ""
?> />
fichiers
</label>
<label for="typedb" style="margin-left: 40px;">
<input type="radio" id="typedb" name="type" value="db"<?php
echo "db" == $currentStorage["type"] ? ' checked="checked"' : ""
?> />
base de données MySQL
</label>
<?php if (!empty($errors["type"])) : ?>
<p class="error"><?php echo $errors["type"]; ?></p>
<?php endif; ?>
</dd>
<dt class="storage-db-options"><label for="options-host">Adresse du serveur</label></dt>
<dd class="storage-db-options">
<input type="text" id="options-host" name="options[host]" value="<?php
echo isset($currentStorage["options"]["host"]) ? htmlspecialchars($currentStorage["options"]["host"]) : "localhost"
?>" />
<?php if (!empty($errors["host"])) : ?>
<p class="error"><?php echo $errors["host"]; ?></p>
<?php endif; ?>
</dd>
<dt class="storage-db-options"><label for="options-user">Utilisateur</label></dt>
<dd class="storage-db-options">
<input type="text" id="options-user" name="options[user]" value="<?php
echo isset($currentStorage["options"]["user"]) ? htmlspecialchars($currentStorage["options"]["user"]) : ""
?>" />
<?php if (!empty($errors["user"])) : ?>
<p class="error"><?php echo $errors["user"]; ?></p>
<?php endif; ?>
</dd>
<dt class="storage-db-options"><label for="options-password">Mot de passe</label></dt>
<dd class="storage-db-options">
<input type="password" id="options-password" name="options[password]" value="<?php
echo isset($currentStorage["options"]["password"]) ? htmlspecialchars($currentStorage["options"]["password"]) : ""
?>" />
<?php if (!empty($errors["password"])) : ?>
<p class="error"><?php echo $errors["password"]; ?></p>
<?php endif; ?>
</dd>
<dt class="storage-db-options"><label for="options-base">Nom de la base de données</label></dt>
<dd class="storage-db-options">
<input type="text" id="options-base" name="options[dbname]" value="<?php
echo isset($currentStorage["options"]["dbname"]) ? htmlspecialchars($currentStorage["options"]["dbname"]) : ""
?>" />
<?php if (!empty($errors["dbname"])) : ?>
<p class="error"><?php echo $errors["dbname"]; ?></p>
<?php endif; ?>
</dd>
<?php if (is_dir(DOCUMENT_ROOT."/var/configs") && 2 < count(scandir(DOCUMENT_ROOT."/var/configs"))) : ?>
<dt class="storage-db-options">
<label for="importtodb"><input type="checkbox" id="importtodb" name="importtodb" value="1"<?php
echo isset($_POST["importtodb"]) ? ' checked="checked"' : ""
?>" /> importer les données existantes dans la base de données.</label>
<?php if (!empty($errors["dbname"])) : ?>
<p class="error"><?php echo $errors["dbname"]; ?></p>
<?php endif; ?>
</dt>
<?php endif; ?>
</dl>
<p><input type="submit" value="Enregistrer" /></p>
</form>
<script type="text/javascript">
if (document.querySelectorAll) {
var elements = document.querySelectorAll(".storage-db-options");
var buttons = document.querySelectorAll("input[name=type]");
var fnCheck = function () {
var display = document.querySelector("input[value=db]").checked ? "block" : "none";
for (var i = 0; i < elements.length; i++) {
elements[i].style.display = display;
}
};
for (var j = 0; j < buttons.length; j++) {
buttons[j].addEventListener("change", fnCheck);
}
fnCheck();
}
</script>

View File

@ -0,0 +1,54 @@
<?php if (!empty($errors)) : ?>
<p class="error">
<?php echo implode("<br />", $errors); ?>
</p>
<br />
<?php endif; ?>
<?php if ($upgradeStarted || $upgradeAvailable) : ?>
<p>
<strong><span style="color: #EF0000;">ATTENTION :</span>
avant de lancer la mise à jour automatique,
merci d'effectuer une sauvegarde de vos données actuelles.</strong>
</p>
<?php endif; ?>
<?php if ($upgradeStarted) : ?>
<form action="" method="post">
<p>
Cliquer sur "Mettre à jour" afin de terminer la mise à jour.
</p>
<p>
<input type="hidden" name="upgrade" value="1" />
<input type="submit" value="Mettre à jour" />
</p>
</form>
<?php elseif ($upgradeAvailable) : ?>
<h2>Une mise à jour est disponible</h2>
<p>
Vous utilisez actuellement la version <strong><?php echo APPLICATION_VERSION; ?></strong>.
La version <strong><?php echo $lastVersion; ?></strong> est disponible.
</p>
<?php if ($allow_update) : ?>
<form action="" method="post">
<p>
<input type="hidden" name="upgrade" value="1" />
<input type="submit" value="Mettre à jour" />
</p>
</form>
<?php endif; ?>
<?php else : ?>
<p><strong>Vous utilisez déjà la dernière version.</strong></p>
<form action="" method="post">
<p>
Dernière vérification effectuée le <?php echo date("d/m/Y à H:i", $_SESSION["lbcLastVersionTime"]); ?>
</p>
<p>
<input type="hidden" name="checkVersion" value="1" />
<input type="submit" value="Vérifier à nouveau" />
</p>
</form>
<?php endif; ?>

View File

@ -0,0 +1,23 @@
<p><a href="?mod=admin&amp;a=add-user">Nouvel utilisateur</a></p>
<table style="width: 500px; text-align: left;">
<thead>
<tr>
<th>Nom d'utilisateur</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
<?php foreach ($users AS $user) : ?>
<tr>
<td><?php echo htmlspecialchars($user->getUsername()); ?></td>
<td>
<?php if ($user->getUsername() != "admin") : ?>
<a href="?mod=admin&amp;a=delete-user&amp;username=<?php echo urlencode($user->getUsername()); ?>">supprimer</a>
<?php else: ?>
-
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>

View File

@ -0,0 +1,25 @@
<?php
$username = "";
$errors = array();
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (!isset($_POST["username"]) || !trim($_POST["username"])) {
$errors["password"] = "Nom d'utilisateur ou mot de passe incorrecte.";
} else {
$username = $_POST["username"];
}
if (empty($errors)) {
$password = isset($_POST["password"])?$_POST["password"]:"";
$auth->setUsername($username)
->setPassword(sha1($password));
if ($auth->authenticate()) {
if ($module == "default" && $action == "login") {
$redirect = "./";
} else {
$redirect = $_SERVER["REQUEST_URI"];
}
header("LOCATION: ".$redirect);
exit;
}
$errors["password"] = "Nom d'utilisateur ou mot de passe incorrecte.";
}
}

View File

@ -0,0 +1,5 @@
<?php
$auth->clear();
header("LOCATION: ./");
exit;

View File

@ -0,0 +1,11 @@
<p>
Utilisez le menu ci-dessus pour accéder à la gestion de vos alertes mails
et des flux RSS.
</p>
<p>
Vous pouvez aussi :
</p>
<ul>
<li><a href="https://github.com/Blount/LBCAlerte/issues">rapporter des bugs</a>.</li>
<li><a href="https://alerte.ilatumi.org/forum">utiliser le forum</a> pour obtenir de l'aide.</li>
</ul>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<title>Alerte mail pour Leboncoin.fr</title>
<meta charset="utf-8">
<meta name="robots" content="none">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="static/styles.css?v=<?php echo APPLICATION_VERSION; ?>" />
</head>
<body>
<?php if ($userAuthed) : ?>
<header>
<h1><a href="./">Système d'alerte Leboncoin</a></h1>
<ul class="topmenu">
<li<?php echo $module === "default"?' class="active"':''; ?>><a href="./?"><img src="static/images/home.png" alt="" /></a></li>
<li<?php echo $module === "mail"?' class="active"':''; ?>><a href="?mod=mail">Mail / SMS</a></li>
<li<?php echo $module === "rss"?' class="active"':''; ?>><a href="?mod=rss">RSS</a></li>
<li<?php echo $module === "user"?' class="active"':''; ?>><a href="?mod=user&amp;a=settings">Paramètres</a></li>
<li><a href="https://alerte.ilatumi.org/forum">Forum</a></li>
<li style="float: right;"><a href="?a=logout">Déconnexion <span>(<?php echo htmlspecialchars($userAuthed->getUsername()); ?>)</span></a></li>
</ul>
</header>
<?php endif; ?>
<div class="content">
<?php echo $content; ?>
</div>
<?php if ($userAuthed) : ?>
<footer>
<?php if ($userAuthed->getUsername() == "admin") : ?>
<a href="?mod=admin&amp;a=users" style="color: #EF0000;">Administration</a> |
<?php endif; ?>
Version <?php echo APPLICATION_VERSION; ?>
| <a href="https://github.com/Blount/LBCAlerte/issues">Rapporter un bug</a>
</footer>
<?php endif; ?>
<script type="text/javascript" src="static/scripts.js"></script>
</body>
</html>

View File

@ -0,0 +1,26 @@
<form action="" method="post">
<h2>Identifiez-vous</h2>
<dl>
<dt>
<label for="username">Nom d'utilisateur</label>
</dt>
<dd>
<input type="text" id="username" name="username" value="<?php
echo htmlspecialchars($username);
?>" />
<?php if (isset($errors["username"])) : ?>
<p class="error"><?php echo $errors["username"]; ?></p>
<?php endif; ?>
</dd>
<dt>
<label for="password">Mot de passe</label>
</dt>
<dd>
<input type="password" id="password" name="password" />
<?php if (isset($errors["password"])) : ?>
<p class="error"><?php echo $errors["password"]; ?></p>
<?php endif; ?>
</dd>
</dl>
<p><input type="submit" value="Connexion" /></p>
</form>

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Mise à jour en cours.</title>
<meta charset="utf-8">
</head>
<body>
<?php if ($userAuthed && $userAuthed->isAdmin()) : ?>
<p><a href="">Cliquez-ici afin d'achever la mise à jour.</a></p>
<?php else: ?>
<p>Mise à jour en cours, veuillez patienter quelques instants …</p>
<?php endif; ?>
</body>
</html>

View File

@ -0,0 +1,11 @@
<?php
if (is_file($config->getFilename()) && !isset($_GET["success"])) {
header("LOCATION: ?mod=install&a=upgrade");
exit;
}
if ($action == "upgrade" && $auth->getUsername() != "admin") {
header("HTTP/1.1 403 Forbidden");
exit;
}

View File

@ -0,0 +1,83 @@
<?php
$errors = array();
$formErrors = array();
$messages = array();
if (!is_writable(DOCUMENT_ROOT."/var")) {
$errors[] = "Il est nécessaire de pouvoir écrire dans le dossier 'var' (".DOCUMENT_ROOT."/var".").";
}
if (!$errors && $_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["password"])) {
$formErrors["password"] = "Ce champ est obligatoire";
} elseif (empty($_POST["confirmPassword"]) || $_POST["confirmPassword"] != $_POST["password"]) {
$formErrors["confirmPassword"] = "Les mots de passe ne sont pas identiques.";
}
if (!empty($_POST["db"]["user"]) || !empty($_POST["db"]["dbname"])) {
if (empty($_POST["db"]["host"])) {
$formErrors["db"]["host"] = "Nom d'hôte invalide.";
}
if (empty($_POST["db"]["user"])) {
$formErrors["db"]["user"] = "Spécifiez un nom d'utilisateur.";
}
if (empty($_POST["db"]["dbname"])) {
$formErrors["db"]["dbname"] = "Spécifiez une base de données.";
}
if (!empty($_POST["db"]["user"]) && !empty($_POST["db"]["dbname"])) {
// test de connexion
$dbConnection = new mysqli(
$_POST["db"]["host"], $_POST["db"]["user"],
$_POST["db"]["password"], $_POST["db"]["dbname"]);
if ($dbConnection->connect_error) {
$formErrors["db"]["host"] = "Connexion impossible à la base de données.";
}
}
}
if (!$formErrors) {
if (!is_dir(DOCUMENT_ROOT."/var/configs")) {
mkdir(DOCUMENT_ROOT."/var/configs");
}
if (!is_dir(DOCUMENT_ROOT."/var/feeds")) {
mkdir(DOCUMENT_ROOT."/var/feeds");
}
if (!is_dir(DOCUMENT_ROOT."/var/log")) {
mkdir(DOCUMENT_ROOT."/var/log");
}
$config->set("general", "version", APPLICATION_VERSION);
if (isset($dbConnection)) {
$config->set("storage", "type", "db");
$config->set("storage", "options", array(
"host" => $_POST["db"]["host"],
"user" => $_POST["db"]["user"],
"password" => $_POST["db"]["password"],
"dbname" => $_POST["db"]["dbname"],
));
} else {
$config->set("storage", "type", "files");
}
$config->save();
$storageType = $config->get("storage", "type", "files");
if ($storageType == "db") {
// installation de la base
require DOCUMENT_ROOT."/others/install/schema.php";
$userStorage = new \App\Storage\Db\User($dbConnection);
} else {
$userStorage = new \App\Storage\File\User(DOCUMENT_ROOT."/var/users.db");
}
// table utilisateurs
$user = new \App\User\User(array(
"username" => "admin",
"password" => sha1($_POST["password"])
));
$userStorage->save($user);
header("LOCATION: ?mod=install&success=true");
exit;
}
}

View File

@ -0,0 +1,17 @@
<?php
if (!is_file($config->getFilename())) {
header("LOCATION: ?mod=install");
exit;
}
if ($auth->getUsername() != "admin") {
header("HTTP/1.1 403 Forbidden");
exit;
}
$require_upgrade = false;
if (-1 == version_compare($config->get("general", "version"), APPLICATION_VERSION)) {
$require_upgrade = true;
}

View File

@ -0,0 +1,116 @@
<?php if (!empty($errors)) : ?>
<ul class="error"><li><?php echo implode("</li><li>", $errors); ?></li></ul>
<?php else: ?>
<form action="" method="post">
<fieldset>
<legend>Nouvelle installation</legend>
<?php if (!isset($_GET["success"]) || $_GET["success"] != "true") : ?>
<dl>
<dt>Mot de passe admin :</dt>
<dd>
<input type="password" name="password" />
<?php if (!empty($formErrors["password"])) : ?>
<p class="error"><?php echo $formErrors["password"]; ?></p>
<?php endif; ?>
</dd>
<dt>Confirmer le mot de passe :</dt>
<dd>
<input type="password" name="confirmPassword" />
<?php if (!empty($formErrors["confirmPassword"])) : ?>
<p class="error"><?php echo $formErrors["confirmPassword"]; ?></p>
<?php endif; ?>
</dd>
</dl>
<h2>Stockage des données</h2>
<p>
Par défaut, les données (utilisateurs, alertes, etc.)
sont stockées dans des fichiers. C'est l'installation la plus simple
et rapide ne nécessitant que peu de connaissance.</p>
<p>
Toutefois, si vous le souhaitez vous pouvez enregistrer les données
dans une base de données MySQL (plus adapté et plus fiable).
</p>
<dl>
<dt>Type de stockage :</dt>
<dd>
<label for="typefiles">
<input type="radio" id="typefiles" name="type" value="files"<?php
echo isset($_POST["type"]) && "files" == $_POST["type"] ? ' checked="checked"' : ""
?> />
fichiers
</label>
<label for="typedb" style="margin-left: 40px;">
<input type="radio" id="typedb" name="type" value="db"<?php
echo isset($_POST["type"]) && "db" == $_POST["type"] ? ' checked="checked"' : ""
?> />
base de données MySQL
</label>
<?php if (!empty($errors["type"])) : ?>
<p class="error"><?php echo $errors["type"]; ?></p>
<?php endif; ?>
</dd>
<dt class="storage-db-options">Hôte :</dt>
<dd class="storage-db-options">
<input type="text" name="db[host]" value="<?php
echo isset($_POST["db"]["host"]) ? htmlspecialchars($_POST["db"]["host"]) : "localhost"
?>" />
<?php if (!empty($formErrors["db"]["host"])) : ?>
<p class="error"><?php echo $formErrors["db"]["host"]; ?></p>
<?php endif; ?>
</dd>
<dt class="storage-db-options">Utilisateur :</dt>
<dd class="storage-db-options">
<input type="text" name="db[user]" value="<?php
echo isset($_POST["db"]["user"]) ? htmlspecialchars($_POST["db"]["user"]) : ""
?>" />
<?php if (!empty($formErrors["db"]["user"])) : ?>
<p class="error"><?php echo $formErrors["db"]["user"]; ?></p>
<?php endif; ?>
</dd>
<dt class="storage-db-options">Mot de passe :</dt>
<dd class="storage-db-options">
<input type="password" name="db[password]" value="<?php
echo isset($_POST["db"]["password"]) ? htmlspecialchars($_POST["db"]["password"]) : ""
?>" />
<?php if (!empty($formErrors["db"]["password"])) : ?>
<p class="error"><?php echo $formErrors["db"]["password"]; ?></p>
<?php endif; ?>
</dd>
<dt class="storage-db-options">Nom de la base de données :</dt>
<dd class="storage-db-options">
<input type="text" name="db[dbname]" value="<?php
echo isset($_POST["db"]["dbname"]) ? htmlspecialchars($_POST["db"]["dbname"]) : ""
?>" />
<?php if (!empty($formErrors["db"]["dbname"])) : ?>
<p class="error"><?php echo $formErrors["db"]["dbname"]; ?></p>
<?php endif; ?>
</dd>
<dt>Cliquez sur le bouton suivant pour lancer l'installation.</dt>
<dd><input type="submit" value="Installer" /></dd>
</dl>
<?php else: ?>
<p style="color: #001FA6;"><strong>Installation terminée.</strong></p>
<p>Vous pouvez vous connecter avec les identifiants suivants :<br />
<strong>Utilisateur:</strong> admin<br />
<strong>Mot de passe:</strong> spécifié lors de l'installation.</p>
<p><a href="./">continuer &gt;</a></p>
<?php endif; ?>
</fieldset>
</form>
<script type="text/javascript">
if (document.querySelectorAll) {
var elements = document.querySelectorAll(".storage-db-options");
var buttons = document.querySelectorAll("input[name=type]");
var fnCheck = function () {
var display = document.querySelector("input[value=db]").checked ? "block" : "none";
for (var i = 0; i < elements.length; i++) {
elements[i].style.display = display;
}
};
for (var j = 0; j < buttons.length; j++) {
buttons[j].addEventListener("change", fnCheck);
}
fnCheck();
}
</script>
<?php endif; ?>

View File

@ -0,0 +1,5 @@
<?php if ($require_upgrade) : ?>
<p>Mise à jour de l'application</p>
<?php else: ?>
<p>Application à jour</p>
<?php endif; ?>

View File

@ -0,0 +1,9 @@
<?php
if ($action != "check") {
$storageType = $config->get("storage", "type", "files");
if ($storageType == "db") {
$storage = new \App\Storage\Db\Alert($dbConnection, $userAuthed);
} else {
$storage = new \App\Storage\File\Alert(DOCUMENT_ROOT."/var/configs/".$auth->getUsername().".csv");
}
}

View File

@ -0,0 +1,561 @@
<?php
set_time_limit(0);
use AdService\SiteConfigFactory;
class Main
{
/**
* @var HttpClientAbstract
*/
protected $_httpClient;
/**
* @var Config_Lite
*/
protected $_config;
/**
* @var PHPMailer
*/
protected $_mailer;
/**
* @var App\User\Storage
*/
protected $_userStorage;
protected $_lockFile;
protected $_logger;
protected $_running = false;
public function __construct(
\Config_Lite $config,
\HttpClientAbstract $client,
\App\Storage\User $userStorage)
{
$this->_config = $config;
if (function_exists("pcntl_signal")) {
pcntl_signal(SIGTERM, array($this, "sigHandler"));
pcntl_signal(SIGINT, array($this, "sigHandler"));
}
$this->_httpClient = $client;
$this->_userStorage = $userStorage;
$this->_logger = Logger::getLogger("main");
$this->_lockFile = DOCUMENT_ROOT."/var/.lock";
$this->_lock();
$this->_running = true;
$this->_logger->info("[Pid ".getmypid()."] Vérification des alertes.");
$this->_mailer = new PHPMailer($exceptions=true);
$this->_mailer->setLanguage("fr", DOCUMENT_ROOT."/lib/PHPMailer/language/");
$this->_mailer->CharSet = "utf-8";
if ($config->hasSection("mailer")) {
if ($smtp = $config->get("mailer", "smtp", array())) {
$this->_mailer->SMTPKeepAlive = true;
if (!empty($smtp["host"])) {
$this->_mailer->Host = $smtp["host"];
if (!empty($smtp["port"])) {
$this->_mailer->Port = $smtp["port"];
}
$this->_mailer->isSMTP();
}
if (!empty($smtp["username"])) {
$this->_mailer->SMTPAuth = true;
$this->_mailer->Username = $smtp["username"];
}
if (!empty($smtp["password"])) {
$this->_mailer->SMTPAuth = true;
$this->_mailer->Password = $smtp["password"];
}
if (!empty($smtp["secure"])) {
$this->_mailer->SMTPSecure = $smtp["secure"];
}
}
if ($from = $config->get("mailer", "from", null)) {
$this->_mailer->Sender = $from;
$this->_mailer->From = $from;
$this->_mailer->FromName = $from;
}
}
$this->_mailer->isHTML(true);
}
public function __destruct()
{
$this->shutdown();
}
public function check()
{
$checkStart = (int)$this->_config->get("general", "check_start", 7);
$checkEnd = (int)$this->_config->get("general", "check_end", 24);
if ($checkStart > 23) {
$checkStart = 0;
}
if ($checkEnd < 1) {
$checkEnd = 24;
}
$hour = (int)date("G");
if ($hour < $checkStart || $hour >= $checkEnd) {
$this->_logger->info("[Pid ".getmypid()."] Hors de la plage horaire. Contrôle annulé.");
return;
}
$this->_checkConnection();
$users = $this->_userStorage->fetchAll();
// génération d'URL court pour les SMS
$curlTinyurl = curl_init();
curl_setopt($curlTinyurl, CURLOPT_RETURNTRANSFER, 1);
$storageType = $this->_config->get("storage", "type", "files");
$baseurl = $this->_config->get("general", "baseurl", "");
foreach ($users AS $user) {
if ($storageType == "db") {
$storage = new \App\Storage\Db\Alert($this->_userStorage->getDbConnection(), $user);
$this->_logger->info("[Pid ".getmypid()."] USER : ".$user->getUsername());
} else {
$file = DOCUMENT_ROOT."/var/configs/".$user->getUsername().".csv";
if (!is_file($file)) {
continue;
}
$storage = new \App\Storage\File\Alert($file);
$this->_logger->info("[Pid ".getmypid()."] USER : ".$user->getUsername()." (".$file.")");
}
$reset_filename = DOCUMENT_ROOT."/var/tmp/reset_".$user->getId();
$reset = is_file($reset_filename);
if ($reset) {
unlink($reset_filename);
}
// configuration des notifications.
$notifications = array();
$notifications_params = $user->getOption("notification");
if ($notifications_params && is_array($notifications_params)) {
foreach ($notifications_params AS $notification_name => $options) {
if (!is_array($options)) {
continue;
}
try {
$notifications[$notification_name] = \Message\AdapterFactory::factory($notification_name, $options);
$this->_logger->debug(
"[Pid ".getmypid()."] USER : ".$user->getUsername().
" -> Notification ".get_class($notifications[$notification_name])." activée"
);
} catch (\Exception $e) {
$this->_logger->warn(
"[Pid ".getmypid()."] USER : ".$user->getUsername().
" -> Notification ".$notification_name." invalide"
);
}
}
}
$alerts = $storage->fetchAll();
$this->_logger->info(
"[Pid ".getmypid()."] USER : ".$user->getUsername()." -> ".
count($alerts)." alerte".(count($alerts) > 1 ? "s" : "").
" trouvée".(count($alerts) > 1 ? "s" : ""));
if (count($alerts) == 0) {
continue;
}
foreach ($alerts AS $i => $alert) {
$log_id = "[Pid ".getmypid()."] USER : ".$user->getUsername()." - ALERT ID : ".$alert->id." -> ";
try {
$config = SiteConfigFactory::factory($alert->url);
} catch (Exception $e) {
$this->_logger->warn($log_id.$e->getMessage());
continue;
}
$unique_ads = $user->getOption("unique_ads");
/**
* Si le site ne fourni pas de date par annonce,
* on est obligé de baser la dernière annonce reçue sur l'ID.
*/
if (!$config->getOption("has_date")) {
$unique_ads = true;
}
$currentTime = time();
if (!isset($alert->time_updated)) {
$alert->time_updated = 0;
}
if ($reset) {
$alert->time_updated = 0;
$alert->last_id = array();
$alert->max_id = 0;
$alert->time_last_ad = 0;
}
if (((int)$alert->time_updated + (int)$alert->interval*60) > $currentTime
|| $alert->suspend) {
continue;
}
$this->_logger->info($log_id."URL : ".$alert->url);
try {
$parser = \AdService\ParserFactory::factory($alert->url);
} catch (\AdService\Exception $e) {
$this->_logger->err($log_id." ".$e->getMessage());
continue;
}
$this->_logger->debug($log_id."Dernière mise à jour : ".(
!empty($alert->time_updated) ?
date("d/m/Y H:i", (int) $alert->time_updated) :
"inconnue"
));
$this->_logger->debug($log_id."Dernière annonce : ".(
!empty($alert->time_last_ad) ?
date("d/m/Y H:i", (int) $alert->time_last_ad) :
"inconnue"
));
$alert->time_updated = $currentTime;
if (!$content = $this->_httpClient->request($alert->url)) {
$this->_logger->error($log_id."Curl Error : ".$this->_httpClient->getError());
continue;
}
$cities = array();
if ($alert->cities) {
$cities = array_map("trim", explode("\n", mb_strtolower($alert->cities)));
}
$filter = new \AdService\Filter(array(
"price_min" => $alert->price_min,
"price_max" => $alert->price_max,
"cities" => $cities,
"price_strict" => (bool)$alert->price_strict,
"categories" => $alert->getCategories(),
"min_id" => $unique_ads ? $alert->max_id : 0,
"exclude_ids" => $alert->last_id,
));
$ads = $parser->process(
$content,
$filter,
parse_url($alert->url, PHP_URL_SCHEME)
);
$countAds = count($ads);
/**
* Migrer vers le nouveau système de détection d'annonce.
*/
if (is_numeric($alert->last_id)) {
$filter->setExcludeIds(array());
$alert->last_id = array();
$tmp_ads = $parser->process(
$content,
$filter,
parse_url($alert->url, PHP_URL_SCHEME)
);
foreach ($tmp_ads AS $tmp_ad) {
$alert->last_id[] = $tmp_ad->getId();
}
unset($tmp_ads, $tmp_ad);
}
if ($countAds == 0) {
$storage->save($alert);
continue;
}
$siteConfig = \AdService\SiteConfigFactory::factory($alert->url);
$newAds = array();
foreach ($ads AS $ad) {
$time = $ad->getDate();
$id = $ad->getId();
$newAds[$id] = require DOCUMENT_ROOT."/app/mail/views/mail-ad.phtml";
if (!in_array($id, $alert->last_id)) {
array_unshift($alert->last_id, $id);
}
if ($time && $alert->time_last_ad < $time) {
$alert->time_last_ad = $time;
}
if ($unique_ads && $id > $alert->max_id) {
$alert->max_id = $id;
}
}
// On conserve 250 IDs d'annonce vues.
if (250 < count($alert->last_id)) {
$alert->last_id = array_slice($alert->last_id, 0, 250);
}
if (!$newAds) {
$storage->save($alert);
continue;
}
$countAds = count($newAds);
$this->_logger->info(
$log_id.$countAds.
" annonce".($countAds > 1 ? "s" : "").
" trouvée".($countAds > 1?"s":"")
);
$this->_mailer->clearAddresses();
$error = false;
if ($alert->send_mail) {
try {
$emails = explode(",", $alert->email);
foreach ($emails AS $email) {
$this->_mailer->addAddress(trim($email));
}
} catch (phpmailerException $e) {
$this->_logger->warn($log_id.$e->getMessage());
$error = true;
}
if (!$error) {
if ($alert->group_ads) {
$newAdsCount = count($newAds);
$subject = "Alerte ".$siteConfig->getOption("site_name")." : ".$alert->title;
$message = '
<h1 style="font-size: 16px;">Alerte : '.htmlspecialchars($alert->title, null, "UTF-8").'</h1>
<p style="font-size: 14px; margin: 0;"><strong><a href="'.htmlspecialchars($alert->url, null, "UTF-8").'"
style="text-decoration: none; color: #0B6CDA;">LIEN DE RECHERCHE</a>';
if ($baseurl) {
$message .= '
- <a href="'.$baseurl.'?mod=mail&amp;a=form&amp;id='. $alert->id .
'" style="text-decoration: none; color: #E77600;">MODIFIER</a>
- <a href="'.$baseurl.'?mod=mail&amp;a=toggle_status&amp;s=suspend&amp;id='. $alert->id .
'" style="text-decoration: none; color: #999999;">ACTIVER / DÉSACTIVER</a>
- <a href="'.$baseurl.'?mod=mail&amp;a=form-delete&amp;id='. $alert->id .
'" style="text-decoration: none; color: #FF0000;">SUPPRIMER</a>
';
}
$message .= '</strong></p>';
$message .= '<hr />';
$message .= '<p style="font-size: 16px; margin: 10px 0;"><strong>'.
$newAdsCount.' nouvelle'.($newAdsCount > 1?'s':'').
' annonce'.($newAdsCount > 1?'s':'').
' - '.date("d/m/Y à H:i", $currentTime).'</strong></p>';
$message .= '<hr /><br />';
$message .= implode("<br /><hr /><br />", $newAds);
$message .= '<hr /><br />';
$this->_mailer->Subject = $subject;
$this->_mailer->Body = $message;
try {
$this->_mailer->send();
} catch (phpmailerException $e) {
$this->_logger->warn($log_id.$e->getMessage());
}
} else {
$newAds = array_reverse($newAds, true);
foreach ($newAds AS $id => $ad) {
$subject = ($alert->title?$alert->title." : ":"").$ads[$id]->getTitle();
$message = '
<h1 style="font-size: 16px;">Alerte : '.htmlspecialchars($alert->title, null, "UTF-8").'</h1>
<p style="font-size: 14px; margin: 0;"><strong><a href="'.htmlspecialchars($alert->url, null, "UTF-8").'"
style="text-decoration: none; color: #0B6CDA;">LIEN DE RECHERCHE</a>';
if ($baseurl) {
$message .= '
- <a href="'.$baseurl.'?mod=mail&amp;a=form&amp;id='. $alert->id .
'" style="text-decoration: none; color: #E77600;">MODIFIER</a>
- <a href="'.$baseurl.'?mod=mail&amp;a=toggle_status&amp;s=suspend&amp;id='. $alert->id .
'" style="text-decoration: none; color: #999999;">ACTIVER / DÉSACTIVER</a>
- <a href="'.$baseurl.'?mod=mail&amp;a=form-delete&amp;id='. $alert->id .
'" style="text-decoration: none; color: #FF0000;">SUPPRIMER</a>
';
}
$message .= '</strong></p>';
$message .= '<hr /><br />';
$message .= $ad;
$this->_mailer->Subject = $subject;
$this->_mailer->Body = $message;
try {
$this->_mailer->send();
} catch (phpmailerException $e) {
$this->_logger->warn($log_id.$e->getMessage());
}
}
}
}
}
if ($notifications && (
$alert->send_sms_free_mobile
|| $alert->send_sms_ovh
|| $alert->send_pushbullet
|| $alert->send_notifymyandroid
|| $alert->send_pushover
)) {
if ($countAds < 5) { // limite à 5 SMS
foreach ($newAds AS $id => $ad) {
$ad = $ads[$id]; // récupère l'objet.
$url = $ad->getLink();
if (false !== strpos($url, "leboncoin")) {
$url = "https://mobile.leboncoin.fr/vi/".$ad->getId().".htm";
}
curl_setopt($curlTinyurl, CURLOPT_URL, "http://tinyurl.com/api-create.php?url=".$url);
if ($url = curl_exec($curlTinyurl)) {
$msg = "Nouvelle annonce ".($alert->title?$alert->title." : ":"").$ad->getTitle();
$others = array();
if ($ad->getPrice()) {
$others[] = number_format($ad->getPrice(), 0, ',', ' ').$ad->getCurrency();
}
if ($ad->getCity()) {
$others[] = $ad->getCity();
} elseif ($ad->getCountry()) {
$others[] = $ad->getCountry();
}
if ($others) {
$msg .= " (".implode(", ", $others).")";
}
$params = array(
"title" => "Alerte ".$siteConfig->getOption("site_name"),
"description" => "Nouvelle annonce".($alert->title ? " pour : ".$alert->title : ""),
"url" => $url,
);
foreach ($notifications AS $key => $notifier) {
switch ($key) {
case "freeMobile":
$key_test = "send_sms_free_mobile";
break;
case "ovh":
$key_test = "send_sms_ovh";
break;
default:
$key_test = "send_".$key;
}
if (isset($alert->$key_test) && $alert->$key_test) {
try {
$notifier->send($msg, $params);
} catch (Exception $e) {
$this->_logger->warn(
$log_id."Erreur sur envoi via ".
get_class($notifier).
": (".$e->getCode().") ".
$e->getMessage()
);
}
}
}
}
}
} else { // envoi un msg global
curl_setopt($curlTinyurl, CURLOPT_URL, "http://tinyurl.com/api-create.php?url=".$alert->url);
if ($url = curl_exec($curlTinyurl)) {
$msg = "Il y a ".$countAds." nouvelles annonces pour votre alerte '".($alert->title?$alert->title:"sans nom")."'";
$params = array(
"title" => "Alerte ".$siteConfig->getOption("site_name"),
"description" => "Nouvelle".($countAds > 1 ? "s" : "").
" annonce".($countAds > 1 ? "s" : "").
($alert->title ? " pour : ".$alert->title : ""),
"url" => $url,
);
foreach ($notifications AS $key => $notifier) {
switch ($key) {
case "freeMobile":
$key_test = "send_sms_free_mobile";
break;
case "ovh":
$key_test = "send_sms_ovh";
break;
default:
$key_test = "send_".$key;
}
if (isset($alert->$key_test) && $alert->$key_test) {
try {
$notifier->send($msg, $params);
} catch (Exception $e) {
$this->_logger->warn(
$log_id."Erreur sur envoi via ".
get_class($notifier).
": (".$e->getCode().") ".
$e->getMessage()
);
}
}
}
}
}
}
$storage->save($alert);
}
}
curl_close($curlTinyurl);
$this->_mailer->smtpClose();
}
public function shutdown()
{
if ($this->_running && is_file($this->_lockFile)) {
unlink($this->_lockFile);
}
}
public function sigHandler($no)
{
if (in_array($no, array(SIGTERM, SIGINT))) {
$this->_logger->info("[Pid ".getmypid()."] QUIT (".$no.")");
$this->shutdown();
exit;
}
}
protected function _checkConnection()
{
// teste la connexion
$this->_httpClient->setDownloadBody(false);
if (false === $this->_httpClient->request("https://www.leboncoin.fr")) {
throw new Exception("Connexion vers https://www.leboncoin.fr échouée".
(($error = $this->_httpClient->getError())?" (erreur: ".$error.")":"").".");
}
if (200 != $code = $this->_httpClient->getRespondCode()) {
throw new Exception("Code HTTP différent de 200 : ".$code);
}
$this->_httpClient->setDownloadBody(true);
}
protected function _lock()
{
if (is_file($this->_lockFile)) {
throw new Exception("Un processus est en cours d'exécution.");
}
file_put_contents($this->_lockFile, time()."\n".getmypid());
return $this;
}
}
require __DIR__."/../../../bootstrap.php";
// lib
require_once "PHPMailer/class.phpmailer.php";
// modèle
$storageType = $config->get("storage", "type", "files");
if ($storageType == "db") {
$userStorage = new \App\Storage\Db\User($dbConnection);
} else {
$userStorage = new \App\Storage\File\User(DOCUMENT_ROOT."/var/users.db");
}
if (is_file(DOCUMENT_ROOT."/var/.lock_update")) {
Logger::getLogger("main")->info("Tâche annulée : une mise à jour de l'application est en cours.");
return;
}
try {
$main = new Main($config, $client, $userStorage);
} catch (\Exception $e) {
Logger::getLogger("main")->info($e->getMessage());
return;
}
try {
$main->check();
} catch (\Exception $e) {
Logger::getLogger("main")->warn($e->getMessage());
}
$main->shutdown();

View File

@ -0,0 +1,14 @@
<?php
if (!isset($_GET["id"])) {
header("LOCATION: ./?mod=mail"); exit;
}
$alert = $storage->fetchById($_GET["id"]);
if (!$alert->id) {
header("LOCATION: ./?mod=mail"); exit;
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (isset($_POST["id"]) && $_POST["id"] == $_GET["id"]) {
$storage->delete($alert);
}
header("LOCATION: ./?mod=mail"); exit;
}

View File

@ -0,0 +1,82 @@
<?php
if (isset($_GET["id"])) {
$alert = $storage->fetchById($_GET["id"]);
}
if (empty($alert)) {
$alert = new App\Mail\Alert();
}
$categoryCollection = new \Lbc\CategoryCollection();
if ($_SERVER["REQUEST_METHOD"] == "POST") {
foreach ($_POST AS $name => $value) {
if (is_array($value)) {
$_POST[$name] = array_map("trim", $_POST[$name]);
} else {
$_POST[$name] = trim($_POST[$name]);
}
}
$alert->fromArray($_POST);
if (empty($alert->send_mail)
&& empty($alert->send_sms_free_mobile)
&& empty($alert->send_sms_ovh)
&& empty($alert->send_pushbullet)
&& empty($alert->send_notifymyandroid)
&& empty($alert->send_pushover)
) {
$errors["send_type"] = "Vous devez sélectionner au moins un moyen de communication.";
}
if (empty($alert->email)) {
$errors["email"] = "Ce champ est obligatoire.";
}
if (empty($alert->title)) {
$errors["title"] = "Ce champ est obligatoire.";
}
if (empty($alert->price_min)) {
$alert->price_min = -1;
}
if (empty($alert->price_max)) {
$alert->price_max = -1;
}
if ($alert->price_min != (int)$alert->price_min) {
$errors["price"] = "Valeur de \"prix min\" non valide. ";
}
if ($alert->price_max != (int)$alert->price_max) {
$errors["price"] .= "Valeur de \"prix max\" non valide.";
}
if (!empty($_POST["price_strict"])) {
$alert->price_strict = (int)(bool)$_POST["price_strict"];
} else {
$alert->price_strict = false;
}
$alert->group = !empty($_POST["group"])?trim($_POST["group"]):"";
if (empty($alert->url)) {
$errors["url"] = "Ce champ est obligatoire.";
} else {
try {
$siteConfig = \AdService\SiteConfigFactory::factory($alert->url);
if (false !== strpos($alert->url, "leboncoin.fr")) {
$alert->url = rtrim(preg_replace("#(o|sp)=[0-9]*&?#", "", $alert->url), "?&");
}
} catch (\AdService\Exception $e) {
$errors["url"] = "Cette adresse ne semble pas valide.";
}
}
$alert->interval = (int)$alert->interval;
if ($alert->interval != (int)$alert->interval || $alert->interval < 0) {
$errors["interval"] = "Cette valeur n'est pas valide.";
}
if (empty($errors)) {
if (!empty($_POST["categories"])) {
if (is_array($alert->categories)) {
$alert->categories = implode(",", $_POST["categories"]);
} else {
$alert->categories = null;
}
} else {
$alert->categories = null;
}
$storage->save($alert);
header("LOCATION: ./?mod=mail"); exit;
}
}

View File

@ -0,0 +1,86 @@
<?php
if (isset($_GET["sort"])) {
if (in_array($_GET["sort"], array("title", "email"))) {
if (!isset($_SESSION["mail"]["sort"]) || $_SESSION["mail"]["sort"] != $_GET["sort"]) {
$_SESSION["mail"]["sort"] = $_GET["sort"];
$_SESSION["mail"]["order"] = "asc";
} elseif (!isset($_SESSION["mail"]["order"]) || $_SESSION["mail"]["order"] == "desc") {
$_SESSION["mail"]["order"] = "asc";
} else {
$_SESSION["mail"]["order"] = "desc";
}
}
header("LOCATION: ?mod=mail"); exit;
}
$alerts = $storage->fetchAll();
$sort = "";
$order = isset($_SESSION["mail"]["order"])?$_SESSION["mail"]["order"]:"asc";
if (isset($_SESSION["mail"]["sort"])) {
$sort = $_SESSION["mail"]["sort"];
setlocale(LC_CTYPE, "fr_FR.UTF-8");
usort($alerts, function ($alert1, $alert2) {
$key = $_SESSION["mail"]["sort"];
$param1 = mb_strtolower($alert1->$key);
$param2 = mb_strtolower($alert2->$key);
if ($key == "title" && function_exists("iconv")) {
$param1 = iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", $param1);
$param2 = iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", $param2);
}
if ($param1 < $param2) {
return -1;
}
if ($param1 > $param2) {
return 1;
}
return 0;
});
}
if (isset($_SESSION["mail"]["order"]) && $_SESSION["mail"]["order"] == "desc") {
$alerts = array_reverse($alerts);
}
// configuration du tableau d'affichage
$showCities = false;
$showPrice = false;
// trie les alertes par groupes
$alertsByGroup = array();
$groups = array();
foreach ($alerts AS $alert) {
$group = $alert->group?$alert->group:"Sans groupe";
$groups[] = $group;
$alertsByGroup[$group][] = $alert;
if (-1 != $alert->price_min || -1 != $alert->price_max) {
$showPrice = true;
}
if ($alert->cities) {
$showCities = true;
}
}
$groups = array_unique($groups);
sort($groups);
if (in_array("Sans groupe", $groups)) {
// met les alertes sans groupe à la fin.
unset($groups[array_search("Sans groupe", $groups)]);
$groups[] = "Sans groupe";
}
$notification["freeMobile"] = $userAuthed->hasSMSFreeMobile();
$notification["ovh"] = $userAuthed->hasSMSOvh();
$notification["pushbullet"] = $userAuthed->hasPushbullet();
$notification["notifymyandroid"] = $userAuthed->hasNotifyMyAndroid();
$notification["pushover"] = $userAuthed->hasPushover();

View File

@ -0,0 +1,8 @@
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// place le marqueur de réinitialisation
file_put_contents(DOCUMENT_ROOT."/var/tmp/reset_".$userAuthed->getId(), time());
header("LOCATION: ./?mod=mail"); exit;
}

View File

@ -0,0 +1,12 @@
<?php
if (isset($_GET["id"]) && $alert = $storage->fetchById($_GET["id"])) {
$status = isset($_GET["s"])?$_GET["s"]:"";
if (in_array($status, array("suspend", "send_mail", "send_sms_free_mobile",
"send_sms_ovh", "send_pushbullet", "send_notifymyandroid",
"send_pushover"))) {
$alert->$status = !$alert->$status;
$storage->save($alert);
}
}
header("LOCATION: ./?mod=mail"); exit;

View File

@ -0,0 +1,14 @@
<form action="" method="post">
<fieldset>
<legend>Supprimer cette alerte ?</legend>
<ul>
<li>Titre : <?php echo htmlspecialchars($alert->title); ?></li>
<li>Url : <?php echo htmlspecialchars($alert->url); ?></li>
</ul>
<p>
<input type="hidden" name="id" value="<?php echo $_GET["id"]; ?>" />
<input type="submit" value="Oui" style="font-weight: bold;" />
| <a href="?mod=mail">Non</a>
</p>
</fieldset>
</form>

View File

@ -0,0 +1,211 @@
<?php
$alertCategories = $alert->getCategories();
?>
<h2>Création d'une nouvelle alerte</h2>
<form action="" method="post">
<h2>Options obligatoires</h2>
<dl>
<dt>
<label for="url">URL de recherche</label>
</dt>
<dd>
<input type="text" id="url" name="url" value="<?php
echo htmlspecialchars($alert->url);
?>" size="75" placeholder="Ex: <?php
echo htmlspecialchars("https://www.leboncoin.fr/ventes_immobilieres/offres/champagne_ardenne/?f=a&th=1&pe=7&ret=1");
?>" />
<?php if (isset($errors["url"])) : ?>
<p class="error"><?php echo $errors["url"]; ?></p>
<?php endif; ?>
</dd>
<dt>
<label for="title">Indiquez un titre pour l'alerte</label>
</dt>
<dd>
<input type="text" id="title" name="title" value="<?php
echo htmlspecialchars($alert->title);
?>" size="50" placeholder="Ex: Achat de maison" />
<?php if (isset($errors["title"])) : ?>
<p class="error"><?php echo $errors["title"]; ?></p>
<?php endif; ?>
</dd>
<?php if ($userAuthed->hasSMSFreeMobile() || $userAuthed->hasSMSOvh() || $userAuthed->hasPushbullet()) : ?>
<dt>
<label>Comment souhaitez-vous recevoir les alertes</label>
</dt>
<dd class="notification-list">
<input type="hidden" name="send_mail" value="0" />
<input type="hidden" name="send_sms_free_mobile" value="0" />
<input type="hidden" name="send_sms_ovh" value="0" />
<input type="hidden" name="send_pushbullet" value="0" />
<input type="hidden" name="send_notifymyandroid" value="0" />
<input type="hidden" name="send_pushover" value="0" />
<label for="alert_mail">
<input id="alert_mail" type="checkbox" name="send_mail" value="1"<?php
echo $alert->send_mail?' checked="checked"':''
?> />
par email
</label>
<?php if ($userAuthed->hasSMSFreeMobile()) : ?>
<label for="alert_sms_free">
<input id="alert_sms_free" type="checkbox" name="send_sms_free_mobile" value="1"<?php
echo $alert->send_sms_free_mobile?' checked="checked"':''
?> />
par SMS Free Mobile
</label>
<?php endif; ?>
<?php if ($userAuthed->hasSMSOvh()) : ?>
<label for="alert_sms_ovh">
<input id="alert_sms_ovh" type="checkbox" name="send_sms_ovh" value="1"<?php
echo $alert->send_sms_ovh?' checked="checked"':''
?> />
par SMS OVH
</label>
<?php endif; ?>
<?php if ($userAuthed->hasPushbullet()) : ?>
<label for="alert_pushbullet">
<input id="alert_pushbullet" type="checkbox" name="send_pushbullet" value="1"<?php
echo $alert->send_pushbullet?' checked="checked"':''
?> />
par Pushbullet
</label>
<?php endif; ?>
<?php if ($userAuthed->hasNotifyMyAndroid()) : ?>
<label for="alert_notifymyandroid">
<input id="alert_notifymyandroid" type="checkbox" name="send_notifymyandroid" value="1"<?php
echo $alert->send_notifymyandroid?' checked="checked"':''
?> />
par NotityMyAndroid
</label>
<?php endif; ?>
<?php if ($userAuthed->hasPushover()) : ?>
<label for="alert_pushover">
<input id="alert_pushover" type="checkbox" name="send_pushover" value="1"<?php
echo $alert->send_pushover?' checked="checked"':''
?> />
par Pushover
</label>
<?php endif; ?>
<?php if (isset($errors["send_type"])) : ?>
<p class="error"><?php echo $errors["send_type"]; ?></p>
<?php endif; ?>
</dd>
<?php else: ?>
<dt><input type="hidden" name="send_mail" value="1" /></dt>
<?php endif; ?>
<dt>
<label for="email">Entrez une adresse email valide</label>
</dt>
<dd>
<input type="text" id="email" name="email" value="<?php
echo htmlspecialchars($alert->email);
?>" placeholder="Ex: toto@exemple.fr" />
<p class="form-more">Vous pouvez indiquer plusieurs adresses en les séparant par une virgule.</p>
<?php if (isset($errors["email"])) : ?>
<p class="error"><?php echo $errors["email"]; ?></p>
<?php endif; ?>
</dd>
</dl>
<?php $isOpen = !$alert->group_ads || $alert->interval != 30 || $alert->group; ?>
<h2 id="moreoptions" class="formbox">Plus d'options <span>(cliquez pour <?php echo $isOpen ? "fermer" : "ouvrir"; ?>)</span></h2>
<dl id="moreoptions-content" style="display: <?php echo $isOpen ? "block" : "none"; ?>;">
<dt style="margin-bottom: 10px;">
<input type="hidden" name="group_ads" value="0" />
<label for="group_ads">
<input type="checkbox" id="group_ads" name="group_ads" value="1"<?php
echo $alert->group_ads?' checked="checked"':''
?> style="margin-left: 0;" />
Cochez la case pour grouper les annonces dans un unique mail.
</label>
</dt>
<dt>
<label for="interval">Nombre de minutes avant la prochaine
vérification de nouvelles annonces</label>
</dt>
<dd>
<input type="text" id="interval" name="interval" value="<?php
echo $alert->interval;
?>" size="10" />
<?php if (isset($errors["interval"])) : ?>
<p class="error"><?php echo $errors["interval"]; ?></p>
<?php endif; ?>
</dd>
<dt><label for="group">Nom du groupe</label></dt>
<dd>
<input type="text" id="group" name="group" value="<?php echo htmlspecialchars($alert->group); ?>" />
<p class="form-more">Les alertes seront affichées par groupe sur la page de vos alertes.</p>
</dd>
</dl>
<?php $isOpen = $alert->price_min != -1 || $alert->price_max != -1
|| $alert->price_strict || !empty($alert->cities) || $alertCategories; ?>
<h2 id="morefilters" class="formbox">Filtres supplémentaires <span>(cliquez pour <?php echo $isOpen ? "fermer" : "ouvrir"; ?>)</span></h2>
<dl id="morefilters-content" style="display: <?php echo $isOpen ? "block" : "none"; ?>;">
<dt>
<label>Filtre sur le prix</label>
<dt>
<dd>
<label for="price_min">
Prix min :
<input type="text" id="price_min" name="price_min" value="<?php
echo $alert->price_min != -1?(int)$alert->price_min:"";
?>" size="6" />
</label>
<label for="price_max">
Prix max :
<input type="text" id="price_max" name="price_max" value="<?php
echo $alert->price_max != -1?(int)$alert->price_max:"";
?>" size="6" />
</label>
<?php if (isset($errors["price"])) : ?>
<p class="error"><?php echo $errors["price"]; ?></p>
<?php endif; ?>
</dd>
<dt style="margin-bottom: 10px;">
<input type="hidden" name="price_strict" value="0" />
<label for="price_strict">
<input type="checkbox" id="price_strict" name="price_strict" value="1"<?php
echo $alert->price_strict?' checked="checked"':''
?> style="margin-left: 0;" />
cochez cette case pour exclure les annonces sans prix d'indiqué de votre recherche.
</label>
</dt>
<dt><label for="cities">Filtre sur les villes ou départements (un par ligne)</label></dt>
<dd>
<textarea id="cities" name="cities" cols="30" rows="10"><?php
echo htmlspecialchars($alert->cities) ?></textarea>
</dd>
<dt><label>Filtre multi-catégorie</label></dt>
<dd class="categories">
<p class="warning"><span>Attention : </span>
ce filtre ne doit être utilisé que pour les recherches sur "toutes les catégories".</p>
<?php $i = 1; ?>
<?php foreach ($categoryCollection->fetchAll() AS $group => $categories) : ?>
<div class="categories-list categories-list-<?php echo $i++; ?>">
<h3><?php echo htmlspecialchars($group); ?></h3>
<?php foreach ($categories AS $id => $category) : ?>
<label for="category-<?php echo $id; ?>"><input id="category-<?php
echo $id; ?>" type="checkbox" name="categories[]" value="<?php
echo htmlspecialchars($category); ?>"<?php
echo in_array($category, $alertCategories)?' checked="checked"':'';
?> /><?php
echo htmlspecialchars($category); ?></label>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</dd>
</dl>
<p><input type="submit" value="Enregistrer" />
| <a href="?mod=mail">annuler</a></p>
</form>

View File

@ -0,0 +1,153 @@
<p>
<?php if (0 < $nbAlertes = count($alerts)) : ?>
<strong><?php echo $nbAlertes ?> <?php
echo $nbAlertes > 1?"alertes enregistrées":"alerte enregistrée"; ?></strong> |
<?php endif; ?>
<a href="?mod=mail&amp;a=form" class="link-create-alert">Ajouter une alerte</a> |
<a href="?mod=mail&amp;a=reset">Tout renvoyer</a>
</p>
<?php if ($groups) : ?>
<?php foreach ($groups AS $group) : ?>
<?php if (count($groups) > 1 || $group != "Sans groupe") : ?>
<h2><?php echo $group != "Sans groupe"?"Groupe : ":""; ?><?php echo htmlspecialchars($group); ?></h2>
<?php endif; ?>
<?php $alerts = $alertsByGroup[$group]; ?>
<table style="width: 100%;">
<thead>
<tr>
<th style="width: 20px"></th>
<th style="width: 250px"><?php if ($sort == "email") :
?><img src="static/images/sort-<?php echo $order; ?>.png" alt="" />&nbsp;<?php
endif; ?><a href="?mod=mail&amp;sort=email">Envoyer à</a></th>
<th><?php if ($sort == "title") :
?><img src="static/images/sort-<?php echo $order; ?>.png" alt="" />&nbsp;<?php
endif; ?><a href="?mod=mail&amp;sort=title">Titre</a></th>
<th style="width: 100px">Intervalle</th>
<?php if ($showPrice) : ?>
<th style="width: 100px">Prix</th>
<?php endif; ?>
<?php if ($showCities) : ?>
<th style="width: 200px">Villes</th>
<?php endif; ?>
<?php if ($notification["freeMobile"]
|| $notification["ovh"]
|| $notification["pushbullet"]
|| $notification["notifymyandroid"]
|| $notification["pushover"]
) : ?>
<th style="width: 140px">Envoyer par email</th>
<?php if ($notification["freeMobile"]) : ?>
<th style="width: 140px">SMS Free Mobile</th>
<?php endif; ?>
<?php if ($notification["ovh"]) : ?>
<th style="width: 140px">SMS OVH</th>
<?php endif; ?>
<?php if ($notification["pushbullet"]) : ?>
<th style="width: 140px">Pushbullet</th>
<?php endif; ?>
<?php if ($notification["notifymyandroid"]) : ?>
<th style="width: 140px">NotityMyAndroid</th>
<?php endif; ?>
<?php if ($notification["pushover"]) : ?>
<th style="width: 140px">Pushover</th>
<?php endif; ?>
<?php endif; ?>
<th style="width: 70px">Actif</th>
<th style="width: 170px">&nbsp;</th>
</tr>
</thead>
<tbody>
<?php $i = 1; foreach ($alerts AS $alert) : ?>
<tr>
<td><?php echo $i++; ?></td>
<td><?php echo str_replace(",", "<br />", htmlspecialchars($alert->email)); ?></td>
<td class="title"><a href="<?php echo htmlspecialchars($alert->url); ?>" target="_blank"><?php
echo $alert->title?htmlspecialchars($alert->title):"-"; ?></a></td>
<td class="intervalle"><?php echo (int)$alert->interval; ?> mins</td>
<?php if ($showPrice) : ?>
<td>
<?php if ($alert->price_min != -1 && $alert->price_max != -1) : ?>
entre <?php echo $alert->price_min; ?>€ et <?php echo $alert->price_max; ?>
<?php elseif ($alert->price_min != -1) : ?>
à partir de <?php echo $alert->price_min; ?>
<?php elseif ($alert->price_max != -1) : ?>
jusque <?php echo $alert->price_max; ?>
<?php else: ?>
-
<?php endif; ?>
</td>
<?php endif; ?>
<?php if ($showCities) : ?>
<td>
<?php if ($alert->cities) : ?>
<ul style="margin: 0; padding: 0 0 0 15px;"><li>
<?php echo str_replace("\n", "</li><li>", htmlspecialchars($alert->cities)); ?>
</li></ul>
<?php else: ?>
-
<?php endif; ?>
</td>
<?php endif; ?>
<?php if ($notification["freeMobile"]
|| $notification["ovh"]
|| $notification["pushbullet"]
|| $notification["notifymyandroid"]
|| $notification["pushover"]
) : ?>
<td>
<a href="?mod=mail&amp;a=toggle_status&amp;s=send_mail&amp;id=<?php echo $alert->id;
?>"><img src="static/images/<?php
echo !$alert->send_mail?"disable":"enable"; ?>.png" alt="" /></a>
</td>
<?php endif; ?>
<?php if ($notification["freeMobile"]) : ?>
<td>
<a href="?mod=mail&amp;a=toggle_status&amp;s=send_sms_free_mobile&amp;id=<?php echo $alert->id;
?>"><img src="static/images/<?php
echo !$alert->send_sms_free_mobile?"disable":"enable"; ?>.png" alt="" /></a>
</td>
<?php endif; ?>
<?php if ($notification["ovh"]) : ?>
<td>
<a href="?mod=mail&amp;a=toggle_status&amp;s=send_sms_ovh&amp;id=<?php echo $alert->id;
?>"><img src="static/images/<?php
echo !$alert->send_sms_ovh?"disable":"enable"; ?>.png" alt="" /></a>
</td>
<?php endif; ?>
<?php if ($notification["pushbullet"]) : ?>
<td>
<a href="?mod=mail&amp;a=toggle_status&amp;s=send_pushbullet&amp;id=<?php echo $alert->id;
?>"><img src="static/images/<?php
echo !$alert->send_pushbullet?"disable":"enable"; ?>.png" alt="" /></a>
</td>
<?php endif; ?>
<?php if ($notification["notifymyandroid"]) : ?>
<td>
<a href="?mod=mail&amp;a=toggle_status&amp;s=send_notifymyandroid&amp;id=<?php echo $alert->id;
?>"><img src="static/images/<?php
echo !$alert->send_notifymyandroid?"disable":"enable"; ?>.png" alt="" /></a>
</td>
<?php endif; ?>
<?php if ($notification["pushover"]) : ?>
<td>
<a href="?mod=mail&amp;a=toggle_status&amp;s=send_pushover&amp;id=<?php echo $alert->id;
?>"><img src="static/images/<?php
echo !$alert->send_pushover?"disable":"enable"; ?>.png" alt="" /></a>
</td>
<?php endif; ?>
<td>
<a href="?mod=mail&amp;a=toggle_status&amp;s=suspend&amp;id=<?php echo $alert->id;
?>"><img src="static/images/<?php
echo $alert->suspend?"disable":"enable"; ?>.png" alt="" /></a>
</td>
<td>
<a href="?mod=mail&amp;a=form&amp;id=<?php echo $alert->id; ?>">modifier</a> |
<a href="?mod=mail&amp;a=form-delete&amp;id=<?php echo $alert->id; ?>">supprimer</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endforeach; ?>
<?php endif; ?>

View File

@ -0,0 +1,46 @@
<?php ob_start(); ?>
<div>
<?php if ($ad->getDate()) : ?>
<strong>Publié le <?php echo date("d/m/Y à H:i", $ad->getDate()); ?></strong>
<br />
<?php endif; ?>
<strong>Nom</strong> :
<a href="<?php echo $ad->getLink(); ?>"><?php echo $ad->getTitle(); ?></a>
<?php if ($link_mobile = $ad->getLinkMobile()) : ?>
(<a href="<?php echo $link_mobile; ?>">Version Mobile</a>)
<?php endif; ?>
<?php if ($ad->getPrice()) : ?>
&nbsp;&nbsp;&nbsp;&nbsp;<strong>Prix</strong> : <?php echo number_format($ad->getPrice(), 0, ',', ' '); ?> <?php echo $ad->getCurrency(); ?>
<?php endif; ?>
<?php if ($ad->getCategory()) : ?>
<br />
<strong>Catégorie</strong> : <?php echo $ad->getCategory(); ?>
<?php endif; ?>
<br />
<?php if ($ad->getCountry()) : ?>
<strong>Département</strong> : <?php echo $ad->getCountry(); ?>
&nbsp;&nbsp;&nbsp;&nbsp;
<?php endif; ?>
<?php if ($ad->getCity()) : ?>
<strong>Ville</strong> : <a href="https://maps.google.fr/?z=9&q=<?php
echo htmlspecialchars($ad->getCountry().' '.$ad->getCity());
?>" title="Localiser sur Google Map"><?php echo $ad->getCity(); ?></a>
<?php endif; ?>
<?php if ($siteConfig->getOption("pro_visible")) : ?>
<br />Annonce de <?php echo $ad->getProfessional()?'professionnel':'particulier.'; ?>
<?php endif; ?>
<br />
<?php if ($ad->getUrgent()) : ?>
<strong style="color: #FF8900;">urgent</strong>
<?php endif; ?>
<?php if ($ad->getThumbnailLink()) : ?>
<br /><img src="<?php echo str_replace('/thumbs/', '/images/', $ad->getThumbnailLink()); ?>" alt=""
style="max-width: 100%; overflow:hidden;" />
<?php else : ?>
<br />Pas de photo disponible.
<?php endif; ?>
</div>
<?php
return ob_get_clean();

View File

@ -0,0 +1,13 @@
<form action="" method="post">
<fieldset>
<legend>Renvoyer toutes les alertes ?</legend>
<p>
En confirmant, vous recevrez toutes les annonces pour chaque alerte
lors du prochain contrôle de nouvelle annonce.
</p>
<p>
<input type="submit" value="Confirmer" style="font-weight: bold;" />
| <a href="?mod=mail">Annuler</a>
</p>
</fieldset>
</form>

View File

@ -0,0 +1,88 @@
<?php
namespace App\Mail;
class Alert
{
public $email;
public $id;
public $title;
public $url;
public $interval = 30;
public $time_last_ad = 0;
public $time_updated = 0;
public $price_min = -1;
public $price_max = -1;
public $price_strict = false;
public $cities;
public $categories;
public $suspend = 0;
public $group = "";
public $group_ads = 1;
public $send_mail = 1;
public $send_sms_free_mobile = 0;
public $last_id = array();
public $max_id = 0;
public $send_sms_ovh = 0;
public $send_pushbullet = 0;
public $send_notifymyandroid = 0;
public $send_pushover = 0;
public function fromArray(array $values)
{
foreach ($values AS $key => $value) {
$this->$key = $value;
}
if (!is_numeric($this->group_ads)) {
$this->group_ads = 1;
}
/**
* Depuis 3.1, last_id contient les derniers IDs de la liste d'annonce
* et max_id l'ID max trouvé.
*/
if ($this->last_id && is_numeric($this->last_id) && !$this->max_id) {
$this->max_id = $this->last_id;
}
}
public function getCategories()
{
if ($this->categories && is_string($this->categories)) {
return explode(",", $this->categories);
}
if (is_array($this->categories)) {
return $this->categories;
}
return array();
}
public function toArray()
{
return array(
"email" => $this->email,
"id" => $this->id,
"title" => $this->title,
"url" => $this->url,
"interval" => $this->interval,
"time_last_ad" => $this->time_last_ad,
"time_updated" => $this->time_updated,
"price_min" => $this->price_min,
"price_max" => $this->price_max,
"price_strict" => $this->price_strict,
"cities" => $this->cities,
"suspend" => $this->suspend,
"group" => $this->group,
"group_ads" => $this->group_ads,
"categories" => $this->categories,
"send_mail" => $this->send_mail,
"send_sms_free_mobile" => $this->send_sms_free_mobile,
"last_id" => $this->last_id,
"max_id" => (int) $this->max_id,
"send_sms_ovh" => $this->send_sms_ovh,
"send_pushbullet" => $this->send_pushbullet,
"send_notifymyandroid" => $this->send_notifymyandroid,
"send_pushover" => $this->send_pushover
);
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Storage;
interface Alert
{
public function fetchAll();
public function fetchById($id);
public function save(\App\Mail\Alert $alert);
public function delete(\App\Mail\Alert $alert);
}

View File

@ -0,0 +1,141 @@
<?php
namespace App\Storage\Db;
class Alert implements \App\Storage\Alert
{
/**
* @var \mysqli
*/
protected $_connection;
protected $_table = "LBC_Alert";
/**
* @var \App\User\User
*/
protected $_user;
public function __construct(\mysqli $connection, \App\User\User $user)
{
$this->_connection = $connection;
$this->_user = $user;
}
public function fetchAll()
{
$alerts = array();
$alertsDb = $this->_connection->query("SELECT * FROM ".$this->_table
." WHERE user_id = ".$this->_user->getId());
while ($alertDb = $alertsDb->fetch_assoc()) {
$alert = new \App\Mail\Alert();
if (isset($alertDb["last_id"]) && !is_numeric($alertDb["last_id"])) {
$alertDb["last_id"] = json_decode($alertDb["last_id"], true);
if (!is_array($alertDb["last_id"])) {
$alertDb["last_id"] = array();
}
}
$alert->fromArray($alertDb);
$alert->id = $alertDb["idstr"];
$alerts[] = $alert;
}
return $alerts;
}
public function fetchById($id)
{
$alert = null;
$alertDb = $this->_connection->query(
"SELECT * FROM ".$this->_table." WHERE user_id = ".$this->_user->getId()."
AND idstr = '".$this->_connection->real_escape_string($id)."'")
->fetch_assoc();
if ($alertDb) {
$alert = new \App\Mail\Alert();
if (isset($alertDb["last_id"]) && !is_numeric($alertDb["last_id"])) {
$alertDb["last_id"] = json_decode($alertDb["last_id"], true);
if (!is_array($alertDb["last_id"])) {
$alertDb["last_id"] = array();
}
}
$alert->fromArray($alertDb);
$alert->id = $alertDb["idstr"];
}
return $alert;
}
public function save(\App\Mail\Alert $alert, $forceInsert = false)
{
$options = $alert->toArray();
if (is_array($options["last_id"])) {
$options["last_id"] = json_encode($options["last_id"]);
}
if (!$alert->id || $forceInsert) {
$options["user_id"] = $this->_user->getId();
if (!$alert->id) {
$id = sha1(uniqid());
$alert->id = $id;
}
$options["idstr"] = $alert->id;
unset($options["id"]);
$sqlOptions = array();
foreach ($options AS $name => $value) {
if ($value === null) {
$value = "NULL";
} elseif (is_bool($value)) {
$value = (int) $value;
} elseif (!is_numeric($value)) {
$value = "'".$this->_connection->real_escape_string($value)."'";
}
$sqlOptions[$name] = $value;
}
$this->_connection->query("INSERT INTO ".$this->_table.
" (`".implode("`, `", array_keys($options)).
"`, `date_created`) VALUES (".implode(", ", $sqlOptions).", NOW())");
} else {
$idStr = $options["id"];
$sqlOptions = array();
unset($options["id"]);
foreach ($options AS $name => $value) {
if ($value === null) {
$value = "NULL";
} elseif (is_bool($value)) {
$value = (int) $value;
} elseif (!is_numeric($value)) {
$value = "'".$this->_connection->real_escape_string($value)."'";
}
$sqlOptions[] = "`".$name."` = ".$value;
}
$this->_connection->query("UPDATE ".$this->_table." SET
".implode(",", $sqlOptions).
" WHERE idstr = '".$this->_connection->real_escape_string($idStr)."'");
}
return $this;
}
public function delete(\App\Mail\Alert $alert)
{
$this->_connection->query("DELETE FROM ".$this->_table."
WHERE idstr = '".$this->_connection->real_escape_string($alert->id)."'");
return $this;
}
/**
* @param \mysqli $dbConnection
* @return \App\Storage\Db\User
*/
public function setDbConnection($dbConnection)
{
$this->_connection = $dbConnection;
return $this;
}
/**
* @return \mysqli
*/
public function getDbConnection()
{
return $this->_connection;
}
}

View File

@ -0,0 +1,102 @@
<?php
namespace App\Storage\Db;
class User implements \App\Storage\User
{
/**
* @var \mysqli
*/
protected $_connection;
protected $_table = "LBC_User";
public function __construct(\mysqli $connection)
{
$this->_connection = $connection;
}
public function fetchAll()
{
$users = array();
$usersDb = $this->_connection->query("SELECT * FROM ".$this->_table);
while ($userDb = $usersDb->fetch_object()) {
$user = new \App\User\User();
$user->setId($userDb->id)
->setPassword($userDb->password)
->setUsername($userDb->username);
if (!empty($userDb->options)) {
$options = json_decode($userDb->options, true);
if (is_array($options)) {
$user->setOptions($options);
}
}
$users[] = $user;
}
return $users;
}
public function fetchByUsername($username)
{
$user = null;
$userDb = $this->_connection->query(
"SELECT * FROM ".$this->_table." WHERE username = '".
$this->_connection->real_escape_string($username)."'")
->fetch_object();
if ($userDb) {
$user = new \App\User\User();
$user->setId($userDb->id)
->setPassword($userDb->password)
->setUsername($userDb->username);
if (!empty($userDb->options)) {
$options = json_decode($userDb->options, true);
if (is_array($options)) {
$user->setOptions($options);
}
}
}
return $user;
}
public function save(\App\User\User $user)
{
if (!$this->fetchByUsername($user->getUsername())) {
$this->_connection->query("INSERT INTO `".$this->_table.
"` (`username`, `password`, `options`) VALUES (
'".$this->_connection->real_escape_string($user->getUsername())."',
'".$this->_connection->real_escape_string($user->getPassword())."',
'".$this->_connection->real_escape_string(json_encode($user->getOptions()))."'
)");
} else {
$this->_connection->query("UPDATE `".$this->_table."` SET
`password` = '".$this->_connection->real_escape_string($user->getPassword())."',
`options` = '".$this->_connection->real_escape_string(json_encode($user->getOptions()))."'
WHERE id = ".$user->getId());
}
return $this;
}
public function delete(\App\User\User $user)
{
$this->_connection->query("DELETE FROM ".$this->_table." WHERE id = ".$user->getId());
return $this;
}
/**
* @param \mysqli $dbConnection
* @return \App\Storage\Db\User
*/
public function setDbConnection($dbConnection)
{
$this->_connection = $dbConnection;
return $this;
}
/**
* @return \mysqli
*/
public function getDbConnection()
{
return $this->_connection;
}
}

View File

@ -0,0 +1,167 @@
<?php
namespace App\Storage\File;
class Alert implements \App\Storage\Alert
{
protected $_filename;
protected $_header = array(
"email",
"id",
"title",
"url",
"interval",
"time_last_ad",
"time_updated",
"price_min",
"price_max",
"price_strict",
"cities",
"suspend",
"group",
"group_ads",
"categories",
"send_mail",
"send_sms_free_mobile",
"last_id",
"max_id",
"send_sms_ovh",
"send_pushbullet",
"send_notifymyandroid",
"send_pushover"
);
public function __construct($filename)
{
$this->_filename = $filename;
$this->_checkFile();
}
public function fetchAll()
{
$alerts = array();
if (is_file($this->_filename)) {
$fopen = fopen($this->_filename, "r");
if ($header = fgetcsv($fopen, 0, ",", '"')) {
$nb_columns = count($header);
while (false !== $values = fgetcsv($fopen, 0, ",", '"')) {
$alert = new \App\Mail\Alert();
$options = array_combine(
$header,
array_slice($values, 0, count($header))
);
if (isset($options["last_id"]) && !is_numeric($options["last_id"])) {
$options["last_id"] = json_decode($options["last_id"], true);
if (!is_array($options["last_id"])) {
$options["last_id"] = array();
}
}
$alert->fromArray($options);
$alerts[$alert->id] = $alert;
}
}
fclose($fopen);
}
return $alerts;
}
public function fetchById($id)
{
$alert = null;
if (is_file($this->_filename)) {
$fopen = fopen($this->_filename, "r");
if ($header = fgetcsv($fopen, 0, ",", '"')) {
while (false !== $values = fgetcsv($fopen, 0, ",", '"')) {
$options = array_combine(
$header,
array_slice($values, 0, count($header))
);
if ($options["id"] == $id) {
if (isset($options["last_id"]) && !is_numeric($options["last_id"])) {
$options["last_id"] = json_decode($options["last_id"], true);
if (!is_array($options["last_id"])) {
$options["last_id"] = array();
}
}
$alert = new \App\Mail\Alert();
$alert->fromArray($options);
break;
}
}
}
fclose($fopen);
}
return $alert;
}
public function save(\App\Mail\Alert $alert)
{
$alerts = $this->fetchAll();
$fopen = fopen($this->_filename, "a");
flock($fopen, LOCK_EX);
$fpNewFile = fopen($this->_filename.".new", "w");
flock($fpNewFile, LOCK_EX);
fputcsv($fpNewFile, $this->_header, ",", '"');
$updated = false;
foreach ($alerts AS $a) {
if ($a->id == $alert->id) {
$a = $alert;
$updated = true;
}
$data = $a->toArray();
if (is_array($data["last_id"])) {
$data["last_id"] = json_encode($data["last_id"]);
}
fputcsv($fpNewFile, $data, ",", '"');
}
if (!$updated && !$alert->id) {
$alert->id = sha1(uniqid());
fputcsv($fpNewFile, $alert->toArray(), ",", '"');
}
fclose($fpNewFile);
fclose($fopen);
file_put_contents($this->_filename, file_get_contents($this->_filename.".new"));
unlink($this->_filename.".new");
return $this;
}
public function delete(\App\Mail\Alert $alert)
{
$alerts = $this->fetchAll();
$fopen = fopen($this->_filename, "a");
flock($fopen, LOCK_EX);
$fpNewFile = fopen($this->_filename.".new", "w");
flock($fpNewFile, LOCK_EX);
fputcsv($fpNewFile, $this->_header, ",", '"');
unset($alerts[$alert->id]);
foreach ($alerts AS $a) {
fputcsv($fpNewFile, $a->toArray(), ",", '"');
}
fclose($fpNewFile);
fclose($fopen);
file_put_contents($this->_filename, file_get_contents($this->_filename.".new"));
unlink($this->_filename.".new");
return $this;
}
protected function _checkFile()
{
if (empty($this->_filename)) {
throw new \Exception("Un fichier doit être spécifié.");
}
$dir = dirname($this->_filename);
if (!is_file($this->_filename)) {
if (!is_writable($dir)) {
throw new \Exception("Pas d'accès en écriture sur le répertoire '".$dir."'.");
}
} elseif (!is_writable($this->_filename)) {
throw new \Exception("Pas d'accès en écriture sur le fichier '".$this->_filename."'.");
}
}
}

View File

@ -0,0 +1,145 @@
<?php
namespace App\Storage\File;
class User implements \App\Storage\User
{
public function __construct($filename)
{
$this->_filename = $filename;
$this->_checkFile();
}
public function fetchAll()
{
$users = array();
if (is_file($this->_filename)) {
$fopen = fopen($this->_filename, "r");
while (false !== $value = fgets($fopen)) {
$value = trim($value);
$user = new \App\User\User();
$user->setPassword(substr($value, 0, 40))
->setUsername(substr($value, 40));
$this->_loadUserOptions($user);
$users[] = $user;
}
fclose($fopen);
}
return $users;
}
public function fetchByUsername($username)
{
$user = null;
if (is_file($this->_filename)) {
$fopen = fopen($this->_filename, "r");
while (false !== $value = fgets($fopen)) {
$value = trim($value);
if (substr($value, 40) == $username) {
$user = new \App\User\User();
$user->setPassword(substr($value, 0, 40))
->setUsername($username);
$this->_loadUserOptions($user);
break;
}
}
fclose($fopen);
}
return $user;
}
public function save(\App\User\User $user)
{
if (!$this->fetchByUsername($user->getUsername()) || !is_file($this->_filename)) {
$fopen = fopen($this->_filename, "a");
fputs($fopen, $user->getPassword().$user->getUsername()."\n");
fclose($fopen);
} else {
$fopen = fopen($this->_filename, "r");
$fpNewFile = fopen($this->_filename.".new", "w");
flock($fopen, LOCK_EX);
while (false !== $value = fgets($fopen)) {
$value = trim($value);
if (substr($value, 40) == $user->getUsername()) {
$value = $user->getPassword().$user->getUsername();
}
fputs($fpNewFile, $value."\n");
}
fclose($fopen);
fclose($fpNewFile);
file_put_contents($this->_filename, file_get_contents($this->_filename.".new"));
unlink($this->_filename.".new");
$this->_saveUserOptions($user);
}
return $this;
}
public function delete(\App\User\User $user)
{
if (is_file($this->_filename)) {
$fopen = fopen($this->_filename, "r");
$fpNewFile = fopen($this->_filename.".new", "w");
while (false !== $value = fgets($fopen)) {
$value = trim($value);
if (substr($value, 40) != $user->getUsername()) {
fputs($fpNewFile, $value."\n");
}
}
fclose($fopen);
fclose($fpNewFile);
file_put_contents($this->_filename, file_get_contents($this->_filename.".new"));
unlink($this->_filename.".new");
$this->_deleteUserOptions($user);
}
return $this;
}
protected function _checkFile()
{
if (empty($this->_filename)) {
throw new \Exception("Un fichier doit être spécifié.");
}
$dir = dirname($this->_filename);
if (!is_file($this->_filename)) {
if (!is_writable($dir)) {
throw new \Exception("Pas d'accès en écriture sur le répertoire '".$dir."'.");
}
} elseif (!is_writable($this->_filename)) {
throw new \Exception("Pas d'accès en écriture sur le fichier '".$this->_filename."'.");
}
}
protected function _loadUserOptions(\App\User\User $user)
{
$dir = DOCUMENT_ROOT.DS."var".DS."configs";
$filename = $dir.DS."user_".$user->getUsername().".json";
if (is_file($filename)) {
$data = json_decode(trim(file_get_contents($filename)), true);
if ($data && is_array($data)) {
$user->setOptions($data);
}
}
return $this;
}
protected function _saveUserOptions(\App\User\User $user)
{
$dir = DOCUMENT_ROOT.DS."var".DS."configs";
if (!is_dir($dir)) {
mkdir($dir);
}
$filename = $dir.DS."user_".$user->getUsername().".json";
file_put_contents($filename, json_encode($user->getOptions()));
return $this;
}
protected function _deleteUserOptions(\App\User\User $user)
{
$dir = DOCUMENT_ROOT.DS."var".DS."configs";
$filename = $dir.DS."user_".$user->getUsername().".json";
if (is_file($filename)) {
unlink($filename);
}
return $this;
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Storage;
interface User
{
public function fetchAll();
public function fetchByUsername($username);
public function save(\App\User\User $user);
public function delete(\App\User\User $user);
}

View File

@ -0,0 +1,186 @@
<?php
namespace App;
class Updater
{
protected $_tmp_dir;
protected $_destination;
/**
* Adresse pour la récupération de la dernière version
* @var string
*/
protected $_url_version = "https://raw.githubusercontent.com/Blount/LBCAlerte/master/version.php";
/**
* Adresse pour récupérer l'archive ZIP.
* %VERSION% est remplacer parle numéro de version à télécharger.
* @var string
*/
protected $_url_archive = "https://github.com/Blount/LBCAlerte/archive/%VERSION%.zip";
public function __construct()
{
$this->_tmp_dir = DOCUMENT_ROOT."/var/tmp";
$this->_destination = DOCUMENT_ROOT;
}
/**
* @param string $tmp_dir
* @return Updater
*/
public function setTmpDir($tmp_dir)
{
$this->_tmp_dir = $tmp_dir;
return $this;
}
/**
* @return string
*/
public function getTmpDir()
{
return $this->_tmp_dir;
}
/**
* @param string $destination
* @return Updater
*/
public function setDestination($destination)
{
$this->_destination = $destination;
return $this;
}
/**
* @return string
*/
public function getDestination()
{
return $this->_destination;
}
/**
* @param string $url_version
* @return Updater
*/
public function setUrlVersion($url_version)
{
$this->_url_version = $url_version;
return $this;
}
/**
* @return string
*/
public function getUrlVersion()
{
return $this->_url_version;
}
/**
* @param string $url_archive
* @return Updater
*/
public function setUrlArchive($url_archive)
{
$this->_url_archive = $url_archive;
return $this;
}
/**
* @return string
*/
public function getUrlArchive()
{
return $this->_url_archive;
}
public function getLastVersion()
{
$lastVersion = file_get_contents($this->getUrlVersion());
if (preg_match('#return\s+"(.*)"\s*;#imsU', $lastVersion, $m)) {
return $m[1];
}
throw new \Exception("Impossible de récupérer la dernière version.");
}
public function installFiles($version)
{
$tmpZip = $this->_tmp_dir."/latest.zip";
if (!is_dir($this->_tmp_dir)) {
mkdir($this->_tmp_dir);
}
if (!is_writable($this->_tmp_dir)) {
throw new \Exception("Impossible d'écrire dans '".$this->_tmp_dir."'");
}
$archive = str_replace("%VERSION%", $version, $this->_url_archive);
if (!is_file($tmpZip) && !copy($archive, $tmpZip)) {
throw new \Exception("Impossible de récupérer l'archive.");
}
$zip = new \ZipArchive();
if (!$zip->open($tmpZip)) {
throw new \Exception("L'archive semble erronée.");
}
// extraire l'archive
$zip->extractTo($this->_tmp_dir);
$zip->close();
// mise à jour des fichiers.
$this->_copyFiles($this->_tmp_dir."/LBCAlerte-".$version, $this->_destination);
rmdir($this->_tmp_dir."/LBCAlerte-".$version);
unlink($tmpZip);
}
public function update($fromVersion, $toVersion)
{
// exécute les mises à jour
$directory = $this->_destination."/others/update";
if (is_dir($directory)) {
$filenames = scandir($directory);
$filenames_php = array();
foreach ($filenames AS $filename) {
if ($filename != "update.php" && false !== strpos($filename, ".php")) {
$filenames_php[basename($filename, ".php")] = $filename;
}
}
$versions = array_keys($filenames_php);
usort($versions, function ($a1, $a2) {
return version_compare($a1, $a2, "<") ? -1 : 1;
});
foreach ($versions AS $version) {
if (version_compare($fromVersion, $version, "<")
&& version_compare($toVersion, $version, ">=")) {
require $directory."/".$filenames_php[$version];
$class = "Update_".str_replace(".", "", $version);
if (class_exists($class, false)) {
$class = new $class();
$class->update();
}
}
}
}
}
protected function _copyFiles($dir, $to)
{
foreach (scandir($dir) AS $file) {
if ($file == "." || $file == "..") {
continue;
}
$destFile = $to."/".$file;
if (is_file($dir."/".$file)) {
rename($dir."/".$file, $destFile);
} elseif (is_dir($dir."/".$file)) {
if (!is_dir($destFile)) {
mkdir($destFile);
}
$this->_copyFiles($dir."/".$file, $destFile);
rmdir($dir."/".$file);
}
}
}
}

View File

@ -0,0 +1,190 @@
<?php
namespace App\User;
class User
{
protected $_id;
protected $_username;
protected $_password;
protected $_options = array();
protected $_optionsLoaded = false;
public function __construct(array $options = array())
{
if (isset($options["id"])) {
$this->setId($options["id"]);
}
if (isset($options["username"])) {
$this->setUsername($options["username"]);
}
if (isset($options["password"])) {
$this->setPassword($options["password"]);
}
}
/**
* @param int $id
* @return User
*/
public function setId($id)
{
$this->_id = $id;
return $this;
}
/**
* @return int
*/
public function getId()
{
if (!$this->_id) {
return md5($this->_username);
}
return $this->_id;
}
/**
* @param string $username
* @return User
*/
public function setUsername($username)
{
$this->_username = $username;
return $this;
}
/**
* @return string
*/
public function getUsername()
{
return $this->_username;
}
/**
* @param string $password
* @return User
*/
public function setPassword($password)
{
$this->_password = $password;
return $this;
}
/**
* @return string
*/
public function getPassword()
{
return $this->_password;
}
/**
* Retourne vrai si la notification SMS Free Mobile est activée.
* @return boolean
*/
public function hasSMSFreeMobile()
{
return false != $this->getOption("notification.freeMobile");
}
/**
* Retourne vrai si la notification SMS OVH est activée.
* @return boolean
*/
public function hasSMSOvh()
{
return false != $this->getOption("notification.ovh");
}
/**
* Retourne vrai si la notification Pushbullet est activée.
* @return boolean
*/
public function hasPushbullet()
{
return false != $this->getOption("notification.pushbullet");
}
/**
* Retourne vrai si la notification NotifyMyAndroid est activée.
* @return boolean
*/
public function hasNotifyMyAndroid()
{
return false != $this->getOption("notification.notifymyandroid");
}
/**
* Retourne vrai si la notification Pushover est activée.
* @return boolean
*/
public function hasPushover()
{
return false != $this->getOption("notification.pushover");
}
/**
* Indique si l'utilisateur est administrateur.
* @return boolean
*/
public function isAdmin()
{
return $this->getUsername() == "admin";
}
public function getOption($name, $default = null)
{
if (strpos($name, ".")) {
$options = explode(".", $name);
$nbOptions = count($options);
$current = $this->_options;
for ($i = 0; $i < $nbOptions; $i++) {
if (is_array($current) && isset($current[$options[$i]])) {
$current = $current[$options[$i]];
} else {
break;
}
}
if ($i == $nbOptions) {
return $current;
}
return $default;
}
return isset($this->_options[$name])?$this->_options[$name]:$default;
}
public function setOption($name, $value)
{
if (strpos($name, ".")) {
$options = explode(".", $name);
$nbOptions = count($options);
$current = $value;
for ($i = $nbOptions - 1; $i >= 0; $i--) {
$current = array($options[$i] => $current);
}
$this->_options = array_replace_recursive($this->_options, $current);
} else {
$this->_options[$name] = $value;
}
return $this;
}
public function getOptions()
{
return $this->_options;
}
public function setOptions(array $options)
{
$this->_options = $options;
return $this;
}
public function mergeOptions(array $options)
{
$this->_options = array_replace_recursive($this->_options, $options);
return $this;
}
}

View File

@ -0,0 +1,45 @@
<?php
$values = array(
"url" => "", "price_min" => "", "price_max" => "", "price_strict" => false,
"cities" => "", "categories" => array()
);
$categoryCollection = new \Lbc\CategoryCollection();
if ($_SERVER["REQUEST_METHOD"] == "POST") {
foreach ($_POST AS $name => $value) {
if (is_array($value)) {
$_POST[$name] = array_map("trim", $_POST[$name]);
} else {
$_POST[$name] = trim($_POST[$name]);
}
}
$values = array_merge($values, $_POST);
if (empty($values["url"])) {
$errors["url"] = "Ce champ est obligatoire.";
}
if ($values["price_min"] && $values["price_min"] != (int)$values["price_min"]) {
$errors["price"] = "Valeur de \"prix min\" non valide. ";
}
if ($values["price_max"] && $values["price_max"] != (int)$values["price_max"]) {
$errors["price"] .= "Valeur de \"prix max\" non valide.";
}
if (empty($errors)) {
$query = array("mod" => "rss", "a" => "refresh", "url" => $values["url"]);
if (!empty($values["price_min"])) {
$query["price_min"] = (int)$values["price_min"];
}
if (!empty($values["price_max"])) {
$query["price_max"] = (int)$values["price_max"];
}
if (!empty($values["cities"])) {
$query["cities"] = $values["cities"];
}
if (!empty($values["categories"]) && is_array($values["categories"])) {
$query["categories"] = $values["categories"];
}
$query["price_strict"] = isset($values["price_strict"])?
(int)(bool)$values["price_strict"]:0;
header("LOCATION: ./?".http_build_query($query));
}
}

View File

@ -0,0 +1,98 @@
<?php
if (!isset($_GET["url"])) {
return;
}
$disableLayout = true;
$logFile = DOCUMENT_ROOT."/var/logs/rss.log";
use \FeedWriter\RSS2;
try {
$parser = \AdService\ParserFactory::factory($_GET["url"]);
} catch (\AdService\Exception $e) {
echo "Cette adresse ne semble pas valide.";
exit;
}
if (false !== strpos($_GET["url"], "leboncoin.fr")) {
$_GET["url"] = rtrim(preg_replace("#(o|sp)=[0-9]*&?#", "", $_GET["url"]), "?&");
}
// nettoyage cache
$files = array_diff(scandir(DOCUMENT_ROOT."/var/feeds"), array(".", ".."));
foreach ($files AS $file) {
$file = DOCUMENT_ROOT."/var/feeds/".$file;
$mtime = filemtime($file);
if (($mtime + 20 * 60) < time()) {
unlink($file);
}
}
header("Content-Type: application/rss+xml", true);
$logger = Logger::getLogger("main");
$id = sha1($_SERVER["REQUEST_URI"]);
$cache_filename = DOCUMENT_ROOT."/var/feeds/".$id.".xml";
if (is_file($cache_filename)) {
readfile($cache_filename);
return;
}
$params = $_GET;
if (isset($params["cities"])) {
$params["cities"] = array_map("trim", explode("\n", mb_strtolower($params["cities"])));
}
$content = $client->request($_GET["url"]);
$filter = new \AdService\Filter($params);
$siteConfig = \AdService\SiteConfigFactory::factory($_GET["url"]);
$ads = $parser->process(
$content,
$filter,
parse_url($_GET["url"], PHP_URL_SCHEME)
);
$title = $siteConfig->getOption("site_name");
$urlParams = parse_url($_GET["url"]);
if (!empty($urlParams["query"])) {
parse_str($urlParams["query"], $aQuery);
if (!empty($aQuery["q"])) {
$title .= " - ".$aQuery["q"];
}
}
$feeds = new RSS2;
$feeds->setTitle($siteConfig->getOption("site_name"));
$feeds->setLink($siteConfig->getOption("site_url"));
$feeds->setSelfLink(
!empty($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"?"https":"http".
"://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"]
);
$feeds->setDescription("Flux RSS de la recherche : ".$_GET["url"]);
$feeds->setChannelElement("language", "fr-FR");
// The date when this feed was lastly updated. The publication date is also set.
$feeds->setDate(date(DATE_RSS, time()));
$feeds->setChannelElement("pubDate", date(\DATE_RSS, strtotime("2013-04-06")));
$feeds->addGenerator();
if (count($ads)) {
foreach ($ads AS $ad) {
$item = $feeds->createNewItem();
$item->setTitle($ad->getTitle());
$item->setLink($ad->getLink());
$item->setDescription(require DOCUMENT_ROOT."/app/rss/views/rss-ad.phtml");
if ($ad->getDate()) {
$item->setDate($ad->getDate());
}
$item->setId(md5($ad->getId()));
$feeds->addItem($item);
}
}
$content = $feeds->generateFeed();
file_put_contents($cache_filename, $content);
echo $content;

View File

@ -0,0 +1,70 @@
<form action="" method="post">
<h2>Génération d'un flux RSS</h2>
<dl>
<dt><label for="url">
Indiquer l'adresse de recherche</label></dt>
<dd><input type="text" id="url" name="url" value="<?php
echo $values["url"]; ?>" size="75" placeholder="Ex: <?php
echo htmlspecialchars("https://www.leboncoin.fr/ventes_immobilieres/offres/champagne_ardenne/?f=a&th=1&pe=7&ret=1");
?>" /></dd>
</dl>
<?php $isOpen = $values["price_min"] || $values["price_max"]
|| $values["price_strict"] || !empty($values["cities"]); ?>
<h2 id="morefilters" class="formbox">Filtres supplémentaires <span>(cliquez pour <?php
echo $isOpen ? "fermer" : "ouvrir"
?>)</span></h2>
<dl id="morefilters-content" style="display: <?php
echo $isOpen ? "block" : "none"
?>;">
<dt>
<label>Filtre sur le prix</label>
<dt>
<dd>
<label for="price_min">
Prix min :
<input type="text" id="price_min" name="price_min" value="<?php
echo $values["price_min"]; ?>" size="6" />
</label>
<label for="price_max">
Prix max :
<input type="text" id="price_max" name="price_max" value="<?php
echo $values["price_max"]; ?>" size="6" />
</label>
<?php if (isset($errors["price"])) : ?>
<p class="error"><?php echo $errors["price"]; ?></p>
<?php endif; ?>
</dd>
<dt style="margin-bottom: 10px;">
<input type="hidden" name="price_strict" value="0" />
<label for="price_strict">
<input type="checkbox" id="price_strict" name="price_strict" value="1"<?php
echo $values["price_strict"]?' checked="checked"':''
?> style="margin-left: 0;" />
cochez cette case pour exclure les annonces sans prix d'indiqué de votre recherche.
</label>
</dt>
<dt><label for="cities">Filtre sur les villes ou départements (un par ligne)</label></dt>
<dd>
<textarea id="cities" name="cities" cols="30" rows="10"><?php
echo htmlspecialchars($values["cities"]) ?></textarea>
</dd>
<dt><label>Filtre multi-catégorie</label></dt>
<dd class="categories">
<p class="warning"><span>Attention : </span>
ce filtre ne doit être utilisé que pour les recherches sur "toutes les catégories".</p>
<?php $i = 1; ?>
<?php foreach ($categoryCollection->fetchAll() AS $group => $categories) : ?>
<div class="categories-list categories-list-<?php echo $i++; ?>">
<h3><?php echo htmlspecialchars($group); ?></h3>
<?php foreach ($categories AS $id => $category) : ?>
<label for="category-<?php echo $id; ?>"><input id="category-<?php
echo $id; ?>" type="checkbox" name="categories[]" value="<?php
echo htmlspecialchars($category); ?>" /><?php
echo htmlspecialchars($category); ?></label>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</dd>
</dl>
<p><input type="submit" value="Générer le flux" /></p>
</form>

View File

@ -0,0 +1,45 @@
<?php
ob_start();
?>
<?php if ($ad->getDate()) : ?>
Publié le <strong><?php echo date("d/m/Y H:i", $ad->getDate()); ?></strong>
<br />
<br />
<?php endif; ?>
<strong>Nom</strong> : <?php echo $ad->getTitle(); ?>
<?php if ($ad->getPrice()) : ?>
&nbsp;&nbsp;&nbsp;&nbsp;<strong>Prix</strong> : <?php echo number_format($ad->getPrice(), 0, ',', ' '); ?> <?php echo $ad->getCurrency(); ?>
<?php endif; ?>
<?php if ($ad->getCategory()) : ?>
<br />
<strong>Catégorie</strong> : <?php echo $ad->getCategory(); ?>
<?php endif; ?>
<br />
<?php if ($ad->getCountry()) : ?>
<strong>Département</strong> : <?php echo $ad->getCountry(); ?>
&nbsp;&nbsp;&nbsp;&nbsp;
<?php endif; ?>
<?php if ($ad->getCity()) : ?><strong>Ville</strong> : <a href="https://maps.google.fr/?z=9&q=<?php
echo htmlspecialchars($ad->getCountry().' '.$ad->getCity());
?>" title="Localiser sur Google Map" target="_blank"><?php echo $ad->getCity(); ?></a>
<?php endif; ?>
<?php if ($siteConfig->getOption("pro_visible")) : ?>
<br />Annonce de <?php echo $ad->getProfessional()?'professionnel':'particulier.'; ?>
<?php endif; ?>
<br />
<?php if ($ad->getUrgent()) : ?>
<strong style="color: #FF8900;">urgent</strong>
<?php endif; ?>
<?php if ($ad->getThumbnailLink()) : ?>
<br /><img src="<?php echo str_replace('/thumbs/', '/images/', $ad->getThumbnailLink()); ?>"
alt="" style="max-width: 600px; float: left; display: block;" />
<?php else : ?>
<br />Pas de photo disponible.
<?php endif; ?>
<?php
return ob_get_clean();

View File

@ -0,0 +1,123 @@
<?php
$params = array(
"notification" => $userAuthed->getOption("notification"),
"unique_ads" => $userAuthed->getOption("unique_ads", false)
);
if (!is_array($params["notification"])) {
$params["notification"] = array();
}
$form_values["notification"] = array_replace_recursive(array(
"freeMobile" => array(
"user" => "",
"key" => "",
),
"notifymyandroid" => array(
"token" => "",
),
"pushbullet" => array(
"token" => "",
),
"ovh" => array(
"account" => "",
"login" => "",
"password" => "",
"from" => "",
"to" => "",
),
"pushover" => array(
"token" => "",
"user_key" => "",
),
), $params["notification"]);
$errors = array();
$errorsTest = array();
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$params = array_merge($params, $_POST);
// test config Free Mobile
foreach ($params["notification"] AS $section => $options) {
if (is_array($options)) {
$hasValue = false;
foreach ($options AS $name => $value) {
if (empty($value)) {
$errors["notification"][$section][$name] = "Ce champ doit être renseigné.";
} else {
$hasValue = true;
}
}
if (!$hasValue) {
unset($errors["notification"][$section]);
$params["notification"][$section] = false;
}
}
}
if (empty($errors["notification"])) {
unset($errors["notification"]);
}
if (empty($errors)) {
if (!empty($_POST["testFreeMobile"])) {
$sms = \Message\AdapterFactory::factory("freeMobile", $params["notification"]["freeMobile"]);
try {
$sms->send("La notification SMS est fonctionnelle.");
} catch (Exception $e) {
$errorsTest["freeMobile"] = "Erreur lors de l'envoi du SMS : (".$e->getCode().") ".$e->getMessage();
}
} elseif (!empty($_POST["testPushbullet"])) {
if (empty($_POST["notification"]["pushbullet"]["token"])) {
$errors["notification"]["pushbullet"]["token"] = "Veuillez renseigner la clé d'identification. ";
} else {
$sender = \Message\AdapterFactory::factory("pushbullet", $_POST["notification"]["pushbullet"]);
try {
$sender->send("La notification Pushbullet est fonctionnelle");
} catch (Exception $e) {
$errorsTest["pushbullet"] = "Erreur lors de l'envoi de la notification : (".$e->getCode().") ".$e->getMessage();
}
}
} elseif (!empty($_POST["testOvh"])) {
$sender = \Message\AdapterFactory::factory("SmsOvh", $params["notification"]["ovh"]);
try {
$sender->send("La notification SMS est fonctionnelle.");
} catch (Exception $e) {
$errorsTest["ovh"] = "Erreur lors de l'envoi du SMS : (".$e->getCode().") ".$e->getMessage();
}
} elseif (!empty($_POST["testNotifyMyAndroid"])) {
if (empty($_POST["notification"]["notifymyandroid"]["token"])) {
$errors["notification"]["notifymyandroid"]["token"] = "Veuillez renseigner la clé d'identification.";
} else {
$sender = \Message\AdapterFactory::factory("notifymyandroid", $_POST["notification"]["notifymyandroid"]);
try {
$sender->send("La notification NotifyMyAndroid est fonctionnelle", array(
"title" => "Test alerte"
));
} catch (Exception $e) {
$errorsTest["notifymyandroid"] = "Erreur lors de l'envoi de la notification : (".$e->getCode().") ".$e->getMessage();
}
}
} elseif (!empty($_POST["testPushover"])) {
if (empty($_POST["notification"]["pushover"]["token"])) {
$errors["notification"]["pushover"]["token"] = "Veuillez renseigner la clé application.";
} elseif (empty($_POST["notification"]["pushover"]["user_key"])) {
$errors["notification"]["pushover"]["user_key"] = "Veuillez renseigner la clé utilisateur.";
} else {
$sender = \Message\AdapterFactory::factory("pushover", $_POST["notification"]["pushover"]);
try {
$sender->send("La notification Pushover est fonctionnelle");
} catch (Exception $e) {
$errorsTest["pushover"] = "Erreur lors de l'envoi de la notification : (".$e->getCode().") ".$e->getMessage();
}
}
} else {
$userAuthed->mergeOptions($params);
$userStorage->save($userAuthed);
$_SESSION["userSettingsSaved"] = true;
header("LOCATION: ./?mod=user&a=settings"); exit;
}
}
}
$userSettingsSaved = isset($_SESSION["userSettingsSaved"]) && true === $_SESSION["userSettingsSaved"];
unset($_SESSION["userSettingsSaved"]);

View File

@ -0,0 +1,250 @@
<form action="" method="post" autocomplete="off">
<?php if (!empty($errors)) : ?>
<p class="error" style="font-size: 1.3em; background: #AB0000; color: #FFF; text-align: center; line-height: 200%;">
Il y a au moins une erreur présente dans le formulaire.</p>
<?php elseif (!empty($errorsTest)) : ?>
<p class="error" style="font-size: 1.3em; background: #AB0000; color: #FFF; text-align: center; line-height: 200%;">
Le test d'envoi a échoué. Voir ci-dessous pour le message d'erreur.</p>
<?php elseif ($userSettingsSaved) : ?>
<p style="font-size: 1.3em; background: #00AB00; color: #FFF; text-align: center; line-height: 200%;">
Les paramètres ont été enregistrés.</p>
<?php endif;?>
<h2>Options générales</h2>
<dl>
<dt style="margin-bottom: 10px;">
<input type="hidden" name="unique_ads" value="0" />
<label for="unique_ads">
<input type="checkbox" id="unique_ads" name="unique_ads" value="1"<?php
echo $params["unique_ads"] ?' checked="checked"':''
?> style="margin-left: 0;" />
Cochez la case pour ne pas recevoir les annonces remontées (évite les doublons).
</label>
</dt>
</dl>
<h2 id="configFreeMobile" class="formbox">Configuration SMS via Free Mobile</h2>
<dl id="configFreeMobile-content" style="display: <?php echo !empty($form_values["notification"]["freeMobile"]["user"]) ? "block" : "none"; ?>;">
<dt>
<label for="free_mobile_user">ID utilisateur</label>
</dt>
<dd>
<input type="text" id="free_mobile_user" name="notification[freeMobile][user]" value="<?php
echo htmlspecialchars($form_values["notification"]["freeMobile"]["user"]);
?>" />
<?php if (isset($errors["notification"]["freeMobile"]["user"])) : ?>
<p class="error"><?php echo $errors["notification"]["freeMobile"]["user"]; ?></p>
<?php endif; ?>
</dd>
<dt>
<label for="free_mobile_key">Clé d'identification</label>
</dt>
<dd>
<input type="text" id="free_mobile_key" name="notification[freeMobile][key]" value="<?php
echo htmlspecialchars($form_values["notification"]["freeMobile"]["key"]);
?>" />
<?php if (isset($errors["notification"]["freeMobile"]["key"])) : ?>
<p class="error"><?php echo $errors["notification"]["freeMobile"]["key"]; ?></p>
<?php endif; ?>
</dd>
<dt style="border: none;">
<input type="submit" name="testFreeMobile" value="Effectuer un test d'envoi SMS" />
</dt>
<?php if (empty($errors) && !empty($_POST["testFreeMobile"])) : ?>
<dd>
<?php if (isset($errorsTest["freeMobile"])) : ?>
<p style="font-weight: bold; color: #AB0000;"><?php
echo htmlspecialchars($errorsTest["freeMobile"]);
?></p>
<?php else: ?>
<p style="font-weight: bold; color: #333399;">Vous devriez recevoir un SMS contenant le message suivant:
« La notification SMS est fonctionnelle ».</p>
<p style="font-weight: bold; color: #339933;">Pensez à confirmer la configuration en cliquant sur "Enregistrer".</p>
<?php endif; ?>
</dd>
<?php endif; ?>
</dl>
<h2 id="configPushbullet" class="formbox">Configuration alerte via Pushbullet</h2>
<dl id="configPushbullet-content" style="display: <?php echo !empty($form_values["notification"]["pushbullet"]["token"]) ? "block" : "none"; ?>;">
<dt>
<label for="pushbullet_token">Clé du service</label>
</dt>
<dd>
<input type="text" id="pushbullet_token" name="notification[pushbullet][token]" value="<?php
echo htmlspecialchars($form_values["notification"]["pushbullet"]["token"]);
?>" />
<?php if (isset($errors["notification"]["pushbullet"]["token"])) : ?>
<p class="error"><?php echo $errors["notification"]["pushbullet"]["token"]; ?></p>
<?php endif; ?>
</dd>
<dt style="border: none;">
<input type="submit" name="testPushbullet" value="Effectuer un test d'envoi de message" />
</dt>
<?php if (empty($errors) && !empty($_POST["testPushbullet"])) : ?>
<dd>
<?php if (isset($errorsTest["pushbullet"])) : ?>
<p style="font-weight: bold; color: #AB0000;"><?php
echo htmlspecialchars($errorsTest["pushbullet"]);
?></p>
<?php else: ?>
<p style="font-weight: bold; color: #333399;">Vous devriez recevoir une notification contenant le message suivant:
« La notification Pushbullet est fonctionnelle ».</p>
<p style="font-weight: bold; color: #339933;">Pensez à confirmer la configuration en cliquant sur "Enregistrer".</p>
<?php endif; ?>
</dd>
<?php endif; ?>
</dl>
<h2 id="configOvh" class="formbox">Configuration SMS via OVH Telecom</h2>
<dl id="configOvh-content" style="display: <?php echo !empty($form_values["notification"]["ovh"]["account"]) ? "block" : "none"; ?>;">
<dt>
<label for="ovh_account">Numéro de compte</label>
</dt>
<dd>
<input type="text" id="ovh_account" name="notification[ovh][account]" value="<?php
echo htmlspecialchars($form_values["notification"]["ovh"]["account"]);
?>" placeholder="De la forme : sms-xxxxxxxx-x" />
<?php if (isset($errors["notification"]["ovh"]["account"])) : ?>
<p class="error"><?php echo $errors["notification"]["ovh"]["account"]; ?></p>
<?php endif; ?>
</dd>
<dt>
<label for="ovh_login">Utilisateur</label>
</dt>
<dd>
<input type="text" id="ovh_login" name="notification[ovh][login]" value="<?php
echo htmlspecialchars($form_values["notification"]["ovh"]["login"]);
?>" />
<?php if (isset($errors["notification"]["ovh"]["login"])) : ?>
<p class="error"><?php echo $errors["notification"]["ovh"]["login"]; ?></p>
<?php endif; ?>
</dd>
<dt>
<label for="ovh_password">Mot de passe</label>
</dt>
<dd>
<input type="text" id="ovh_password" name="notification[ovh][password]" value="<?php
echo htmlspecialchars($form_values["notification"]["ovh"]["password"]);
?>" />
<?php if (isset($errors["notification"]["ovh"]["password"])) : ?>
<p class="error"><?php echo $errors["notification"]["ovh"]["password"]; ?></p>
<?php endif; ?>
</dd>
<dt>
<label for="ovh_from">Expéditeur</label>
</dt>
<dd>
<input type="text" id="ovh_from" name="notification[ovh][from]" value="<?php
echo htmlspecialchars($form_values["notification"]["ovh"]["from"]);
?>" />
<?php if (isset($errors["notification"]["ovh"]["from"])) : ?>
<p class="error"><?php echo $errors["notification"]["ovh"]["from"]; ?></p>
<?php endif; ?>
</dd>
<dt>
<label for="ovh_to">Destinataire</label>
</dt>
<dd>
<input type="text" id="ovh_to" name="notification[ovh][to]" value="<?php
echo htmlspecialchars($form_values["notification"]["ovh"]["to"]);
?>" placeholder="Forme international (Ex: +33605040301)" />
<?php if (isset($errors["notification"]["ovh"]["to"])) : ?>
<p class="error"><?php echo $errors["notification"]["ovh"]["to"]; ?></p>
<?php endif; ?>
</dd>
<dt style="border: none;">
<input type="submit" name="testOvh" value="Effectuer un test d'envoi SMS" />
</dt>
<?php if (empty($errors) && !empty($_POST["testOvh"])) : ?>
<dd>
<?php if (isset($errorsTest["ovh"])) : ?>
<p style="font-weight: bold; color: #AB0000;"><?php
echo htmlspecialchars($errorsTest["ovh"]);
?></p>
<?php else: ?>
<p style="font-weight: bold; color: #333399;">Vous devriez recevoir un SMS contenant le message suivant:
« La notification SMS est fonctionnelle ».</p>
<p style="font-weight: bold; color: #339933;">Pensez à confirmer la configuration en cliquant sur "Enregistrer".</p>
<?php endif; ?>
</dd>
<?php endif; ?>
</dl>
<h2 id="configNotifyMyAndroid" class="formbox">Configuration alerte via NotifyMyAndroid</h2>
<dl id="configNotifyMyAndroid-content" style="display: <?php echo !empty($form_values["notification"]["notifymyandroid"]["token"]) ? "block" : "none"; ?>;">
<dt>
<label for="notifymyandroid_token">Clé du service</label>
</dt>
<dd>
<input type="text" id="notifymyandroid_token" name="notification[notifymyandroid][token]" value="<?php
echo htmlspecialchars($form_values["notification"]["notifymyandroid"]["token"]);
?>" />
<?php if (isset($errors["notification"]["notifymyandroid"]["token"])) : ?>
<p class="error"><?php echo $errors["notification"]["notifymyandroid"]["token"]; ?></p>
<?php endif; ?>
</dd>
<dt style="border: none;">
<input type="submit" name="testNotifyMyAndroid" value="Effectuer un test d'envoi de message" />
</dt>
<?php if (empty($errors) && !empty($_POST["testNotifyMyAndroid"])) : ?>
<dd>
<?php if (isset($errorsTest["notifymyandroid"])) : ?>
<p style="font-weight: bold; color: #AB0000;"><?php
echo htmlspecialchars($errorsTest["notifymyandroid"]);
?></p>
<?php else: ?>
<p style="font-weight: bold; color: #333399;">Vous devriez recevoir une notification contenant le message suivant:
« La notification NotifyMyAndroid est fonctionnelle ».</p>
<p style="font-weight: bold; color: #339933;">Pensez à confirmer la configuration en cliquant sur "Enregistrer".</p>
<?php endif; ?>
</dd>
<?php endif; ?>
</dl>
<h2 id="configPushover" class="formbox">Configuration alerte via Pushover</h2>
<dl id="configPushover-content" style="display: <?php echo !empty($form_values["notification"]["pushover"]["token"]) ? "block" : "none"; ?>;">
<dt>
<label for="pushover_token">Clé application</label>
</dt>
<dd>
<input type="text" id="pushover_token" name="notification[pushover][token]" value="<?php
echo htmlspecialchars($form_values["notification"]["pushover"]["token"]);
?>" />
<?php if (isset($errors["notification"]["pushover"]["token"])) : ?>
<p class="error"><?php echo $errors["notification"]["pushover"]["token"]; ?></p>
<?php endif; ?>
</dd>
<dt>
<label for="pushover_token">Clé utilisateur</label>
</dt>
<dd>
<input type="text" id="pushover_token" name="notification[pushover][user_key]" value="<?php
echo htmlspecialchars($form_values["notification"]["pushover"]["user_key"]);
?>" />
<?php if (isset($errors["notification"]["pushover"]["user_key"])) : ?>
<p class="error"><?php echo $errors["notification"]["pushover"]["user_key"]; ?></p>
<?php endif; ?>
</dd>
<dt style="border: none;">
<input type="submit" name="testPushover" value="Effectuer un test d'envoi de message" />
</dt>
<?php if (empty($errors) && !empty($_POST["testPushover"])) : ?>
<dd>
<?php if (isset($errorsTest["pushover"])) : ?>
<p style="font-weight: bold; color: #AB0000;"><?php
echo htmlspecialchars($errorsTest["pushover"]);
?></p>
<?php else: ?>
<p style="font-weight: bold; color: #333399;">Vous devriez recevoir une notification contenant le message suivant:
« La notification Pushover est fonctionnelle ».</p>
<p style="font-weight: bold; color: #339933;">Pensez à confirmer la configuration en cliquant sur "Enregistrer".</p>
<?php endif; ?>
</dd>
<?php endif; ?>
</dl>
<p><input type="submit" value="Enregistrer" />
| <a href="?mod=user&amp;a=settings">annuler les modifications</a></p>
</form>