can edit events now
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 14 Oct 2007 18:32:34 +0000 (18:32 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 14 Oct 2007 18:32:34 +0000 (18:32 +0000)
git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@50 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

17 files changed:
doc/prog_protocol.html
src/event.cpp
src/event.h
src/eventedit.cpp
src/eventedit.h
src/overview.cpp
src/overview.h
src/room.cpp [new file with mode: 0644]
src/room.h [new file with mode: 0644]
src/smoke.pro
src/webrequest.cpp
src/webrequest.h
www/inc/db.php
www/inc/event.php
www/inc/room.php [new file with mode: 0644]
www/loader_nonadmin.php
www/machine.php

index 38775da..486d1c3 100644 (file)
@@ -172,3 +172,62 @@ Attributes and tags:<br>
 </table>
 
 If one of the requested events does not exist, it simply does not generate an <tt>Event</tt> block. It is permissible for the server to send an empty <tt>EventData</tt> tag if no data is available for the request.<p>
+
+<h3>Changing/Creating an Event</h3>
+
+The <tt>seteventdata</tt> transaction creates/changes an event. The request data looks like:<p>
+
+<pre>
+&lt;Event id="0" ....>
+  &lt;Title>....
+&lt;/Event>
+</pre>
+
+Attributes and tags are the same as for the <tt>geteventdata</tt> response. Except that the <tt>id</tt> attribute may contain the value <tt>"new"</tt> to create a new event, a negative integer is not allowed.<p>
+
+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.
+
+<h2>Room related Transactions</h2>
+
+<h3>Getting Rooms</h3>
+
+The <tt>getroomdata</tt> transaction returns data about rooms in the database. The request data looks like this:<p>
+
+<pre>
+&lt;GetRooms detail="basic">
+  &lt;Room>ID of room&lt;/Room>
+  ...
+&lt;/GetRooms>
+</pre>
+
+The <tt>detail</tt> attribute may be "basic" or "full". If no <tT>&lt;Room></tt> tags are present all rooms are returned.<p>
+
+The response data looks like:<p>
+
+<pre>
+&lt;RoomData>
+  &lt;Room capacity="24">
+    &lt;ID>Room ID&lt;/ID>
+    &lt;Description>some encoded HTML text that describes the room&lt;/Description>
+  &lt;/Room>
+  ...
+&lt;/RoomData>
+</pre>
+
+The <tt>capacity</tt> attribute tells how many persons fit into the room. The <tt>ID</tt> tag contains the ID or Name of the room, the optional <tt>Description</tt> tag contains a description of the room - it is only present if full detail has been requested.
+
+<h3>Setting Rooms</h3>
+
+The <tt>setroomdata</tt> transaction is used to create/change one or more rooms, the request data looks like:<p>
+
+<pre>
+&lt;RoomData>
+  &lt;Room capacity="24">
+    &lt;ID>Room ID&lt;/ID>
+    &lt;Description>some encoded HTML text that describes the room&lt;/Description>
+  &lt;/Room>
+  ...
+&lt;/RoomData>
+</pre>
+
+The response simply contains the status "Ok" or "Error".
index be52a47..6c71acd 100644 (file)
@@ -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
index 928f18f..19ef9d6 100644 (file)
 #include <QString>
 
 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
index 1ffc1cf..e7204a9 100644 (file)
@@ -11,6 +11,7 @@
 //
 
 #include "eventedit.h"
+#include "webrequest.h"
 
 #include <QGridLayout>
 #include <QBoxLayout>
@@ -23,6 +24,8 @@
 #include <QTextEdit>
 #include <QTimer>
 #include <QMessageBox>
+#include <QListWidget>
+#include <QInputDialog>
 
 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
+{
+       QList<MRoom>rlst=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;i<rlst.size();i++)
+               rlstw->addItem(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
+       QList<QListWidgetItem*>wlst=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);
+       }
+}
index acc85d3..e105f39 100644 (file)
@@ -32,6 +32,7 @@ class MEventEditor:public QDialog
        private slots:
                void writeBack();
                void selectRoom();
+               void newRoom();
        private:
                MWebRequest*req;
                MEvent event;
index e94bf2b..2e06dd9 100644 (file)
@@ -130,15 +130,15 @@ MOverview::MOverview(MWebRequest*mw,QString pk)
 
 void MOverview::updateEvents()
 {
-       QList<MWebRequest::Eventlet>evl=req->getAllEvents();
+       QList<MEvent>evl=req->getAllEvents();
        eventmodel->clear();
        eventmodel->insertColumns(0,2);
        eventmodel->insertRows(0,evl.size());
        eventmodel->setHorizontalHeaderLabels(QStringList()<<tr("Start Time")<<tr("Title"));
        for(int i=0;i<evl.size();i++){
-               eventmodel->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);
index 1c7bce0..cd97875 100644 (file)
@@ -14,6 +14,7 @@
 #define MAGICSMOKE_OVERVIEW_H
 
 #include <QMainWindow>
+#include <QPointer>
 
 class MWebRequest;
 class QTabWidget;
@@ -42,7 +43,7 @@ class MOverview:public QMainWindow
                void updateEvents();
        private:
                //my session object
-               MWebRequest*req;
+               QPointer<MWebRequest>req;
                //the profile associated with this session
                QString profilekey;
                //widgets
diff --git a/src/room.cpp b/src/room.cpp
new file mode 100644 (file)
index 0000000..ef8fd84
--- /dev/null
@@ -0,0 +1,99 @@
+//
+// C++ Implementation: room
+//
+// Description: 
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "room.h"
+#include "webrequest.h"
+
+#include <QtXml>
+
+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<nl.size();i++){
+                       el=nl.at(i).toElement();
+                       if(el.isNull())continue;
+                       QDomNodeList nl2=el.elementsByTagName("ID");
+                       if(nl2.size()<1)continue;
+                       if(nl2.at(0).toElement().text()==m_roomid)
+                               initFromElement(el);
+               }
+       }
+}
+
+void MRoom::initFromElement(QDomElement&el)
+{
+       bool b;
+       m_valid=true;
+       int cap=el.attribute("capacity","x").trimmed().toInt(&b);
+       if(b && cap>=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 (file)
index 0000000..630046d
--- /dev/null
@@ -0,0 +1,49 @@
+//
+// C++ Interface: room
+//
+// Description: 
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef ROOM_H
+#define ROOM_H
+
+#include <QString>
+
+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
index 14c7f61..a09b10f 100644 (file)
@@ -13,13 +13,13 @@ win32-* {
  #RC-File containing the icon:
  RC_FILE += win.rc
 }
-\r
-#compilation output:\r
-DESTDIR = ../src\r
-OBJECTS_DIR = .ctmp\r
-MOC_DIR = .ctmp\r
-RCC_DIR = .ctmp\r
-\r
+
+#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
 
index 2f506a9..dd4da22 100644 (file)
@@ -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::Eventlet> MWebRequest::getAllEvents()
+QList<MEvent> MWebRequest::getAllEvents()
 {
        errstr="";
-       if(!request("geteventlist"))return QList<Eventlet>();
+       if(!request("geteventlist"))return QList<MEvent>();
        //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<Eventlet>();
+               return QList<MEvent>();
        }
        QDomElement root=doc.documentElement();
        QDomNodeList nl=root.elementsByTagName("Event");
-       QList<Eventlet>ret;
+       QList<MEvent>ret;
        for(int i=0;i<nl.size();i++){
                QDomElement el=nl.at(i).toElement();
                if(el.isNull())continue;
-               Eventlet ev;
-               ev.title=el.text();
-               bool b;
-               ev.id=el.attribute("id").toInt(&b);
-               if(!b || ev.id<0)continue;
-               ev.start=QDateTime::fromTime_t(el.attribute("start").toInt(&b));
-               if(!b)continue;
-               ret.append(ev);
+               MEvent ev(this,el);
+               if(ev.isValid())ret.append(ev);
+       }
+       return ret;
+}
+
+QList<MRoom> MWebRequest::getAllRooms()
+{
+       errstr="";
+       if(!request("getroomdata","<GetRooms detail=\"basic\"/>"))return QList<MRoom>();
+       //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<MRoom>();
+       }
+       QDomElement root=doc.documentElement();
+       QDomNodeList nl=root.elementsByTagName("Room");
+       QList<MRoom>ret;
+       for(int i=0;i<nl.size();i++){
+               QDomElement el=nl.at(i).toElement();
+               if(el.isNull())continue;
+               MRoom rm(this,el);
+               if(rm.isValid())ret.append(rm);
        }
        return ret;
 }
index 39021bd..a979270 100644 (file)
@@ -22,6 +22,9 @@
 #include <QList>
 #include <QDateTime>
 
+#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*/
-               QList<Eventlet>getAllEvents();
+               /**returns a list of all events (in incomplete state)*/
+               QList<MEvent>getAllEvents();
+               
+               /**returns a list of all rooms (without description, which is loaded dynamically if requested)*/
+               QList<MRoom>getAllRooms();
                
        public slots:
                /**set how long to wait for a web request*/
index d429a84..09727b8 100644 (file)
@@ -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)."'";
        }
        
index 08cfc98..06d76d5 100644 (file)
@@ -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 (file)
index 0000000..4df6e6e
--- /dev/null
@@ -0,0 +1,50 @@
+<?
+//
+// PHP Implementation: room
+//
+// Description: 
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (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
index 2b2af5f..1df82e8 100644 (file)
@@ -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
index f56ce3e..a129079 100644 (file)
@@ -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.");