Site icon Game And Me

Gestionnaire d’annonces PHP – osClass

Mise à jour du 30/05/2016: réécriture pour le site le bon coin.

Comme le décrivent les concepteurs: osClass est aux petites annonces ce que WordPress est aux CMS; et c’est vrai !

osClass permet de définir des champs spécifiques en fonction des catégories. Il permet de faire des recherches par filtre, et est vraiment très simple d’utilisation.
En plus, le thème par défaut n’est pas trop mal et fonctionne parfaitement sur tablette.
Une liste de plugins/thèmes existe déjà, et vous pouvez adapter votre site à vos besoins spécifiques (gestion de CV, sites matrimoniaux…)
Personnellemment, j’ai installé un osClass pour gérer des annonces immobilières.

Dans un premier temps, me femme et moi recherchions un logement. Nous nous en sommes donc servi pour rassembler nos recherches, les partager à nos proches (pour rechercher les adresses via Google Map et éviter de payer les frais démesurés de ces P### d’agences), se souvenir des photos, comparer, etc.
Mais c’est devenu rapidement galère de devoir tout recopier d’un site à l’autre, et les doublons se généraient trop souvent.

Nos sites d’annonces immobilières préférés étant leboncoin, seloger, ou encore ouestfrance-immo.
J’ai donc développé une page qui duplique l’annonce et l’envoie directement dans osClass. C’est peut être pas du super niveau de dév, mais ca fonctionne, c ‘est paramétrable sur chaque site via Xpath, et ca ne m’as pas pris 3 heures pour comprendre le framework d’origine.

Voici un petit aperçu du résultat.

Créer d’abord 2 catégories maison et appart (notez les identifiants qu’il faudra replacer dans le fichier jsimport.php).

Puis modifier le fichier oc-includes/osclass/ItemActions.php ligne 206 pour ajouter ça

global $itemId;

Créér maintenant le fichier jsimport.php à la racine avec ce code.

<?php
/*
Import automatique d'annonce depuis une url
*/
 
define("CAT_MAISON","96");
define("CAT_APPART","97");
define ("LECONTACT","toto");
define ("LEMAIL","toto@toto.fr");
 
 
 define('ABS_PATH', str_replace('\\', '/', dirname($_SERVER['SCRIPT_FILENAME']) . '/'));
 if(PHP_SAPI==='cli') {
 define('CLI', true);
 }
 
 require_once ABS_PATH . 'oc-load.php';
 
 if( CLI ) {
 $cli_params = getopt('p:t:');
 Params::setParam('page', $cli_params['p']);
 Params::setParam('cron-type', $cli_params['t']);
 if(Params::getParam('page')=='upgrade') {
 require_once(osc_lib_path() . 'osclass/upgrade-funcs.php');
 exit(1);
 } else if( !in_array(Params::getParam('page'), array('cron')) && !in_array(Params::getParam('cron-type'), array('hourly', 'daily', 'weekly')) ) {
 exit(1);
 }
 }
 
 if( file_exists(ABS_PATH . '.maintenance') ) {
 if(!osc_is_admin_user_logged_in()) {
 
 header('HTTP/1.1 503 Service Temporarily Unavailable');
 header('Status: 503 Service Temporarily Unavailable');
 header('Retry-After: 900');
 
 if(file_exists(WebThemes::newInstance()->getCurrentThemePath().'maintenance.php')) {
 osc_current_web_theme_path('maintenance.php');
 die();
 } else {
 require_once LIB_PATH . 'osclass/helpers/hErrors.php';
 
 $title = sprintf(__('Maintenance &raquo; %s'), osc_page_title());
 $message = sprintf(__('We are sorry for any inconvenience. %s is undergoing maintenance.') . '.', osc_page_title() );
 osc_die($title, $message);
 }
 } else {
 define('__OSC_MAINTENANCE__', true);
 }
 }
 
 if(!osc_users_enabled() && osc_is_web_user_logged_in()) {
 Session::newInstance()->_drop('userId');
 Session::newInstance()->_drop('userName');
 Session::newInstance()->_drop('userEmail');
 Session::newInstance()->_drop('userPhone');
 
 Cookie::newInstance()->pop('oc_userId');
 Cookie::newInstance()->pop('oc_userSecret');
 Cookie::newInstance()->set();
 }
 
 if(osc_is_web_user_logged_in()) {
 User::newInstance()->lastAccess(osc_logged_user_id(), date('Y-m-d H:i:s'), $_SERVER['REMOTE_ADDR'], 3600);
 }
 
 switch( Params::getParam('page') )
 {
 case ('cron'): // cron system
 define('__FROM_CRON__', true);
 require_once(osc_lib_path() . 'osclass/cron.php');
 break;
 case ('user'): // user pages (with security)
 if(Params::getParam('action')=='change_email_confirm' || Params::getParam('action')=='activate_alert'
 || (Params::getParam('action')=='unsub_alert' && !osc_is_web_user_logged_in())
 || Params::getParam('action')=='contact_post'
 || Params::getParam('action')=='pub_profile') {
 require_once(osc_lib_path() . 'osclass/controller/user-non-secure.php');
 $do = new CWebUserNonSecure();
 $do->doModel();
 } else {
 require_once(osc_lib_path() . 'osclass/controller/user.php');
 $do = new CWebUser();
 $do->doModel();
 }
 break;
 case ('item'): // item pages
 require_once(osc_lib_path() . 'osclass/controller/item.php');
 $do = new CWebItem();
 $do->doModel();
 break;
 case ('search'): // search pages
 require_once(osc_lib_path() . 'osclass/controller/search.php');
 $do = new CWebSearch();
 $do->doModel();
 break;
 case ('page'): // static pages
 require_once(osc_lib_path() . 'osclass/controller/page.php');
 $do = new CWebPage();
 $do->doModel();
 break;
 case ('register'): // register page
 require_once(osc_lib_path() . 'osclass/controller/register.php');
 $do = new CWebRegister();
 $do->doModel();
 break;
 case ('ajax'): // ajax
 require_once(osc_lib_path() . 'osclass/controller/ajax.php');
 $do = new CWebAjax();
 $do->doModel();
 break;
 case ('login'): // login page
 require_once(osc_lib_path() . 'osclass/controller/login.php');
 $do = new CWebLogin();
 $do->doModel();
 break;
 case ('language'): // set language
 require_once(osc_lib_path() . 'osclass/controller/language.php');
 $do = new CWebLanguage();
 $do->doModel();
 break;
 case ('contact'): //contact
 require_once(osc_lib_path() . 'osclass/controller/contact.php');
 $do = new CWebContact();
 $do->doModel();
 break;
 case ('custom'): //contact
 require_once(osc_lib_path() . 'osclass/controller/custom.php');
 $do = new CWebCustom();
 $do->doModel();
 break;
 default: // home and static pages that are mandatory...
 require_once(osc_lib_path() . 'osclass/controller/main.php');
 $do = new CWebMain();
 //$do->doModel();
 break;
 }
 
 if(!defined('__FROM_CRON__')) {
 if( osc_auto_cron() ) {
 osc_doRequest(osc_base_url(), array('page' => 'cron'));
 }
 }
 
 
 
 
 if (isset($_GET["url"])){
 $mItem = new ItemActions(true); 
 $mItem->prepareData(true);
 set_time_limit(300);
 $mItem->data["contactName"] =LECONTACT;
 $mItem->data["currency"] = "EUR";
 $mItem->data["contactEmail"] = LEMAIL;
 $mItem->data["catId"] = CAT_MAISON;//Maison
 
 $tabSitesOk = array("www.leboncoin.fr","www.seloger.com","www.ouestfrance-immo.com","www.blot-immobilier.fr");
 $bSiteOk = false;
 foreach ($tabSitesOk as $sSite){
 if (strpos(strtolower($_GET["url"]),$sSite)!==false){
 $bSiteOk = true;
 }
 }
 
 if ($bSiteOk){
 
 //On verifie que le site est pas deja en base
 $oDB = new DB(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
 $sql = "SELECT count(*) as nb FROM oc_t_item_meta where s_value = '".$_GET["url"]."'";
 $iCount = $oDB->osc_dbFetchValue($sql);
 
 if ($iCount == 0){ 
 $sContenu = file_get_contents($_GET["url"]);
 
 //On convertit les sites qui sont en UTF-8
 if (strpos($_GET["url"],"www.seloger.com") !== false or strpos($_GET["url"],"www.ouestfrance-immo.com") !== false ){
 $sContenu = utf8_decode($sContenu);
 }
 
 if ($docXML = @DOMDocument::loadHTML(($sContenu))){
 $xpath = new DOMXPath($docXML);
 
 $tabPhotos = array();
 $tabPhotosType = array();
 $success = 0;
 if (strpos($_GET["url"],"www.leboncoin.fr") !== false){
 
 preg_match_all('/(.*)images_thumbs\[(.*)\] = \"(.*)\"; /',$sContenu,$tab, PREG_SET_ORDER);
 foreach ($tab as $o){
 $tabPhotosType[] = "jpg";
 $tabPhotos[] = str_replace("//","http://",str_replace("/thumbs","/images",$o[3]));
 }
 
 if (count($tabPhotos) == 0){
 $sXpath = "//div[@class='item_image big popin-open trackable']/img";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $tabPhotosType[] = "jpg";
 $tabPhotos[] = str_replace("//","http://",$oNode->getAttribute("src"));
 }
 }
 
 /* Ajout de l auteur si besoin */
 $sAuteur = "";
 $sXpath = "//aside[@role='complementary']/div/div[position()=1]/p";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sAuteur = " - " .trim($oNode->nodeValue);
 } 
 
 $sTitre = "";
 $sXpath = "//h1";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 //$mItem->data["title"] = array("fr_FR"=>trim($oNode->nodeValue . " " . $sAuteur));
 $mItem->data["title"] = array("fr_FR"=>trim($oNode->nodeValue));
 $sTitre = trim($oNode->nodeValue);
 }
 
 preg_match_all('/(.*)var zipcode = \\$\.trim\("(.*)"\)/',$sContenu,$out, PREG_SET_ORDER);
 $mItem->data["s_zip"] = trim($out[0][2]);
 preg_match_all('/(.*)var city = \\$\.trim\("(.*)"\)/',$sContenu,$out, PREG_SET_ORDER);
 $mItem->data["cityName"] = utf8_encode(trim($out[0][2]));

 
 $sDesc = "";
 $sXpath = "//p[@itemprop='description']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sDesc .= trim(strip_tags($oNode->nodeValue));
 }
 
 $sXpath = "//div[@class='lbcParams criterias']/*";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sDesc .= "\n".trim(strip_tags(str_replace("\n"," ",$oNode->nodeValue)));
 }
 $mItem->data["description"]=array("fr_FR"=>$sDesc);
 
 if (strpos(strtolower($sDesc),"appart") !== false or strpos(strtolower($sTitre),"appart") !== false){
 $mItem->data["catId"] = CAT_APPART;//Appart
 }
 
 $sXpath = "//h2[@itemprop='price']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $mItem->data["price"] = (int) str_replace(chr(0),"",str_replace(" ","",trim(str_replace("€","",$oNode->getAttribute("content"))))); 
 $mItem->data["price"] = $mItem->data["price"] * 1000000;
 }
 
 $success = $mItem->add();
 }
 
 
 if (strpos($_GET["url"],"http://www.ouestfrance-immo.com/") !== false){ 
 $sXpath = "//ul[@class='slides']/li/img";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sFile = trim($oNode->getAttribute("src"));
 $tabExt = explode(".",$sFile);
 $sExt = $tabExt[count($tabExt)-1];
 if ($sExt == "jpg"){
 $tabPhotos[] = $sFile;
 $tabPhotosType[] = $sExt;
 }
 } 
 
 $sTitre = "";
 $sXpath = "//h2[@id='caractDetail']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sTitre = str_replace("Caractéristiques","",str_replace("m²"," m2", str_replace("\n" , " ",trim($oNode->nodeValue))));
 while (strpos($sTitre," ")!==false){
 $sTitre = str_replace(" " , " ",$sTitre);
 }
 
 $mItem->data["title"] = array("fr_FR"=>$sTitre); 
 }
 
 $sXpath = "//h2[@class='detail-subtitle']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $s = trim($oNode->nodeValue);
 $tab = explode("à",$s);
 if (isset($tab[1])){
 $mItem->data["cityArea"] = trim($tab[1]);
 $mItem->data["cityName"] = trim($tab[1]);
 }
 } 
 
 $sDesc = "";
 $sXpath = "//div[@itemprop='description']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sDesc .= trim(strip_tags($oNode->nodeValue));
 }
 
 $sXpath = "//ul[@class='colGAnn']/li";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sDesc .= "\n".trim(strip_tags(str_replace("\n"," ",$oNode->nodeValue)));
 }
 $mItem->data["description"]=array("fr_FR"=>$sDesc);
 
 if (strpos(strtolower($sDesc),"appart") !== false or strpos(strtolower($sTitre),"appart") !== false){
 $mItem->data["catId"] = CAT_APPART;//Appart
 }
 
 $sXpath = "//strong[@itemprop='price']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $mItem->data["price"] = (int) str_replace(chr(0),"",str_replace(" ","",trim(str_replace("€","",$oNode->nodeValue)))); 
 $mItem->data["price"] = $mItem->data["price"] * 1000000;
 }
 
 $success = $mItem->add();
 }
 
 if (strpos($_GET["url"],"http://www.blot-immobilier.fr/") !== false){ 
 $sXpath = "//ul[@id='carousel_info']/li/ul/li/a";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) {
 $sFile = "http://www.blot-immobilier.fr/xx/".trim($oNode->getAttribute("href"));
 $tabExt = explode(".",$sFile);
 $sExt = $tabExt[count($tabExt)-1];
 if ($sExt == "jpg"){
 $tabPhotos[] = $sFile;
 $tabPhotosType[] = $sExt;
 }
 } 
 
 $sTitre = "";
 $sXpath = "//h1";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sTitre = str_replace("Caractéristiques","",str_replace("m²"," m2", str_replace("\n" , " ",trim($oNode->nodeValue))));
 while (strpos($sTitre," ")!==false){
 $sTitre = str_replace(" " , " ",$sTitre);
 }
 
 $mItem->data["title"] = array("fr_FR"=>$sTitre); 
 }
 
 $iPos = 0;
 $sXpath = "//div[@class='conteneur_valeur_crit']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $iPos++;
 $s = trim($oNode->nodeValue);
 if ($iPos == 3){
 $mItem->data["cityArea"] = $s;
 $mItem->data["cityName"] = $s;
 }
 if ($iPos == 4){
 $mItem->data["s_zip"] = trim($oNode->nodeValue);
 }
 } 
 
 $sXpath = "//div[@class='conteneur_valeur_crit' and position()=4]";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $mItem->data["s_zip"] = trim($oNode->nodeValue);
 } 
 
 $sDesc = "";
 $sXpath = "//div[@class='contenu_d4_desc']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sDesc .= trim(strip_tags($oNode->nodeValue));
 }
 
 $sXpath = "//div[@class='criteres_bien']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sDesc .= trim(strip_tags($oNode->nodeValue))." \n";
 } 
 
 $mItem->data["description"]=array("fr_FR"=>$sDesc);
 
 if (strpos(strtolower($sDesc),"appart") !== false or strpos(strtolower($sTitre),"appart") !== false){
 $mItem->data["catId"] = CAT_APPART;//Appart
 }
 
 $sXpath = "//div[@class='info_price']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $mItem->data["price"] = (int) str_replace("F.A.I.","",str_replace(" ","",trim(str_replace("€","",$oNode->nodeValue)))); 
 $mItem->data["price"] = $mItem->data["price"] * 1000000000;
 }
 
 $success = $mItem->add();
 }
 
 if (strpos($_GET["url"],"www.seloger.com") !== false){ 
 $sXpath = "//ul[@id='slider1']/li/img";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sFile = trim($oNode->getAttribute("src"));
 $tabExt = explode(".",$sFile);
 $sExt = $tabExt[count($tabExt)-1];
 
 $tabPhotos[] = $sFile;
 $tabPhotosType[] = $sExt;
 } 
 
 $sTitre = "";
 $sXpath = "//h1[@class='detail-title']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sTitre = str_replace("m²"," m2", str_replace("\n" , " ",trim($oNode->nodeValue)));
 while (strpos($sTitre," ")!==false){
 $sTitre = str_replace(" " , " ",$sTitre);
 }
 
 $mItem->data["title"] = array("fr_FR"=>$sTitre); 
 }
 
 $sXpath = "//h2[@class='detail-subtitle']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $s = trim($oNode->nodeValue);
 $tab = explode("à",$s);
 if (isset($tab[1])){
 $mItem->data["cityArea"] = trim($tab[1]);
 $mItem->data["cityName"] = trim($tab[1]);
 }
 } 
 
 $sDesc = "";
 $sXpath = "//p[@class='description']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sDesc .= trim(strip_tags($oNode->nodeValue));
 }
 
 $sXpath = "//ol[@class='description-liste']/li";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $sDesc .= "\n".trim(strip_tags(str_replace("\n"," ",$oNode->nodeValue)));
 }
 $mItem->data["description"]=array("fr_FR"=>$sDesc);
 
 if (strpos(strtolower($sDesc),"appart") !== false or strpos(strtolower($sTitre),"appart") !== false){
 $mItem->data["catId"] = CAT_APPART;//Appart
 }
 
 $sXpath = "//span[@id='price']";
 $lNodes = $xpath->query($sXpath); 
 foreach ($lNodes as $oNode) { 
 $mItem->data["price"] = (int) str_replace(chr(0),"",str_replace(" ","",trim(str_replace("€","",$oNode->nodeValue)))); 
 $mItem->data["price"] = $mItem->data["price"] * 1000000;
 }
 
 $success = $mItem->add();
 }
 
 
 if( $success==1 || $success==2 ) {
 //Ajout de l'url
 global $itemId;
 $sql = "UPDATE oc_t_item_meta SET s_value = '".$_GET["url"]."' where fk_i_item_id = ".$itemId." and fk_i_field_id=1";
 $oDB->osc_dbExec($sql);
 
 //Recup des photos
 $uid = uniqid();
 $sql = "SELECT MAX(pk_i_id) FROM oc_t_item_resource";
 $iMax = $oDB->osc_dbFetchValue($sql);
 
 if (!is_dir("oc-content/uploads/0/")){
 mkdir("oc-content/uploads/0/");
 } 
 
 $iPhoto = 0;
 foreach ($tabPhotos as $sPhoto){
 $iMax++;
 $sExt = strtolower($tabPhotosType[$iPhoto]);
 if ($tabPhotosType[$iPhoto] == "jpg"){
 $sExt = "jpeg";
 }
 
 $sql = "INSERT INTO oc_t_item_resource (pk_i_id,fk_i_item_id,s_name,s_extension,s_content_type,s_path) VALUES (".$iMax.",".$itemId.",'".uniqid()."','".$tabPhotosType[$iPhoto]."','image/".$sExt."','oc-content/uploads/0/')";
 $oDB->osc_dbExec($sql); 
 $s = file_get_contents($sPhoto);
 file_put_contents("oc-content/uploads/0/".$iMax,$s);
 
 
 // Create normal size
 $extension = $tabPhotosType[$iPhoto];
 $path = 'oc-content/uploads/0/';
 $tmpName = $path.$iMax;
 $normal_path = $path = $tmpName."_normal";
 $size = explode('x', osc_normal_dimensions());
 $img = ImageResizer::fromFile($tmpName)->autoRotate()->resizeTo($size[0], $size[1]); 
 $img->saveToFile($path, $extension);
 
 // Create preview
 $path = $tmpName."_preview";
 $size = explode('x', osc_preview_dimensions());
 ImageResizer::fromFile($normal_path)->resizeTo($size[0], $size[1])->saveToFile($path, $extension);
 
 // Create thumbnail
 $path = $tmpName."_thumbnail";
 $size = explode('x', osc_thumbnail_dimensions());
 ImageResizer::fromFile($normal_path)->resizeTo($size[0], $size[1])->saveToFile($path, $extension);
 
 $path = 'oc-content/uploads/0/';
 rename($path.$iMax,$path.$iMax.".".$extension);
 rename($path.$iMax."_normal",$path.$iMax."_normal.".$extension);
 rename($path.$iMax."_thumbnail",$path.$iMax."_thumbnail.".$extension);
 rename($path.$iMax."_preview",$path.$iMax."_preview.".$extension);
 
 $iPhoto++; 
 } 
 echo "<script type='text/javascript'>window.close();</script>";
 }else{
 echo "L'importation de cette annonce n'a pas fonctionnée correctement pour la raison suivante: ". $success; 
 }
 }
 }else{
 echo "Cette annonce est déjà en base.";
 echo "<script type='text/javascript'>window.close();</script>";
 }
 }else{
 echo "Ce site n'est pas pris en charge par cet outil";
 }
 }
 
 /* file end: ./index.php */
?>

Il vous suffit ensuite de rajouter un snippet dans votre barre de favoris avec ce code et de cliquer sur le lien sur la page de l’annonce pour qu’elle se duplique.

javascript:javascript:(function(){var url = location.href;var title = document.title || url;var my_window =window.open('http://localhost/osclass/jsimport.php?url='+url,'_blank','menubar=no,height=1200,width=1200,toolbar=no,scrollbars=no,status=no');})();

J’espère que ca vous aidera dans vos démarches.

+

Quitter la version mobile