From 3dac8b7ad5d0fe74371a35c21d1ed47fdfa88f2b Mon Sep 17 00:00:00 2001 From: konrad Date: Sun, 14 Oct 2007 18:32:34 +0000 Subject: [PATCH] can edit events now git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@50 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33 --- doc/prog_protocol.html | 59 ++++++++++++++ src/event.cpp | 194 +++++++++++++++++++++++++++++++++++------------ src/event.h | 48 +++++++++++- src/eventedit.cpp | 64 +++++++++++++++- src/eventedit.h | 1 + src/overview.cpp | 8 +- src/overview.h | 3 +- src/room.cpp | 99 ++++++++++++++++++++++++ src/room.h | 49 ++++++++++++ src/smoke.pro | 20 +++-- src/webrequest.cpp | 45 ++++++++---- src/webrequest.h | 18 ++-- www/inc/db.php | 2 + www/inc/event.php | 111 +++++++++++++++++++++++++++ www/inc/room.php | 50 ++++++++++++ www/loader_nonadmin.php | 1 + www/machine.php | 21 +++++- 17 files changed, 701 insertions(+), 92 deletions(-) create mode 100644 src/room.cpp create mode 100644 src/room.h create mode 100644 www/inc/room.php diff --git a/doc/prog_protocol.html b/doc/prog_protocol.html index 38775da..486d1c3 100644 --- a/doc/prog_protocol.html +++ b/doc/prog_protocol.html @@ -172,3 +172,62 @@ Attributes and tags:
If one of the requested events does not exist, it simply does not generate an Event block. It is permissible for the server to send an empty EventData tag if no data is available for the request.

+ +

Changing/Creating an Event

+ +The seteventdata transaction creates/changes an event. The request data looks like:

+ +

+<Event id="0" ....>
+  <Title>....
+</Event>
+
+ +Attributes and tags are the same as for the geteventdata response. Except that the id attribute may contain the value "new" to create a new event, a negative integer is not allowed.

+ +The response contains the ID of the new/changed event if the status is "Ok". In the case of failure the status will be "Error" and an optional reason for the failure may be in the body. + +

Room related Transactions

+ +

Getting Rooms

+ +The getroomdata transaction returns data about rooms in the database. The request data looks like this:

+ +

+<GetRooms detail="basic">
+  <Room>ID of room</Room>
+  ...
+</GetRooms>
+
+ +The detail attribute may be "basic" or "full". If no <Room> tags are present all rooms are returned.

+ +The response data looks like:

+ +

+<RoomData>
+  <Room capacity="24">
+    <ID>Room ID</ID>
+    <Description>some encoded HTML text that describes the room</Description>
+  </Room>
+  ...
+</RoomData>
+
+ +The capacity attribute tells how many persons fit into the room. The ID tag contains the ID or Name of the room, the optional Description tag contains a description of the room - it is only present if full detail has been requested. + +

Setting Rooms

+ +The setroomdata transaction is used to create/change one or more rooms, the request data looks like:

+ +

+<RoomData>
+  <Room capacity="24">
+    <ID>Room ID</ID>
+    <Description>some encoded HTML text that describes the room</Description>
+  </Room>
+  ...
+</RoomData>
+
+ +The response simply contains the status "Ok" or "Error". diff --git a/src/event.cpp b/src/event.cpp index be52a47..6c71acd 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -21,14 +21,39 @@ MEvent::MEvent(MWebRequest*r,int id) { req=r; eventid=id; + refresh(); +} + +MEvent::MEvent(MWebRequest*r,QDomElement&el) +{ + req=r; m_starttime=QDateTime::currentDateTime().toTime_t(); m_endtime=m_starttime+3600; m_capacity=10; m_defaultprice=100; + m_valid=false; + m_roomid=m_title=m_artist=m_description=m_cancelreason=""; m_valid=true; - if(id>=0){ + m_complete=false; + bool b; + eventid=el.attribute("id","x").toInt(&b); + if(!b)eventid=-1; + else initFromElement(el); +} + +void MEvent::refresh() +{ + m_starttime=QDateTime::currentDateTime().toTime_t(); + m_endtime=m_starttime+3600; + m_capacity=10; + m_defaultprice=100; + m_valid=false; + m_roomid=m_title=m_artist=m_description=m_cancelreason=""; + m_valid=true; + m_complete=false; + if(eventid>=0){ //get data from server - if(!req->request("geteventdata",QString::number(id).toAscii())){ + if(!req->request("geteventdata",QString::number(eventid).toAscii())){ m_valid=false; return; } @@ -53,61 +78,114 @@ MEvent::MEvent(MWebRequest*r,int id) bool b; int eid=el.attribute("id","x").toInt(&b); if(eid!=eventid || !b)continue; - //get attribute data - m_starttime=el.attribute("start","0").toInt(); - m_endtime=el.attribute("end","0").toInt(); - m_capacity=el.attribute("capacity","0").toInt(); - m_defaultprice=el.attribute("defaultprice","0").toInt(); - bool iscancel=el.attribute("cancelled","false")=="true"; - //get title - QDomNodeList nl2=el.elementsByTagName("Title"); - if(nl2.size()>0){ - QDomElement el2=nl2.at(0).toElement(); - if(!el2.isNull()) - m_title=el2.text(); - } - //get artist - nl2=el.elementsByTagName("Artist"); - if(nl2.size()>0){ - QDomElement el2=nl2.at(0).toElement(); - if(!el2.isNull()) - m_artist=el2.text(); - } - //get description - nl2=el.elementsByTagName("Description"); - if(nl2.size()>0){ - QDomElement el2=nl2.at(0).toElement(); - if(!el2.isNull()) - m_description=el2.text(); - } - //get room - nl2=el.elementsByTagName("Room"); - if(nl2.size()>0){ - QDomElement el2=nl2.at(0).toElement(); - if(!el2.isNull()) - m_roomid=el2.text().trimmed(); - } - //get cancel reason - nl2=el.elementsByTagName("CancelReason"); - if(nl2.size()>0){ - QDomElement el2=nl2.at(0).toElement(); - if(!el2.isNull()) - m_cancelreason=el2.text().trimmed(); - } - if(iscancel){ - if(m_cancelreason=="")m_cancelreason=" "; - }else{ - m_cancelreason=""; - } + initFromElement(el); } } } +void MEvent::initFromElement(QDomElement&el) +{ + //get attribute data + m_starttime=el.attribute("start","0").toInt(); + m_endtime=el.attribute("end","0").toInt(); + m_capacity=el.attribute("capacity","0").toInt(); + m_defaultprice=el.attribute("defaultprice","0").toInt(); + bool iscancel=el.attribute("cancelled","false")=="true"; + //get title (if element exists this is a complete list, otherwise only preview) + QDomNodeList nl2=el.elementsByTagName("Title"); + if(nl2.size()>0){ + m_complete=true; + QDomElement el2=nl2.at(0).toElement(); + if(!el2.isNull()) + m_title=el2.text(); + }else{ + //incomplete event, break here + m_complete=false; + m_title=el.text().trimmed(); + return; + } + //get artist + nl2=el.elementsByTagName("Artist"); + if(nl2.size()>0){ + QDomElement el2=nl2.at(0).toElement(); + if(!el2.isNull()) + m_artist=el2.text(); + } + //get description + nl2=el.elementsByTagName("Description"); + if(nl2.size()>0){ + QDomElement el2=nl2.at(0).toElement(); + if(!el2.isNull()) + m_description=el2.text(); + } + //get room + nl2=el.elementsByTagName("Room"); + if(nl2.size()>0){ + QDomElement el2=nl2.at(0).toElement(); + if(!el2.isNull()) + m_roomid=el2.text().trimmed(); + } + //get cancel reason + nl2=el.elementsByTagName("CancelReason"); + if(nl2.size()>0){ + QDomElement el2=nl2.at(0).toElement(); + if(!el2.isNull()) + m_cancelreason=el2.text().trimmed(); + } + if(iscancel){ + if(m_cancelreason=="")m_cancelreason=" "; + }else{ + m_cancelreason=""; + } +} + MEvent::~MEvent() {} -void MEvent::save() +QString MEvent::save() { + //do not attempt to save invalid or incomplete data + if(!m_valid || !m_complete)return QCoreApplication::translate("MEvent","Event is not complete, cannot save."); + //create XML + QDomDocument doc; + QDomElement root=doc.createElement("Event"); + if(eventid>=0)root.setAttribute("id",eventid); + else root.setAttribute("id","new"); + root.setAttribute("start",m_starttime); + root.setAttribute("end",m_endtime); + root.setAttribute("capacity",m_capacity); + root.setAttribute("defaultprice",m_defaultprice); + root.setAttribute("cancelled",isCancelled()?"true":"false"); + QDomElement el=doc.createElement("Title"); + el.appendChild(doc.createTextNode(m_title)); + root.appendChild(el); + el=doc.createElement("Artist"); + el.appendChild(doc.createTextNode(m_artist)); + root.appendChild(el); + el=doc.createElement("Description"); + el.appendChild(doc.createTextNode(m_description)); + root.appendChild(el); + el=doc.createElement("Room"); + el.appendChild(doc.createTextNode(m_roomid)); + root.appendChild(el); + if(isCancelled()){ + el=doc.createElement("CancelReason"); + el.appendChild(doc.createTextNode(m_cancelreason)); + root.appendChild(el); + } + doc.appendChild(root); + //call + req->request("seteventdata",doc.toByteArray()); + //get new ID + if(req->responseStatus()==MWebRequest::Ok){ + QString r=QString::fromAscii(req->responseBody()).trimmed(); + bool b; + int eid=r.toInt(&b); + if(b && eid>=0)eventid=eid; + return ""; + }else{ + return req->errorString()+" "; + } } QRegExp MEvent::priceRegExp()const @@ -122,4 +200,22 @@ QString MEvent::priceString()const ret+=QString::number((m_defaultprice/10)%10); ret+=QString::number(m_defaultprice%10); return ret; +} + +void MEvent::setCancelled(bool ic,QString cr) +{ + if(ic){ + m_cancelreason=cr.trimmed(); + if(m_cancelreason=="")m_cancelreason=" "; + }else + m_cancelreason=""; +} + +void MEvent::setPrice(QString str) +{ + QStringList ps=str.split(QCoreApplication::translate("MEvent",".","price decimal dot")); + int prc=0; + if(ps.size()>=1)prc=ps[0].toInt()*100; + if(ps.size()>=2)prc+=ps[1].toInt(); + m_defaultprice=prc; } \ No newline at end of file diff --git a/src/event.h b/src/event.h index 928f18f..19ef9d6 100644 --- a/src/event.h +++ b/src/event.h @@ -16,31 +16,75 @@ #include class MWebRequest; +class QDomElement; +/**encapsulation of an event, this class handles all there is to know about events and how to communicate with the database*/ class MEvent { public: + /**creates an event by ID, the constructor asks the server/database for details*/ MEvent(MWebRequest*,int); + /**creates an event via a DOM-element, used by WebRequest::getAllEvents*/ + MEvent(MWebRequest*,QDomElement&); + /**destructs an event*/ ~MEvent(); - void save(); + /**updates data from the database, can be used to upgrade an incomplete event to a complete one*/ + void refresh(); + /**saves all data back to the database, it returns an empty string on success, it does not do anything if the event is invalid or incomplete*/ + QString save(); + + /**returns the database ID of the event, a valid event will always have an ID >=0*/ + int eventId()const{return eventid;} + + /**returns the title of the event*/ QString title()const{return m_title;} + /**returns the artist of the event*/ QString artist()const{return m_artist;} + /**returns the description of the event (HTML)*/ QString description()const{return m_description;} + /**returns the start time of the event as Unix timestamp*/ int startTime()const{return m_starttime;} + /**returns the end time of the event as Unix timestamp*/ int endTime()const{return m_endtime;} + /**returns the room of the event, the room must be one out of the list of valid rooms*/ QString room()const{return m_roomid;} + /**returns the amount of tickets than can be sold for this event, initially this should be a copy of the rooms capacity*/ int capacity()const{return m_capacity;} + /**returns the normal price of tickets in cent*/ int price()const{return m_defaultprice;} + /**returns whether the event is cancelled*/ bool isCancelled()const{return !m_cancelreason.isEmpty();} + /**returns the reason why the event is cancelled*/ QString cancelReason()const{return m_cancelreason.trimmed();} + void setTitle(QString t){m_title=t;} + void setArtist(QString t){m_artist=t;} + void setDescription(QString t){m_description=t;} + void setRoom(QString t){m_roomid=t;} + void setStartTime(int t){m_starttime=t;} + void setEndTime(int t){m_endtime=t;} + void setCapacity(int c){m_capacity=c;} + void setPrice(int p){if(p>=0)m_defaultprice=p;} + void setPrice(QString); + void setCancelled(bool,QString cr=QString()); + + /**returns the price as a localized string*/ QString priceString()const; + /**returns the local regular expression for prices*/ QRegExp priceRegExp()const; + /**returns whether the event is valid. an event can be invalid if it is uninitialized (negative ID) or the server request failed*/ bool isValid()const{return m_valid;} + /**returns whether the event is complete - this depends on the amount of data sent by the server*/ + bool isComplete()const{return m_complete;} + /**forces the event to believe it is valid and complete; used for saving new events*/ + void makeValid(){m_valid=true;m_complete=true;} private: + //used by both constructors: + void initFromElement(QDomElement&); + MWebRequest*req; int eventid; //display data @@ -55,7 +99,7 @@ class MEvent //if not null/empty: event has been cancelled QString m_cancelreason; //holds whether the loaded data is valid - bool m_valid; + bool m_valid,m_complete; }; #endif diff --git a/src/eventedit.cpp b/src/eventedit.cpp index 1ffc1cf..e7204a9 100644 --- a/src/eventedit.cpp +++ b/src/eventedit.cpp @@ -11,6 +11,7 @@ // #include "eventedit.h" +#include "webrequest.h" #include #include @@ -23,6 +24,8 @@ #include #include #include +#include +#include MEventEditor::MEventEditor(QWidget*w,MWebRequest*r,qint32 id) :QDialog(w),event(r,id) @@ -109,14 +112,69 @@ MEventEditor::MEventEditor(QWidget*w,MWebRequest*r,qint32 id) vl->addLayout(hl=new QHBoxLayout,0); hl->addStretch(); hl->addWidget(p=new QPushButton(tr("Save"))); - connect(p,SIGNAL(clicked()),this,SLOT(accept())); +// connect(p,SIGNAL(clicked()),this,SLOT(accept())); connect(p,SIGNAL(clicked()),this,SLOT(writeBack())); hl->addWidget(p=new QPushButton(tr("Cancel"))); connect(p,SIGNAL(clicked()),this,SLOT(reject())); } void MEventEditor::writeBack() -{} +{ + //copy contents to event + event.setTitle(title->text()); + event.setStartTime(starttime->dateTime().toTime_t()); + event.setEndTime(endtime->dateTime().toTime_t()); + event.setArtist(artist->text()); + event.setRoom(room->text()); + event.setPrice(price->text()); + event.setCancelled(cancelcheck->isChecked(),cancelreason->text()); + event.setDescription(description->toPlainText()); + event.setCapacity(capacity->value()); + //send to server + event.makeValid(); + QString r=event.save(); + if(r!=""){ + QMessageBox::warning(this,tr("Warning"),tr("Problem while uploading event: %s").arg(r)); + }else + accept(); +} void MEventEditor::selectRoom() -{} \ No newline at end of file +{ + QListrlst=req->getAllRooms(); + QDialog d; + d.setWindowTitle(tr("Select a Room")); + QVBoxLayout*vl; + d.setLayout(vl=new QVBoxLayout); + QListWidget*rlstw; + vl->addWidget(rlstw=new QListWidget,10); + for(int i=0;iaddItem(rlst[i].roomId()); + QHBoxLayout*hl; + vl->addLayout(hl=new QHBoxLayout,0); + hl->addStretch(10); + QPushButton*p; + hl->addWidget(p=new QPushButton(tr("New...","new room")),0); + connect(p,SIGNAL(clicked()),this,SLOT(newRoom())); + connect(p,SIGNAL(clicked()),&d,SLOT(reject())); + hl->addWidget(p=new QPushButton(tr("Select","select room")),0); + connect(p,SIGNAL(clicked()),&d,SLOT(accept())); + hl->addWidget(p=new QPushButton(tr("Cancel")),0); + connect(p,SIGNAL(clicked()),&d,SLOT(reject())); + if(d.exec()==QDialog::Rejected)return; + //get selection + QListwlst=rlstw->selectedItems(); + if(wlst.size()<1)return; + room->setText(wlst[0]->text()); +} + +void MEventEditor::newRoom() +{ + QString rid=QInputDialog::getText(this,tr("New Room"),tr("Name of new room:")); + if(rid!=""){ + MRoom rm(req,rid); + rm.makeValid(); + rm.save(); + room->setText(rid); + } +} diff --git a/src/eventedit.h b/src/eventedit.h index acc85d3..e105f39 100644 --- a/src/eventedit.h +++ b/src/eventedit.h @@ -32,6 +32,7 @@ class MEventEditor:public QDialog private slots: void writeBack(); void selectRoom(); + void newRoom(); private: MWebRequest*req; MEvent event; diff --git a/src/overview.cpp b/src/overview.cpp index e94bf2b..2e06dd9 100644 --- a/src/overview.cpp +++ b/src/overview.cpp @@ -130,15 +130,15 @@ MOverview::MOverview(MWebRequest*mw,QString pk) void MOverview::updateEvents() { - QListevl=req->getAllEvents(); + QListevl=req->getAllEvents(); eventmodel->clear(); eventmodel->insertColumns(0,2); eventmodel->insertRows(0,evl.size()); eventmodel->setHorizontalHeaderLabels(QStringList()<setData(eventmodel->index(i,0),evl[i].id,Qt::UserRole); - eventmodel->setData(eventmodel->index(i,0),evl[i].start.toString(tr("ddd MMMM d yyyy, h:mm ap","time format"))); - eventmodel->setData(eventmodel->index(i,1),evl[i].title); + eventmodel->setData(eventmodel->index(i,0),evl[i].eventId(),Qt::UserRole); + eventmodel->setData(eventmodel->index(i,0),QDateTime::fromTime_t(evl[i].startTime()).toString(tr("ddd MMMM d yyyy, h:mm ap","time format"))); + eventmodel->setData(eventmodel->index(i,1),evl[i].title()); } eventtable->resizeColumnToContents(0); eventtable->resizeColumnToContents(1); diff --git a/src/overview.h b/src/overview.h index 1c7bce0..cd97875 100644 --- a/src/overview.h +++ b/src/overview.h @@ -14,6 +14,7 @@ #define MAGICSMOKE_OVERVIEW_H #include +#include class MWebRequest; class QTabWidget; @@ -42,7 +43,7 @@ class MOverview:public QMainWindow void updateEvents(); private: //my session object - MWebRequest*req; + QPointerreq; //the profile associated with this session QString profilekey; //widgets diff --git a/src/room.cpp b/src/room.cpp new file mode 100644 index 0000000..ef8fd84 --- /dev/null +++ b/src/room.cpp @@ -0,0 +1,99 @@ +// +// C++ Implementation: room +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2007 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#include "room.h" +#include "webrequest.h" + +#include + +MRoom::MRoom(MWebRequest*r,QDomElement&el) +{ + req=r; + m_valid=m_complete=false; + m_capacity=0; + initFromElement(el); +} + +MRoom::MRoom(MWebRequest*r,QString rn) +{ + req=r; + m_roomid=rn; + refresh(); +} + +void MRoom::refresh() +{ + m_valid=m_complete=false; + m_capacity=0; + //request + QDomDocument doc1; + QDomElement root=doc1.createElement("GetRooms"); + root.setAttribute("detail","full"); + QDomElement el=doc1.createElement("Room"); + el.appendChild(doc1.createTextNode(m_roomid)); + root.appendChild(el); + doc1.appendChild(root); + if(req->request("getroomdata",doc1.toByteArray())){ + if(req->responseStatus()!=MWebRequest::Ok)return; + QDomDocument doc2; + if(!doc2.setContent(req->responseBody()))return; + root=doc2.documentElement(); + QDomNodeList nl=root.elementsByTagName("Room"); + for(int i=0;i=0)m_capacity=cap; + else m_valid=false; + QDomNodeList nl=el.elementsByTagName("ID"); + if(nl.size()>0){ + m_roomid=nl.at(0).toElement().text(); + if(m_roomid=="")m_valid=false; + }else + m_valid=false; + nl=el.elementsByTagName("Description"); + if(nl.size()>0){ + m_description=nl.at(0).toElement().text(); + m_complete=true; + }else + m_complete=false; +} + +void MRoom::save() +{ + if(!m_valid || !m_complete)return; + QDomDocument doc; + QDomElement root=doc.createElement("RoomData"); + QDomElement room=doc.createElement("Room"); + room.setAttribute("capacity",m_capacity); + QDomElement el=doc.createElement("ID"); + el.appendChild(doc.createTextNode(m_roomid)); + room.appendChild(el); + el=doc.createElement("Description"); + el.appendChild(doc.createTextNode(m_description)); + room.appendChild(el); + root.appendChild(room); + doc.appendChild(root); + req->request("setroomdata",doc.toByteArray()); +} diff --git a/src/room.h b/src/room.h new file mode 100644 index 0000000..630046d --- /dev/null +++ b/src/room.h @@ -0,0 +1,49 @@ +// +// C++ Interface: room +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2007 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#ifndef ROOM_H +#define ROOM_H + +#include + +class MWebRequest; +class QDomElement; + +class MRoom +{ + public: + MRoom(MWebRequest*,QDomElement&); + MRoom(MWebRequest*,QString); + + QString roomId()const{return m_roomid;} + QString description()const{return m_description;} + int capacity()const{return m_capacity;} + + void setDescription(QString s){m_description=s;} + void setCapacity(int c){if(c>=0)m_capacity=c;} + + bool isValid()const{return m_valid;} + bool isComplete()const{return m_complete;} + void makeValid(){m_valid=m_complete=true;} + + void save(); + void refresh(); + + private: + void initFromElement(QDomElement&); + MWebRequest*req; + QString m_roomid,m_description; + int m_capacity; + bool m_valid,m_complete; +}; + +#endif diff --git a/src/smoke.pro b/src/smoke.pro index 14c7f61..a09b10f 100644 --- a/src/smoke.pro +++ b/src/smoke.pro @@ -13,13 +13,13 @@ win32-* { #RC-File containing the icon: RC_FILE += win.rc } - -#compilation output: -DESTDIR = ../src -OBJECTS_DIR = .ctmp -MOC_DIR = .ctmp -RCC_DIR = .ctmp - + +#compilation output: +DESTDIR = ../src +OBJECTS_DIR = .ctmp +MOC_DIR = .ctmp +RCC_DIR = .ctmp + SOURCES = \ main.cpp \ @@ -30,7 +30,8 @@ SOURCES = \ webrequest.cpp \ overview.cpp \ eventedit.cpp \ - event.cpp + event.cpp \ + room.cpp HEADERS = \ keygen.h \ mainwindow.h \ @@ -38,7 +39,8 @@ HEADERS = \ webrequest.h \ overview.h \ eventedit.h \ - event.h + event.h \ + room.h RESOURCES += files.qrc diff --git a/src/webrequest.cpp b/src/webrequest.cpp index 2f506a9..dd4da22 100644 --- a/src/webrequest.cpp +++ b/src/webrequest.cpp @@ -45,7 +45,7 @@ bool MWebRequest::request(QString hreq,QByteArray data) if(url.scheme().toLower()=="http")port=80; else port=443; } - qDebug("connecting to host=%s port=%i scheme=%s",url.host().toAscii().data(),(int)port,url.scheme().toAscii().data()); + qDebug("connecting to host=%s port=%i scheme=%s request=%s",url.host().toAscii().data(),(int)port,url.scheme().toAscii().data(),hreq.toAscii().data()); QHttp::ConnectionMode conm; if(url.scheme().toLower()=="http")conm=QHttp::ConnectionModeHttp; else conm=QHttp::ConnectionModeHttps; @@ -61,7 +61,7 @@ bool MWebRequest::request(QString hreq,QByteArray data) hrh.setValue("X-MagicSmoke-Session",sessionid); hrh.setContentLength(data.size()); hrh.setContentType("application/x-magicsmoke"); - qDebug("Requesting data with:\n%s",hrh.toString().toAscii().data()); + qDebug("Requesting data with:\n%s\n\n%s",hrh.toString().toAscii().data(),data.data()); waitid=req.request(hrh,data); qDebug("started req %i",waitid); fin=false;errstr=""; @@ -298,31 +298,48 @@ bool MWebRequest::hasRole(QString r) return roles.contains(r.toLower()); } -QList MWebRequest::getAllEvents() +QList MWebRequest::getAllEvents() { errstr=""; - if(!request("geteventlist"))return QList(); + if(!request("geteventlist"))return QList(); //parse return document QDomDocument doc; QString msg;int ln,cl; if(!doc.setContent(rspdata,&msg,&ln,&cl)){ errstr=tr("Error parsing EventList XML data (line %1 column %2): %3").arg(ln).arg(cl).arg(msg); - return QList(); + return QList(); } QDomElement root=doc.documentElement(); QDomNodeList nl=root.elementsByTagName("Event"); - QListret; + QListret; for(int i=0;i MWebRequest::getAllRooms() +{ + errstr=""; + if(!request("getroomdata",""))return QList(); + //parse return document + QDomDocument doc; + QString msg;int ln,cl; + if(!doc.setContent(rspdata,&msg,&ln,&cl)){ + errstr=tr("Error parsing EventList XML data (line %1 column %2): %3").arg(ln).arg(cl).arg(msg); + return QList(); + } + QDomElement root=doc.documentElement(); + QDomNodeList nl=root.elementsByTagName("Room"); + QListret; + for(int i=0;i #include +#include "room.h" +#include "event.h" + /**abstraction of requests to the web server, handles sessions and all data transfer*/ class MWebRequest:public QObject { @@ -50,7 +53,7 @@ class MWebRequest:public QObject InvalidRequest=5, /**the request data had syntactical errors*/ SyntaxError=6, - /**the HTTP transport failed or the server was unable to execute the script*/ + /**the HTTP transport failed (time out) or the server was unable to execute the script; this code is set in all cases in which request returns false*/ HttpError=100 }; @@ -63,14 +66,11 @@ class MWebRequest:public QObject /**returns whether the user has a specific role/right*/ bool hasRole(QString); - /**represents the minimal info about an event that comes from a getAllEvents*/ - struct Eventlet{ - int id; - QString title; - QDateTime start; - }; - /**returns a list of all events*/ - QListgetAllEvents(); + /**returns a list of all events (in incomplete state)*/ + QListgetAllEvents(); + + /**returns a list of all rooms (without description, which is loaded dynamically if requested)*/ + QListgetAllRooms(); public slots: /**set how long to wait for a web request*/ diff --git a/www/inc/db.php b/www/inc/db.php index d429a84..09727b8 100644 --- a/www/inc/db.php +++ b/www/inc/db.php @@ -190,12 +190,14 @@ abstract class DbEngine /**escapes integers; the default implementation just makes sure it is an int*/ public function escapeInt($i) { + if($i === false)return "NULL"; return $i + 0; } /**escapes strings; the default uses addslashes and encloses the value in ''*/ public function escapeString($s) { + if($s === false) return "NULL"; return "'".addslashes($s)."'"; } diff --git a/www/inc/event.php b/www/inc/event.php index 08cfc98..06d76d5 100644 --- a/www/inc/event.php +++ b/www/inc/event.php @@ -43,6 +43,7 @@ function getAllEventsXml() echo $xml->saveXml(); } +/**Wrapper around event table*/ class Event { private $evid; @@ -161,4 +162,114 @@ function getEventsXml($evts) echo $xml->saveXml(); } +/**Machine-Interface: set an event (it's not possible to set from Web-Browser)*/ +function setEventXml($xmldata) +{ + global $db; + //stage 1: parse XML + $xml=new DOMDocument; + if($xml->loadXML($xmldata)===false){ + header("X-MagicSmoke-Status: SyntaxError"); + echo "Unable to parse XML."; + return; + } + //stage 2: extract data from XML + $doc=$xml->documentElement; + $eventid=trim($doc->getAttribute("id")); + $start=trim($doc->getAttribute("start"))+0; + $end=trim($doc->getAttribute("end"))+0; + $capacity=trim($doc->getAttribute("capacity"))+0; + $defaultprice=trim($doc->getAttribute("defaultprice"))+0; + $cancelled=trim($doc->getAttribute("cancelled")); + $title=$artist=$description=$room=$cancelreason=""; + foreach($doc->getElementsByTagName("Title") as $el) + foreach($el->childNodes as $cn) + if($cn->nodeType==XML_TEXT_NODE) + $title=trim($cn->wholeText); + foreach($doc->getElementsByTagName("Artist") as $el) + foreach($el->childNodes as $cn) + if($cn->nodeType==XML_TEXT_NODE) + $artist=trim($cn->wholeText); + foreach($doc->getElementsByTagName("Description") as $el) + foreach($el->childNodes as $cn) + if($cn->nodeType==XML_TEXT_NODE) + $description=trim($cn->wholeText); + foreach($doc->getElementsByTagName("Room") as $el) + foreach($el->childNodes as $cn) + if($cn->nodeType==XML_TEXT_NODE) + $room=trim($cn->wholeText); + foreach($doc->getElementsByTagName("CancelReason") as $el) + foreach($el->childNodes as $cn) + if($cn->nodeType==XML_TEXT_NODE) + $cancelreason=trim($cn->wholeText); + //stage 3: validate input + if(ereg("^([0-9]+)|(new)$",$eventid)===false){ + header("X-MagicSmoke-Status: Error"); + echo "Invalid Event ID, must be positive integer or 'new'."; + return; + } + if($cancelled!="true" && $cancelled!="false"){ + header("X-MagicSmoke-Status: Error"); + echo "Event neither cancelled, nor non-cancelled."; + return; + } + if($title==""){ + header("X-MagicSmoke-Status: Error"); + echo "Empty Title."; + return; + } + if($artist==""){ + header("X-MagicSmoke-Status: Error"); + echo "No Artist."; + return; + } + $db->beginTransaction(); + $res=$db->select("room","roomid","roomid='".addslashes($room)."'"); + if(count($res)<1){ + //end DB transaction + $db->rollbackTransaction(); + //error + header("X-MagicSmoke-Status: Error"); + echo "Invalid Room."; + return; + } + + //stage 4: call DB + $data["title"]=$title; + $data["artist"]=$artist; + $data["description"]=$description; + $data["starttime"]=$start; + $data["endtime"]=$end; + $data["roomid"]=$room; + $data["capacity"]=$capacity; + $data["defaultprice"]=$defaultprice; + if($cancelled=="true") + $data["cancelreason"]=$cancelreason." "; + else + $data["cancelreason"]=false; + if($eventid=="new"){ + //create new ID + $res=$db->select("event","max(eventid)",""); + if(count($res)==0)$eventid=0; + else $eventid=$res[0][0]+1; + //create event + $data["eventid"]=$eventid; + $db->insert("event",$data); + }else{ + //check ID + $eventid=$eventid+0; + $res=$db->select("event","eventid","eventid=".$eventid); + if(count($res)==0){ + header("X-MagicSmoke-Status: Error"); + echo "Invalid Event: eventid does not exist in database."; + $db->rollbackTransaction(); + return; + } + $db->update("event",$data,"eventid=".$eventid); + } + $db->commitTransaction(); + header("X-MagicSmoke-Status: Ok"); + echo $eventid; +} + ?> \ No newline at end of file diff --git a/www/inc/room.php b/www/inc/room.php new file mode 100644 index 0000000..4df6e6e --- /dev/null +++ b/www/inc/room.php @@ -0,0 +1,50 @@ +, (C) 2007 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +//TODO: implement: +class Room +{ + public function __construct($roomid){} + public function exists(){return false;} + +}; + +function getRoomsXml($xmldata) +{ + global $db; + //TODO: check xml data + //return rooms + $res=$db->select("room","roomid,capacity,description",""); + $xml=new DOMDocument; + $root=$xml->createElement("RoomData"); + if(count($res)>0) + foreach($res as $k => $rm){ + $room=$xml->createElement("Room"); + $room->setAttribute("capacity",$rm["capacity"]); + $id=$xml->createElement("ID",$rm["roomid"]); + $room->appendChild($id); + $des=$xml->createElement("Description",$rm["description"]); + $room->appendChild($des); + $root->appendChild($room); + } + $xml->appendChild($root); + header("X-MagicSmoke-Status: Ok"); + print($xml->saveXML()); +} + +function setRoomsXml($xmldata) +{ + //TODO:implement +} + +?> \ No newline at end of file diff --git a/www/loader_nonadmin.php b/www/loader_nonadmin.php index 2b2af5f..1df82e8 100644 --- a/www/loader_nonadmin.php +++ b/www/loader_nonadmin.php @@ -4,4 +4,5 @@ if(!$db->canUseDb()) die("Database is not correctly configured. Giving up."); //load class-files include('inc/event.php'); +include('inc/room.php'); ?> \ No newline at end of file diff --git a/www/machine.php b/www/machine.php index f56ce3e..a129079 100644 --- a/www/machine.php +++ b/www/machine.php @@ -16,7 +16,8 @@ $ALLOWEDREQUESTS=array( //all requests below here need authentication "getmyroles", //role management //all requests below here need a role entry in the DB - "geteventlist", "geteventdata", //event infos + "geteventlist", "geteventdata", "seteventdata", //event infos + "getroomdata","setroomdata",//room infos "getcustomerlist" //customer info ); /**contains the low-level request name from the client*/ @@ -119,6 +120,24 @@ if($SMOKEREQUEST=="geteventdata"){ exit(); } +//set an event +if($SMOKEREQUEST=="seteventdata"){ + setEventXml($REQUESTDATA); + exit(); +} + +//get room +if($SMOKEREQUEST=="getroomdata"){ + getRoomsXml($REQUESTDATA); + exit(); +} + +//set room +if($SMOKEREQUEST=="setroomdata"){ + setRoomsXml($REQUESTDATA); + exit(); +} + //EOF header("X-MagicSmoke-Status: Error"); die("Internal Error: unknown command, hiccup in code structure."); -- 1.7.2.5