2014-05-09 22 views
5

Ho una chiamata API. La chiamata restituisce il codice XML, lo converto in XML in un array e quindi utilizzo json_encode per inviare la risposta in una chiamata jsonp. Quello che sto facendo funziona, ma l'API non mi consente di filtrare in base a uno stato, di filtrare per ora di inizio e di fine e di verificare che la stanza sia disponibile.Array di filtri o XML con tempo tra l'inizio e l'ora di fine

Diventa pazzo con diverse chiamate jsponp. Ancora una volta, quello che ho sta funzionando, ma ho bisogno di capire un modo per filtrare ancora una volta con i miei risultati. Ho restituito lo stato corretto e la data corretta, ma devo ancora filtrare i tempi. Se l'ora è attualmente alle 10:29, non voglio mostrare le camere prenotate che iniziano alle 10:30 perché non è prenotata fino alle 10:30. Quindi, se il mio orario attuale è 10:29 ho bisogno di filtrare attraverso i miei eventi nel mio array e mostrare solo gli eventi che hanno un tempo di inizio e di fine che hanno l'ora corrente in mezzo.

Una prenotazione tra le 10 e le 11 dovrebbe rimanere nel mio array ma una prenotazione dalle 14.00 non dovrebbe essere mostrata nel mio array. Come ho già detto, l'array è prima un documento XML restituito, quindi un array, quindi JSON, quindi tecnicamente posso utilizzare qualsiasi cosa funzioni per filtrare. PHP per filtrare in XML, PHP per filtrare la matrice. Anche Javascript ammette che il file PHP è pronto per la mia chiamata ajax.

Ecco il mio array prima di trasformarlo in JSON e restituirlo. Le volte in cui filtro sono TimeEventStart e TimeEventEnd. Posso utilizzare l'ora corrente di Javascript o il tempo di funzione della data di PHP. Posso filtrare l'array o usare qualcosa come XMLPath per filtrare. Non sono sicuro di quale sia il più efficiente e funzionerebbe meglio.

$axml = Array{ 
    "Bookings":{ 
     "Data":[ 
     { 
      "BookingDate":[ 
       "2014-05-09T00:00:00" 
      ], 
      "RoomDescription":[ 
       "Room06" 
      ], 
      "TimeEventStart":[ 
       "2014-05-09T14:00:00" 
      ], 
      "TimeEventEnd":[ 
       "2014-05-09T14:30:00" 
      ], 
      "EventName":[ 
       "Jake Long" 
      ], 
      "SetupTypeDescription":[ 
       "(none)" 
      ], 
      "ReservationID":[ 
       "137" 
      ], 
      "OpenTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "CloseTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "EventTypeDescription":[ 
       [ 

       ] 
      ], 
      "BookingID":[ 
       "709" 
      ], 
      "TimeBookingStart":[ 
       "2014-05-09T14:00:00" 
      ], 
      "TimeBookingEnd":[ 
       "2014-05-09T14:30:00" 
      ], 
      "GMTStartTime":[ 
       "2014-05-09T18:00:00" 
      ], 
      "GMTEndTime":[ 
       "2014-05-09T18:30:00" 
      ], 
      "TimeZone":[ 
       "ET" 
      ], 
      "RoomCode":[ 
       "R06" 
      ], 
      "Room":[ 
       "Room 6" 
      ], 
      "RoomID":[ 
       "34" 
      ], 
      "StatusID":[ 
       "3" 
      ], 
      "EventTypeID":[ 
       "0" 
      ], 
      "DateAdded":[ 
       "2014-05-09T13:47:29.087" 
      ], 
      "DateChanged":[ 
       "2014-05-09T13:47:29.087" 
      ], 
      "ChangedBy":[ 
       "Admin" 
      ] 
     }, 
     { 
      "BookingDate":[ 
       "2014-05-09T00:00:00" 
      ], 
      "RoomDescription":[ 
       "Room06" 
      ], 
      "TimeEventStart":[ 
       "2014-05-09T18:00:00" 
      ], 
      "TimeEventEnd":[ 
       "2014-05-09T20:00:00" 
      ], 
      "EventName":[ 
       "Rob Brown" 
      ], 
      "SetupTypeDescription":[ 
       "(none)" 
      ], 
      "ReservationID":[ 
       "142" 
      ], 
      "OpenTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "CloseTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "EventTypeDescription":[ 
       [ 

       ] 
      ], 
      "BookingID":[ 
       "714" 
      ], 
      "TimeBookingStart":[ 
       "2014-05-09T18:00:00" 
      ], 
      "TimeBookingEnd":[ 
       "2014-05-09T20:00:00" 
      ], 
      "GMTStartTime":[ 
       "2014-05-09T22:00:00" 
      ], 
      "GMTEndTime":[ 
       "2014-05-10T00:00:00" 
      ], 
      "TimeZone":[ 
       "ET" 
      ], 
      "RoomCode":[ 
       "R06" 
      ], 
      "Room":[ 
       "Room 6" 
      ], 
      "RoomID":[ 
       "34" 
      ], 
      "StatusID":[ 
       "3" 
      ], 
      "EventTypeID":[ 
       "0" 
      ], 
      "DateAdded":[ 
       "2014-05-09T14:58:55.71" 
      ], 
      "DateChanged":[ 
       "2014-05-09T14:58:55.71" 
      ], 
      "ChangedBy":[ 
       "Admin" 
      ] 
     }, 
     { 
      "BookingDate":[ 
       "2014-05-09T00:00:00" 
      ], 
      "StartBookingDate":[ 
       "2014-05-09T00:00:00" 
      ], 
      "RoomDescription":[ 
       "Room06" 
      ], 
      "TimeEventStart":[ 
       "2014-05-09T11:00:00" 
      ], 
      "TimeEventEnd":[ 
       "2014-05-09T12:00:00" 
      ], 
      "EventName":[ 
       "Jimmy James" 
      ], 
      "SetupTypeDescription":[ 
       "(none)" 
      ], 
      "ReservationID":[ 
       "141" 
      ], 
      "OpenTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "CloseTime":[ 
       "1900-01-01T00:00:00" 
      ], 
      "EventTypeDescription":[ 
       [ 

       ] 
      ], 
      "BookingID":[ 
       "713" 
      ], 
      "TimeBookingStart":[ 
       "2014-05-09T11:00:00" 
      ], 
      "TimeBookingEnd":[ 
       "2014-05-09T12:00:00" 
      ], 
      "GMTStartTime":[ 
       "2014-05-09T15:00:00" 
      ], 
      "GMTEndTime":[ 
       "2014-05-09T16:00:00" 
      ], 
      "TimeZone":[ 
       "ET" 
      ], 
      "RoomCode":[ 
       "R06" 
      ], 
      "Room":[ 
       "Room 6" 
      ], 
      "RoomID":[ 
       "34" 
      ], 
      "StatusID":[ 
       "1" 
      ], 
      "EventTypeID":[ 
       "0" 
      ], 
      "DateAdded":[ 
       "2014-05-09T14:58:15.17" 
      ], 
      "DateChanged":[ 
       "2014-05-09T14:58:15.17" 
      ], 
      "ChangedBy":[ 
       "Admin" 
      ] 
     } 
     ] 
    } 
} 
; 

Il mio array viene restituito da una chiamata SOAP in XML. Mi è toccato il posteriore e XML usando

$sxml = simplexml_load_string($xml) 

Poi sto usando una funzione chiamata xmlToArray di metterlo nella matrice pubblicato.

$axml = xmlToArray($sxml); 

Ecco l'XML prima di convertirmi in un array e poi in JSON.

<?xml version="1.0" encoding="utf-8"?><Bookings> 
    <Data> 
    <BookingDate>2014-05-13T00:00:00</BookingDate> 
    <StartBookingDate>2014-05-13T00:00:00</StartBookingDate> 
    <RoomDescription>Room 06</RoomDescription> 
    <TimeEventStart>2014-05-13T10:00:00</TimeEventStart> 
    <TimeEventEnd>2014-05-13T10:30:00</TimeEventEnd> 
    <EventName>Jake Long</EventName> 
    <ReservationID>159</ReservationID> 
    <ClosedAllDay>false</ClosedAllDay> 
    <OpenTime>1900-01-01T00:00:00</OpenTime> 
    <CloseTime>1900-01-01T00:00:00</CloseTime> 
    <BookingID>731</BookingID> 
    <TimeBookingStart>2014-05-13T10:00:00</TimeBookingStart> 
    <TimeBookingEnd>2014-05-13T10:30:00</TimeBookingEnd> 
    <GMTStartTime>2014-05-13T14:00:00</GMTStartTime> 
    <GMTEndTime>2014-05-13T14:30:00</GMTEndTime> 
    <RoomCode>R09</RoomCode> 
    <Room>Room 9</Room> 
    <RoomID>37</RoomID> 
    <StatusID>3</StatusID> 
    <DateAdded>2014-05-13T08:38:22.36</DateAdded> 
    <DateChanged>2014-05-13T08:38:22.36</DateChanged> 
    </Data> 
</Bookings> 
+0

È possibile utilizzare Xpath per recuperare/filtrare nodi XML. – ThW

+0

È possibile fornire l'origine dati originale (XML). Convertirlo in un array significa perdere dati. – ThW

+0

Credo che la matrice sia buona. Ho eliminato alcuni elementi XML extra, non necessari. Rendere questo più difficile per me è che sono Eastern Time e il progetto deve essere Pacifico. Credo che la risposta fornita sia sulla buona strada, ho solo bisogno di avere il tempo corretto. – donlaur

risposta

4

Ok, quindi ho scritto alcune funzioni PHP, per filtrare ciò che richiedete.

Per confrontare le date in php è più semplice convertirle in ora Unix. Questo è ciò che fa la prima funzione. Unix time è il tempo trascorso in secondi dal 1 ° gennaio 1970. La loro conversione offre il vantaggio che è possibile utilizzare semplicemente < e> operatori per confrontare due volte.

La funzione successiva (nowBetween), guarda se l'ora corrente è compresa tra le due volte date ($ start e $ end).

Poi ho preso la tua stringa JSON (dato che non ho davvero visto la sorgente XML quando ho scritto questo post) e l'ho convertita in array PHP. Possiamo essere certi che siano array, poiché il secondo parametro in json_decode è impostato su true.

Ultimo ma non meno importante, eseguo il ciclo di tutte le prenotazioni nella sezione "dati" del tuo contenuto JSON, leggi i tempi GMTStart e GMTEnd e controlla se l'ora corrente è tra di loro utilizzando la nostra funzione. In caso contrario, rimuovo la prenotazione dall'array $ bookings.

Il risultato sono solo le prenotazioni con i tempi corretti. Il mio risultato ora era vuoto, ma è perché le tue prenotazioni risalgono al 2014-05-09 ... Quando ho adattato il tempo in cui ha funzionato.

Spero che questa risposta soddisfi le vostre esigenze.

function convertDateTime($datetime) { 
    //FORMAT IS date("YYYY-MM-DDThh:mm:ss") 
    $datetime = str_replace("T"," ",$datetime); 
    return date("U",strtotime($datetime)); 
} 
function nowBetween($start,$end) { 
    $now = gmdate("U"); 
    $start = convertDateTime($start); 
    $end = convertDateTime($end); 
    if ($start <= $now && $end > $now) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

$bookings = '{"Bookings":{"Data":[{"BookingDate":["2014-05-09T00:00:00"],"RoomDescription":["Room06"],"TimeEventStart":["2014-05-09T14:00:00"],"TimeEventEnd":["2014-05-09T14:30:00"],"EventName":["Jake Long"],"SetupTypeDescription":["(none)"],"ReservationID":["137"],"OpenTime":["1900-01-01T00:00:00"],"CloseTime":["1900-01-01T00:00:00"],"EventTypeDescription":[[]],"BookingID":["709"],"TimeBookingStart":["2014-05-09T14:00:00"],"TimeBookingEnd":["2014-05-09T14:30:00"],"GMTStartTime":["2014-05-09T18:00:00"],"GMTEndTime":["2014-05-09T18:30:00"],"TimeZone":["ET"],"RoomCode":["R06"],"Room":["Room 6"],"RoomID":["34"],"StatusID":["3"],"EventTypeID":["0"],"DateAdded":["2014-05-09T13:47:29.087"],"DateChanged":["2014-05-09T13:47:29.087"],"ChangedBy":["Admin"]},{"BookingDate":["2014-05-09T00:00:00"],"RoomDescription":["Room06"],"TimeEventStart":["2014-05-09T18:00:00"],"TimeEventEnd":["2014-05-09T20:00:00"],"EventName":["Rob Brown"],"SetupTypeDescription":["(none)"],"ReservationID":["142"],"OpenTime":["1900-01-01T00:00:00"],"CloseTime":["1900-01-01T00:00:00"],"EventTypeDescription":[[]],"BookingID":["714"],"TimeBookingStart":["2014-05-09T18:00:00"],"TimeBookingEnd":["2014-05-09T20:00:00"],"GMTStartTime":["2014-05-09T22:00:00"],"GMTEndTime":["2014-05-10T00:00:00"],"TimeZone":["ET"],"RoomCode":["R06"],"Room":["Room 6"],"RoomID":["34"],"StatusID":["3"],"EventTypeID":["0"],"DateAdded":["2014-05-09T14:58:55.71"],"DateChanged":["2014-05-09T14:58:55.71"],"ChangedBy":["Admin"]},{"BookingDate":["2014-05-9T00:00:00"],"StartBookingDate":["2014-05-09T00:00:00"],"RoomDescription":["Room06"],"TimeEventStart":["2014-05-09T11:00:00"],"TimeEventEnd":["2014-05-09T12:00:00"],"EventName":["Jimmy James"],"SetupTypeDescription":["(none)"],"ReservationID":["141"],"OpenTime":["1900-01-01T00:00:00"],"CloseTime":["1900-01-01T00:00:00"],"EventTypeDescription":[[]],"BookingID":["713"],"TimeBookingStart":["2014-05-09T11:00:00"],"TimeBookingEnd":["2014-05-09T12:00:00"],"GMTStartTime":["2014-05-09T15:00:00"],"GMTEndTime":["2014-05-09T16:00:00"],"TimeZone":["ET"],"RoomCode":["R06"],"Room":["Room 6"],"RoomID":["34"],"StatusID":["1"],"EventTypeID":["0"],"DateAdded":["2014-05-09T14:58:15.17"],"DateChanged":["2014-05-09T14:58:15.17"],"ChangedBy":["Admin"]}]}}'; 
$bookings = json_decode($bookings,true); 


foreach ($bookings["Bookings"]["Data"] as $index=>$arrContent) 
{ 
    if (!nowBetween($arrContent["GMTStartTime"][0],$arrContent["GMTEndTime"][0])) 
    { 
     unset($bookings["Bookings"]["Data"][$index]); 
    } 
} 
+0

Si noti che è possibile abbreviare il codice sostituendo la costruzione if in now Between: "return ($ start <= $ now && $ end> ​​$ now);" ma ho pensato che fosse più chiaro in questo modo: – JohannesB

+0

. Il mio array è attualmente assegnato a $ axml poiché ho aggiornato la domanda per dimostrarlo. – donlaur

+1

Penso che questo funzioni per me. Anche l'altro esempio di Xpath XML è buono. – donlaur

6

È possibile filtrare l'XML utilizzando Xpath. Xpath 1.0 non può confrontare le stringhe, ma puoi anche registrare le funzioni PHP.

Così scrivono la condizione in PHP:

function isBetween($current, $min, $max) { 
    $current = strtotime($current.'Z'); 
    $min = strtotime($min.'Z'); 
    $max = strtotime($max.'Z'); 
    return $current >= $min && $current <= $max; 
} 

Creare un documento DOM e caricare il XML. Crea l'istanza Xpath registra lo spazio dei nomi PHP e la funzione.

$dom = new DOMDocument(); 
$dom->loadXml($xml); 
$xpath = new DOMXpath($dom); 
$xpath->registerNamespace("php", "http://php.net/xpath"); 
$xpath->registerPhpFunctions('isBetween'); 

Definire un'espressione XPath che utilizza la funzione per filtrare l'elemento nodi dati:

// use gmtime() for current time 
$now = strtotime('2014-05-13T14:00:00Z'); 
$expression = sprintf(
    '/Bookings/Data[ 
    php:function("isBetween", "%s", string(GMTStartTime), string(GMTEndTime)) 
    ]', 
    gmdate('Y-m-d\\TH:i:s', $now) 
); 

Fetch i nodi elemento dati utilizzando l'espressione XPath:

$result = []; 
foreach($xpath->evaluate($expression) as $dataNode) { 
    $record = []; 
    // convert the matching data into a record array 
    foreach ($xpath->evaluate('*', $dataNode) as $childNode) { 
    $record[$childNode->localName] = $childNode->nodeValue; 
    } 
    $result[] = $record; 
} 
var_dump($result); 

Demo: https://eval.in/151732

2

Come ho capito, riceverete diversi record nel vostro < Prenotazioni>? Quindi hai due opzioni: se il numero di record è sempre molto grande - più di qualche migliaio allora dovresti usare XPath per filtrare i dati PRIMA di convertirli in un array - copiare i nodi da XPath-> risultato della query sul nuovo documento e convertire questo documento alla matrice. Se il numero di record è piccolo, allora è più facile per convertire i loro dopo - basta usare array_filter con un callback simile a questo:

$filteredResult = array_filter($data, function($row) { 
    // parse dates and compare them.  
}); 

E otterrete serie filtrata.