Scout24 / restapi-php-sdk

SDK für PHP-Entwickler um die Arbeit mit der API von ImmobilienScout24 zu vereinfachen. Über die API erhält man Ergebnislisten, Objektdaten, uvm. von ImmobilienScout und kann diese Daten inhherhalb seines Webservice integrieren. Die Dokumentation zum SDK findet man unter https://github.com/Immocaster/php-sdk/wiki.
64 stars 46 forks source link

Korrekturen in Rest.php #24

Closed huschi-jan closed 8 years ago

huschi-jan commented 9 years ago

Da es hier gerade so munter weiter geht, hier eine Kleinigkeit von mir:

In _getExpose($aArgs) wird username mit '' belegt. Überall sonst wird $aArgs['username'] = $this->_sDefaultUsername; genutzt.

In der __call() findet sich ein array_change_key_case($args[0],CASE_LOWER) welches alle Parameter-Namen in Kleinbuchstaben umsetzt. Das ist aber falsch. Denn es gibt Parameter mit Großbuchstaben. Und IS24 ist anscheinend Casesensitiv. Aufgefallen ist es mir beim Export von Attachments (_exportObjectAttachment()) bei den Parametern "titlePicture" und das für mich wichtige "externalId".

Ansonsten: Vielen Dank für die Arbeit. Half mir recht viel.

fmielke commented 9 years ago

Hallo huschi-jan,

in der Funktion getExpose braucht man gar keinen Username, deswegen wird der dort demnächst verschwinden.

Ja, die Schemavalidierung, gegen welche der Request läuft, ist case sensitive. Dein erwähntes Problem kommt aber gar nicht erst bis dahin, da die Variablen innerhalb des SDKs nicht korrekt übergeben werden. IN: titlePicture -> __call -> OUT: titlepicture.

Werde ich beides demnächst fixen. Danke dir fürs Feedback!

huschi-jan commented 9 years ago

Leider sehe ich gerade, dass im letzten Update die __call() in der Rest.php nicht überarbeitet wurde. Wie oben geschrieben reicht es schon wenn man den array_change_key_case() weg lässt. Dann werden alle Parameter korrekt durch gereicht.

Nochmal was anderes, denn bei OpenSource sollte man auch mal was zurück geben. Hier die Abwandlung der Rest.php um mit der _exportObjectAttachment() auch Links zu exportieren. Als Aufruf werden 3 Parameter im aArgs benötigt: 'type'=>'Link', 'title'=>'Dies ist ein Link', 'url'=>http://www,dies-ist-ein-link.de/' Die Übertragung von 'type'=>'Picture' funktioniert parallel weiter wie bisher.

    private function _exportObjectAttachment($aArgs)
    {
        $aRequired = array('username','estateid');
        if($aArgs['type'] == 'Picture') $aRequired[] = 'file';
        if($aArgs['type'] == 'Link') $aRequired[] = 'url';
        if(!isset($aArgs['username']))
        {
            $aArgs['username'] = $this->_sDefaultUsername;
        }
        if(!isset($aArgs['title'])){ $aArgs['title'] = ''; }
        if(!isset($aArgs['floorplan'])){ $aArgs['floorplan'] = 'false'; }
        if(!isset($aArgs['titlePicture'])){ $aArgs['titlePicture'] = 'false'; }
        if(!isset($aArgs['type'])){ $aArgs['type'] = 'Picture'; }
        if(!isset($aArgs['externalId'])){ $aArgs['externalId'] = ''; }
        $oToken = null;
        $sSecret = null;
        $aHeader = array();
        list($oToken, $sSecret) = $this->getApplicationTokenAndSecret($aArgs['username']);
        if($oToken === NULL || $sSecret === NULL)
        {
            return IMMOCASTER_SDK_LANG_APPLICATION_NOT_CERTIFIED;
        }
        if(($aArgs['type'] == 'Picture') && !is_file($aArgs['file']))
        {
            return sprintf(IMMOCASTER_SDK_LANG_FILE_NOT_FOUND,$aArgs['file']);
        }
        if($aArgs['type'] == 'Picture') {
            $sMimeBoundary = md5(time());
            $aArgs['request_body'] = parent::createAttachmentBody($sMimeBoundary,$aArgs);
            $aHeader = array(
                'Content-Type'=>'multipart/form-data; boundary="'.$sMimeBoundary.'"',
                'Accept-Encoding' => 'gzip,deflate'
            );
        } else 
        if($aArgs['type'] == 'Link') {
            $aArgs['request_body'] = '<?xml version="1.0" encoding="UTF-8"?>'."\r\n"
                                    .'<common:attachment xsi:type="common:Link" xmlns:common="http://rest.immobilienscout24.de/schema/common/1.0" xmlns:ns3="http://rest.immobilienscout24.de/schema/platform/gis/1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'."\r\n"
                                        .'<title>'.$aArgs['title'].'</title>'."\r\n"
                                        .((isset($aArgs['externalId']) && (strlen($aArgs['externalId']) > 0)) ? '<externalId>'.$aArgs['externalId'].'</externalId>'."\r\n" : '')
                                        .'<url>'.$aArgs['url'].'</url>'."\r\n"
                                    .'</common:attachment>'."\r\n";
        }
        $req = $this->doRequest(
            'offer/v1.0/user/'.$aArgs['username'].'/realestate/'.$aArgs['estateid'].'/attachment',
            $aArgs,
            $aRequired,
            __FUNCTION__,
            $oToken,
            'POST'
        );
        $req->unset_parameter('title');
        $req->unset_parameter('floorplan');
        $req->unset_parameter('titlePicture');
        $req->unset_parameter('estateid');
        $req->unset_parameter('username');
        $req->unset_parameter('file');
        $req->unset_parameter('url');
        $req->unset_parameter('type');
        $req->unset_parameter('externalId');
        return parent::getContent(
            $req,
            $sSecret,
            $aHeader
        );
fmielke commented 9 years ago

Sehr cool! Erstelle doch dazu ein Pull Request, dann kann ich "einfach" mergen.

Update auf die __call mache ich hoffentlich nächste Woche (ist ja Aufwand<0). Die Authentifizierung ohne DB wurde erstmal als wichtiger eingeschätzt.

fmielke commented 9 years ago

Entfernung 3-beinigem oAuth für Funktion getExpose entfernt und __call verbessert. Nun können auch große Buchstaben in Variablen übergeben werden. Danke, @huschi-jan !!!

See commit: d852055f7eb016f4f877b56d5700f091c8853a25

POST Attachment(URL) wird folgen. Werde dabei wahrscheinlich noch ein wenig umbauen. indem ich den Body wie bisher in der Immobilienscout.php zusammenbaue. Trotzdem sehr sehr hilfreich! Danke!

kaischi70 commented 9 years ago

Ich habe noch was, leider weiß ich nicht, wie ich ein pull-reuest erstelle ...

meines Erachtens nach fehlt die Funktion zum ändern eines Attachments, müsste so gehen:

/* * Anhang zu einem Objekt ändern. * (Hierfür müssen besondere Berechtigungen bei ImmobilienScout24 beantragt werden. * Bitte informieren Sie sich direkt bei IS24 darüber.) * @param array $aArgs * @return mixed */ private function _changeObjectAttachment($aArgs) { $aRequired = array('username','attachmentid','estateid'); if(!isset($aArgs['username'])) { $aArgs['username'] = $this->_sDefaultUsername; } if(!isset($aArgs['title'])){ $aArgs['title'] = ''; } if(!isset($aArgs['floorplan'])){ $aArgs['floorplan'] = 'false'; } if(!isset($aArgs['titlePicture'])){ $aArgs['titlePicture'] = 'false'; } $oToken = null; $sSecret = null; list($oToken, $sSecret) = $this->getApplicationTokenAndSecret($aArgs['username']); if($oToken === NULL || $sSecret === NULL) { return IMMOCASTER_SDK_LANG_APPLICATION_NOT_CERTIFIED; } $req = $this->doRequest( 'offer/v1.0/user/'.$aArgs['username'].'/realestate/'.$aArgs['estateid'].'/attachment/'.$aArgs['attachmentid'], $aArgs, $aRequired, FUNCTION, $oToken, 'PUT' ); $req->unset_parameter('attachmentid'); $req->unset_parameter('estateid'); $req->unset_parameter('username'); $req->unset_parameter('title'); $req->unset_parameter('floorplan'); $req->unset_parameter('titlePicture'); return parent::getContent($req,$sSecret); }

kaischi70 commented 9 years ago

Tja, das scheint doch nicht zu klappen:

ERROR_COMMON_BAD_REQUEST<\/messageCode> Invalid HTTP request (check URL or body content).<\/message> Wird das doch nicht unterstützt? Laut API schon ...
fmielke commented 9 years ago

Danke für den Hinweis!

Konnte soeben mal kurz drüber schauen. Wo wird denn der Body des Requests zusammengebaut?

kaischi70 commented 9 years ago

Also, ich rufe das Ganze so auf: $estateid = $_POST['estateid']; $objekt_id = $_POST['objekt_id']; $attachmentid = $_POST['attachmentid']; $title = $_POST['title']; $floorplan = $_POST['floorplan']; $titlePicture = $_POST['titlePicture'];

$aParameter = array( 'username' => $my_user_id, 'title' => $title, 'floorplan' => $floorplan, 'titlePicture' => $titlePicture, 'estateid' => $estateid, 'attachmentid' => $attachmentid );

$result = $oImmocaster->changeObjectAttachment($aParameter);

Das php Programm wird praktisch mit den gleichen Daten angesprochen, wie beim post, insofern würde ich einen Fehler bei den gelieferten Werten mal ausschließen!?

changeObjectAttachment habe ich so, wie oben gepostet, eingebaut ...

kaischi70 commented 9 years ago

die Order der Attachments kann man mit dem SDK auch nicht ändern, oder? Mein Workaround ist nämlich im Moment, den zu ändernden Anhang zu löschen und wieder hochzuspielen. Was bei Bildern dann zumindest in einer falschen Reihenfolge resultiert.

fmielke commented 9 years ago

Nein, in deinem neuen changeObjectAttachmentRequest wird anscheinend kein Body erstellt. Das funktioniert bisher beim create* mit der createAttachmentBody Funktion. Du könnteste diese modifizieren, eine neue erstellen oder den Body direkt in deiner change* Funktion erstellen lassen.

GET/PUT Attachmentsorder müssen wir noch nachziehen, richtig. Löschen und Hinzufügen von Bildern belastet unnötig unsere Server.

MfG Fabian

kaischi70 commented 9 years ago

Ah, ich hatte die delete kopiert und angepasst ... doof.

ich schau es noch mal an, danke schon mal

kaischi70 commented 9 years ago

Hab's nun so:

/**
     * Anhang zu einem Objekt ändern.
     * (Hierfür müssen besondere Berechtigungen bei ImmobilienScout24 beantragt werden.
     * Bitte informieren Sie sich direkt bei IS24 darüber.)
     *
     * @param array $aArgs
     * @return mixed
     */
    private function _changeObjectAttachment($aArgs)
    {
        $aRequired = array('username','attachmentid','estateid');
        if(!isset($aArgs['username']))
        {
            $aArgs['username'] = $this->_sDefaultUsername;
        }
        if(!isset($aArgs['title'])){ $aArgs['title'] = ''; }
        if(!isset($aArgs['floorplan'])){ $aArgs['floorplan'] = 'false'; }
        if(!isset($aArgs['titlePicture'])){ $aArgs['titlePicture'] = 'false'; }
        if(!isset($aArgs['type'])){ $aArgs['type'] = 'Picture'; }
        $oToken = null;
        $sSecret = null;
        list($oToken, $sSecret) = $this->getApplicationTokenAndSecret($aArgs['username']);
        if($oToken === NULL || $sSecret === NULL)
        {
            return IMMOCASTER_SDK_LANG_APPLICATION_NOT_CERTIFIED;
        }

        $sBreak = "\r\n";
        $sBody .= '<common:attachment xsi:type="common:' . $aArgs['type'] . '" id="' . $aArgs['attachmentid'] . '" xmlns:common="http://rest.immobilienscout24.de/schema/common/1.0" ';
        $sBody .= 'xmlns:ns3="http://rest.immobilienscout24.de/schema/platform/gis/1.0" xmlns:xlink="http://www.w3.org/1999/xlink" ';
        $sBody .= 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . $sBreak;
        $sBody .= '<title>'.$aArgs['title'].'</title>' . $sBreak;
        $sBody .= '<floorplan>'.$aArgs['floorplan'].'</floorplan>' . $sBreak;
        if( $aArgs['type']==='Picture' ) {
            $sBody .= '<titlePicture>'.$aArgs['titlePicture'].'</titlePicture>' . $sBreak;
        }
        $sBody .= '</common:attachment>' . $sBreak;

        $aArgs['request_body'] = $sBody;
        $req = $this->doRequest('offer/v1.0/user/'.$aArgs['username'].'/realestate/'.$aArgs['estateid'].'/attachment/'.$aArgs['attachmentid'],$aArgs,$aRequired,__FUNCTION__,$oToken,'PUT');
        $req->unset_parameter('attachmentid');
        $req->unset_parameter('estateid');
        $req->unset_parameter('username');
        $req->unset_parameter('title');
        $req->unset_parameter('floorplan');
        $req->unset_parameter('titlePicture');
        $req->unset_parameter('type');
        return parent::getContent($req,$sSecret);
    }
kaischi70 commented 9 years ago

Noch mal ein update für die anderen Attachment-Typen. In der API-Doku werden bei den anderen Typen als Picture keine IDs übergeben, ist das richtig?

/**
     * Anhang zu einem Objekt ändern.
     * (Hierfür müssen besondere Berechtigungen bei ImmobilienScout24 beantragt werden.
     * Bitte informieren Sie sich direkt bei IS24 darüber.)
     *
     * @param array $aArgs
     * @return mixed
     */
    private function _changeObjectAttachment($aArgs)
    {
        $aRequired = array('username','attachmentid','estateid');
        if(!isset($aArgs['username']))
        {
            $aArgs['username'] = $this->_sDefaultUsername;
        }
        if(!isset($aArgs['title'])){ $aArgs['title'] = ''; }
        if(!isset($aArgs['floorplan'])){ $aArgs['floorplan'] = 'false'; }
        if(!isset($aArgs['titlePicture'])){ $aArgs['titlePicture'] = 'false'; }
        if(!isset($aArgs['type'])){ $aArgs['type'] = 'Picture'; }
        $oToken = null;
        $sSecret = null;
        list($oToken, $sSecret) = $this->getApplicationTokenAndSecret($aArgs['username']);
        if($oToken === NULL || $sSecret === NULL)
        {
            return IMMOCASTER_SDK_LANG_APPLICATION_NOT_CERTIFIED;
        }

        $if( $aArgs['type']==='StreamingVideo' ) {
            $sBody .= '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . $sBreak;
        }
        $sBody .= '<common:attachment xsi:type="common:' . $aArgs['type'] . '" id="' . $aArgs['attachmentid'] . '" xmlns:common="http://rest.immobilienscout24.de/schema/common/1.0" ';
        $sBody .= 'xmlns:ns3="http://rest.immobilienscout24.de/schema/platform/gis/1.0" xmlns:xlink="http://www.w3.org/1999/xlink" ';
        $sBody .= 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . $sBreak;
        $sBody .= '<title>'.$aArgs['title'].'</title>' . $sBreak;
        if( $aArgs['type']==='Picture' or $aArgs['type']==='PDFDocument' ) {
            $sBody .= '<floorplan>'.$aArgs['floorplan'].'</floorplan>' . $sBreak;
        }
        if( $aArgs['type']==='Picture' ) {
            $sBody .= '<titlePicture>'.$aArgs['titlePicture'].'</titlePicture>' . $sBreak;
        }
        if( $aArgs['type']==='Link' ) {
            $sBody .= '<url>'.$aArgs['url'].'</url>' . $sBreak;
        }
        $sBody .= '</common:attachment>' . $sBreak;

        $aArgs['request_body'] = $sBody;
        $req = $this->doRequest('offer/v1.0/user/'.$aArgs['username'].'/realestate/'.$aArgs['estateid'].'/attachment/'.$aArgs['attachmentid'],$aArgs,$aRequired,__FUNCTION__,$oToken,'PUT');
        $req->unset_parameter('attachmentid');
        $req->unset_parameter('estateid');
        $req->unset_parameter('username');
        $req->unset_parameter('title');
        $req->unset_parameter('floorplan');
        $req->unset_parameter('titlePicture');
        $req->unset_parameter('type');
        return parent::getContent($req,$sSecret);
    }
fmielke commented 9 years ago

Alle Attachments können eine externalId haben. Das muss beim create und update von allen Attachments noch nachgezogen werden, richtig. Bisher können im SDK nur Bilder eine externalId besitzen.

kaischi70 commented 9 years ago

Das meinte ich nicht. Im XML-Body gibt man oben die is24-Attachment-Id an. In der Doku ist die aber NUR bei den Bildern drin. Ich habe bei mir aber für alle

Wie sieht es mit der oben bearbeiteten exportObjectAttachment Funktion aus? Dort wurde ja der Link als Attachment mit eingebaut. Was dort noch fehlt, ist „PDFDocument“ als type, wenn man ein File mitgibt. Wenn man das so nutzt, klappt es nicht.

Wie gesagt, das mit den Pull-Requests habe ich nicht verstanden, sonst würde ich es dort einstellen ;-)

Gruß Kai

fmielke commented 9 years ago

Hallo Kai,

jedes Attachment hat eine ID, richtig. Unter Angabe des RealestateID und AttachmentID als Path Parameter spricht man den speziellen Anhang an. Wo ist das in der Doku falsch beschrieben?

Genau, und Video dürfte auch fehlen. Generell ist das SDK momentan nur auf Attachment (Picture) ausgelegt und muss um URL, PDF und StreamingVideo erweitert werden.

Schau mal, der Body von PUT Attachment ist bei allen Medien fast gleich: http://api.immobilienscout24.de/our-apis/import-export/attachments/put-by-id.html. Title und externalId (fehlt in Doku) haben sie alle. Je nach Typ kommen dann ein, zwei Felder hinzu.

MfG Fabian

kaischi70 commented 9 years ago

Du hast natürlich recht, die id wird ja in der url mitgegeben ... ich habe mich hiervon ablenken lassen: <common:attachment xsi:type="common:Picture" id="695671604" ...

kaischi70 commented 9 years ago

Angepasste Version der Export-Funktion mit Link, Image und PDF. Streaming Video habe ich jetzt nicht drin, weil ich es nicht brauche ...

private function _exportObjectAttachment($aArgs)
    {
        $aRequired = array('username','estateid');
        if($aArgs['type'] == 'Picture' or $aArgs['type'] == 'PDFDocument') $aRequired[] = 'file';
        if($aArgs['type'] == 'Link') $aRequired[] = 'url';
        if(!isset($aArgs['username']))
        {
            $aArgs['username'] = $this->_sDefaultUsername;
        }
        if(!isset($aArgs['title'])){ $aArgs['title'] = ''; }
        if(!isset($aArgs['floorplan'])){ $aArgs['floorplan'] = 'false'; }
        if(!isset($aArgs['titlePicture'])){ $aArgs['titlePicture'] = 'false'; }
        if(!isset($aArgs['type'])){ $aArgs['type'] = 'Picture'; }
        if(!isset($aArgs['externalId'])){ $aArgs['externalId'] = ''; }
        $oToken = null;
        $sSecret = null;
        $aHeader = array();
        list($oToken, $sSecret) = $this->getApplicationTokenAndSecret($aArgs['username']);
        if($oToken === NULL || $sSecret === NULL)
        {
            return IMMOCASTER_SDK_LANG_APPLICATION_NOT_CERTIFIED;
        }
        if(($aArgs['type'] == 'Picture' or $aArgs['type'] == 'PDFDocument') && !is_file($aArgs['file']))
        {
            return sprintf(IMMOCASTER_SDK_LANG_FILE_NOT_FOUND,$aArgs['file']);
        }
        if($aArgs['type'] == 'Picture' or $aArgs['type'] == 'PDFDocument') {
            $sMimeBoundary = md5(time());
            $aArgs['request_body'] = parent::createAttachmentBody($sMimeBoundary,$aArgs);
            $aHeader = array(
                'Content-Type'=>'multipart/form-data; boundary="'.$sMimeBoundary.'"',
                'Accept-Encoding' => 'gzip,deflate'
            );
        } else 
        if($aArgs['type'] == 'Link') {
            $aArgs['request_body'] = '<?xml version="1.0" encoding="UTF-8"?>'."\r\n"
                                    .'<common:attachment xsi:type="common:Link" xmlns:common="http://rest.immobilienscout24.de/schema/common/1.0" xmlns:ns3="http://rest.immobilienscout24.de/schema/platform/gis/1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'."\r\n"
                                        .'<title>'.$aArgs['title'].'</title>'."\r\n"
                                        .((isset($aArgs['externalId']) && (strlen($aArgs['externalId']) > 0)) ? '<externalId>'.$aArgs['externalId'].'</externalId>'."\r\n" : '')
                                        .'<url>'.$aArgs['url'].'</url>'."\r\n"
                                    .'</common:attachment>'."\r\n";
        }
        $req = $this->doRequest(
            'offer/v1.0/user/'.$aArgs['username'].'/realestate/'.$aArgs['estateid'].'/attachment',
            $aArgs,
            $aRequired,
            __FUNCTION__,
            $oToken,
            'POST'
        );
        $req->unset_parameter('title');
        $req->unset_parameter('floorplan');
        $req->unset_parameter('titlePicture');
        $req->unset_parameter('estateid');
        $req->unset_parameter('username');
        $req->unset_parameter('file');
        $req->unset_parameter('url');
        $req->unset_parameter('type');
        $req->unset_parameter('externalId');
        return parent::getContent(
            $req,
            $sSecret,
            $aHeader
        );
    }
fmielke commented 9 years ago

Super! Danke dir für die Veröffentlichung des Codes! Ich werde zeitnah einen Code Review machen und den Teil veröffentlichen!

kaischi70 commented 9 years ago

Ich Teste auch alles noch mal durch ... Sah bisher aber gut aus