- see COPYING.AGPL for details
-->
<Wolf>
-
- <Table name="moneylog" backup="yes">
- <Column name="logid" type="seq64" primarykey="yes"/>
- <Column name="logtime" type="int64" notnull="yes"/>
- <Column name="uname" type="string:64" foreignkey="user:uname" null="yes"/>
- <Column name="orderid" type="int32" foreignkey="order:orderid" null="yes"/>
- <Column name="voucherid" type="string:32" foreignkey="voucher:voucherid" null="yes"/>
- <Column name="moved" type="int32" notnull='yes'/>
- <Column name="orderpaid" type="int32" null="yes"/>
- <Column name="orderdue" type="int32" null="yes"/>
- <Column name="vouchervalue" type="int32" null="yes"/>
- <Column name="log" type="string" notnull='yes'/>
- </Table>
-
<Table name="documentlog" backup="yes">
<Column name="docid" type="seq64" primarykey="yes"/>
<Column name="logtime" type="int64" notnull="yes"/>
<Property name="name" type="string"/>
<Property name="description" type="string"/>
<Property name="comment" type="string"/>
+
+ <Mapping table="artist">
+ <Map column="artistid" property="id"/>
+ <Map column="artistname" property="name"/>
+ <Map column="description"/>
+ <Map column="comment"/>
+ </Mapping>
</Class>
<Class name="Price">
<Mapping table="event">
<Map column="eventid" property="id"/>
<Map column="title"/>
- <Map column="artist"/>
+ <Map property="artist">
+ <Call lang="php" method="WOArtist::fromTableartist($table->getObjectForartistid())"/>
+ </Map>
<Map column="description"/>
<Map column="comment"/>
<!--timing and location-->
<!-- generic settings -->
<Project baseDir=".." wobDir="wob" name="MagicSmoke"/>
<Version comm="0100" needcomm="0100" humanReadable="1.91 alpha" svnTarget="."/>
- <DataBase instance="db" schema="dbScheme" version="01.04"/>
+ <DataBase instance="db" schema="dbScheme" version="01.04">
+ <AuditTables>
+ <Column name="audittime" type="int64">
+ <Call lang="php" method="time()"/>
+ </Column>
+ <Column name="audituname" type="string:64">
+ <Call lang="php" method="Session::currentUserName()"/>
+ </Column>
+ <Column name="audittransaction" type="string:64">
+ <Call lang="php" method="WobTransactionBase::getExecutingName()"/>
+ </Column>
+ </AuditTables>
+ </DataBase>
<!-- configure output -->
<QtClientOutput sourceDir="src" subDir="wob" priInclude="wob.pri" classPrefix="M" clean="yes"/>
<Authenticator
isAuthenticated="Session::instance()->isAuthenticated()"
hasRole="Session::instance()->canExecute(%)"
- userName="Session::instance()->getUser()"
+ userName="Session::currentUserName()"
init="new Session($this)"/>
</PHPServerOutput>
<!-- HtmlOutput sourceDir="doc" subDir="wob"/ -->
<Column name="flags" type="string"/>
<Column name="description" type="string"/> <!--description for the shipping type-->
</Table>
- <Table name="order" backup="yes">
+ <Table name="paymenttype" backup="yes">
+ <Column name="paytype" type="string:64" primarykey="yes"/>
+ <Column name="description" type="string"/>
+ <Column name="dataname" type="string:64"/>
+ </Table>
+ <Table name="order" backup="yes" audit="yes">
<Column name="orderid" type="seq32" primarykey="yes"/>
<!--customer-->
<Column name="customerid" type="int32" foreignkey="customer:customerid"/>
<!--pointer to shipping type (none per default, programmatic default is in config)-->
<Column name="shippingtype" type="int32" null="yes" foreignkey="shipping:shipid"/>
+ <!-- in audit: monitor the type of payment -->
+ <AuditColumn name="paytype" type="string:64" foreignkey="paymenttype:paytype"/>
+ <AuditColumn name="paydata" type="string"/>
+
<Foreign method="getTickets" via="ticket:orderid=orderid"/>
<Foreign method="getVouchers" via="voucher:orderid=orderid"/>
+ <Foreign method="getItems" via="item:orderid=orderid"/>
</Table>
- <Table name="ticket" backup="yes" base="BarcodeTable">
+ <Table name="ticket" backup="yes" base="BarcodeTable" audit="yes">
<!--a 8-32 char code (code39: case-insensitive letters+digits) for the ticket-->
- <Column name="ticketid" type="string:32" primarykey="yes"/>
+ <Column name="ticketid" type="string:32" primarykey="yes">
+ <Call lang="php" method="BarcodeTable::getNewTicketId()"/>
+ </Column>
<Column name="eventid" type="int32" foreignkey="event:eventid"/>
<!--initially a copy from event, can be adjusted by seller-->
<Column name="price" type="int32" notnull="yes"/>
<!-- TODO: add check constraint that eventid,pricecategoryid exist in eventprice-->
</Table>
- <Table name="voucher" backup="yes" base="BarcodeTable">
+ <Table name="voucher" backup="yes" base="BarcodeTable" audit="yes">
<!--a 8-32 char code (code39: case-insensitive letters+digits) for the voucher-->
- <Column name="voucherid" type="string:32" primarykey="yes"/>
+ <Column name="voucherid" type="string:32" primarykey="yes">
+ <Call lang="php" method="BarcodeTable::getNewVoucherId()"/>
+ </Column>
<!--price of the voucher (0 if cancelled)-->
<Column name="price" type="int32" notnull="yes"/>
<!--order this voucher belongs to-->
<Column name="flags" type="string"/>
<Column name="tax" type="int32"/>
</Table>
- <Table name="item" backup="yes">
+ <Table name="item" backup="yes" audit="yes">
<Column name="itemid" type="seq64" primarykey="yes"/>
<Column name="productid" type="int32" foreignkey="product:productid" notnull="yes"/>
<Column name="orderid" type="int32" foreignkey="order:orderid" notnull="yes"/>
for(int i=0;i<cols.size();i++){
//automatic resolution of internal foreign keys
if(tbl.columnIsForeign(cols[i])){
- code+="public function get"+cols[i]+"(){\n\tglobal "+dbi+";\n\treturn WT";
+ code+="public function getObjectFor"+cols[i]+"(){\n\tglobal "+dbi+";\n\treturn WT";
QStringList foreign=tbl.columnForeign(cols[i]).split(":");
code+=foreign[0]+"::selectFromDB(\""+foreign[1]+"=\"."+dbi+"->escapeColumn(\""+foreign[0]+"\",\""+foreign[1]+"\",$this->"+cols[i]+"));\n}\n\n";
}
code+="const "+ens[i].first+"="+QString::number(ens[i].second)+";\n";
}
+ //hasproperty function
+ code+="public function hasProperty($p){switch($p){\n";
+ for(int i=0;i<cols.size();i++)
+ code+="\tcase \""+cols[i]+"\":\n";
+ QStringList aps=tbl.auditColumns();
+ for(int i=0;i<aps.size();i++)
+ code+="\tcase \""+aps[i]+"\":\n";
+ code+="\t\treturn true;\n\tdefault:return false;}}\n";
+
+ //create audit stuff
+ if(tbl.isAuditable()){
+ code+="public function isAuditable(){return true;}\n";
+ code+="protected function createAudit(){$ad=new WT"+tbl.name()+"_audit($this->data,false,\""+tbl.name()+"_audit\");\n";
+ code+="\treturn $ad->insert();\n}\n";
+ }
+
+ //create newKey function
+ code+="public function newKey(){\n\tparent::newKey();\n";
+ for(int i=0;i<cols.size();i++){
+ QString c=tbl.columnCall(cols[i],"php");
+ if(c=="")continue;
+ code+="\t$this->cdata[\""+cols[i]+"\"]="+c+";\n";
+ }
+ code+="}\n";
+
//write table class
code+="};\n";
tf.write(code.toAscii());
for(int i=0;i<k.size();i++){
code+="\nstatic public function fromTable"+k[i]+"($table){\n";
code+="\t$data=new WO"+cls.name()+"();\n";
- QList<QPair<QString,QString> >map=cls.mapping(k[i]);
- for(int j=0;j<map.size();j++){
- code+="\t$data->prop_"+map[j].second+"=$table->"+map[j].first+";\n";
+ QMap<QString,QString>map=cls.mapping(k[i]);
+ QStringList mapk=map.keys();
+ for(int j=0;j<mapk.size();j++){
+ QString meth=cls.mapMethod(k[i],mapk[j],"php");
+ if(meth!="")code+="\t$data->prop_"+mapk[j]+"="+meth+";\n";
+ else code+="\t$data->prop_"+mapk[j]+"=$table->"+map[mapk[j]]+";\n";
}
code+="\treturn $data;\n}\n";
code+="static public function fromTableArray"+k[i]+"(array $table){\n\t$ret=array();\n";
//getters/setters
tf.write(trnGetSet(trn).toAscii());
+ //direct execution
+ tf.write(trnExecute(trn).toAscii());
//end
code="\n//end of class\n}\n";
return code;
}
+
+QString WocPHPServerOut::trnExecute(const WocTransaction&trn)
+{
+ QStringList in=trn.inputNames();
+ QString code="static public function execute(";
+ for(int i=0;i<in.size();i++){
+ if(i)code+=",";
+ code+="$"+in[i];
+ }
+ code+=")\n{\n\t$inst=new "+trnClassName(trn)+";\n";
+ for(int i=0;i<in.size();i++)
+ code+="\t$this->ainput[\""+in[i]+"\"]=$"+in[i]+";\n";
+ code+="\tself::$running=\""+trn.name()+"\";\n";
+ code+="\t$inst->do_execute();\n";
+ code+="\tself::$running=\"\";\n";
+ code+="\treturn $inst;\n}\n";
+ code+="private function do_execute(){"+trn.callFunction("php")+"}\n";
+ return code;
+}
class QDomElement;
+/**generates output for a PHP server side*/
class WocPHPServerOut:public WocOutput
{
public:
+ /**initializes the output object*/
WocPHPServerOut(const QDomElement&);
protected:
+ /**writes any last words after parsing finished*/
virtual void finalize();
+ /**creates a class*/
virtual void newClass(const WocClass&);
+ /**creates a table*/
virtual void newTable(const WocTable&);
+ /**creates a transaction*/
virtual void newTransaction(const WocTransaction&);
private:
QString m_basedir,m_subdir,m_fileext;
QString trnOutput(const WocTransaction&);
/**helper: create getters and setters*/
QString trnGetSet(const WocTransaction&);
+ /**helper: create direct execution code for web interface*/
+ QString trnExecute(const WocTransaction&);
/**helper: return the PHP-class-name of a WocClass*/
QString className(const WocClass&c){return "WO"+c.name();}
m_tables.append(tbl);
emit newTable(tbl);
if(m_error)return false;
+ if(tbl.isAuditable()){
+ WocTable atbl=tbl.auditTable();
+ m_tables.append(atbl);
+ emit newTable(atbl);
+ if(m_error)return false;
+ }
}else
return false;
}else
m_dbSchema=el.attribute("schema","dbSchema");
if(el.hasAttribute("version"))
m_dbVer=el.attribute("version");
+ QDomNodeList nl=el.elementsByTagName("AuditTables");
+ for(int i=0;i<nl.size();i++)
+ WocTable::parseAuditStatic(nl.at(i).toElement());
}else
if(tn=="QtClientOutput"){
new WocQtClientOut(el);
m_valid=false;
return;
}
- QList<QPair<QString,QString> >map;
+ QList<s_map>map;
QDomNodeList nl2=el.elementsByTagName("Map");
for(int j=0;j<nl2.size();j++){
QDomElement el2=nl2.at(j).toElement();
if(el2.isNull())continue;
- QString col=el2.attribute("column");
- QString prp=el2.attribute("property");
- if(prp=="")prp=col;
- if(col=="")col=prp;
- if(col==""){
+ s_map sm;
+ sm.column=el2.attribute("column");
+ sm.property=el2.attribute("property");
+ if(sm.property=="")sm.property=sm.column;
+ if(sm.column=="")sm.column=sm.property;
+ if(sm.column==""){
qDebug("Warning: empty mapping in class %s mapping %s. Ignoring it.",m_name.toAscii().data(),name.toAscii().data());
continue;
}
- map.append(QPair<QString,QString>(col,prp));
+ QDomNodeList nl3=el2.elementsByTagName("Call");
+ for(int k=0;k<nl3.size();k++){
+ QDomElement el3=nl3.at(k).toElement();
+ if(el3.isNull())continue;
+ QString lang=el3.attribute("lang");
+ QString meth=el3.attribute("method","false");
+ sm.method.insert(lang,meth);
+ }
+ map.append(sm);
}
m_maps.insert(name,map);
}
else return false;
}
+QMap<QString,QString> WocClass::mapping(QString m)const
+{
+ if(!m_maps.contains(m))return QMap<QString,QString>();
+ QList<s_map> sml=m_maps[m];
+ QMap<QString,QString>ret;
+ for(int i=0;i<sml.size();i++)
+ ret.insert(sml[i].property,sml[i].column);
+ return ret;
+}
+
+QString WocClass::mapMethod(QString table,QString property,QString lang)const
+{
+ if(!m_maps.contains(table))return "";
+ QList<s_map> sml=m_maps[table];
+ for(int i=0;i<sml.size();i++)
+ if(sml[i].property==property){
+ if(sml[i].method.contains(lang))return sml[i].method[lang];
+ else return "";
+ }
+ return "";
+}
+
/******************************************************************************
* WocTable
WocTable::WocTable()
{
- m_backup=m_valid=false;
+ m_backup=m_valid=m_audit=false;
}
WocTable::WocTable(const QDomElement&tbl)
}
m_backup=str2bool(tbl.attribute("backup","0"));
m_base=tbl.attribute("base","WobTable");
+ m_audit=str2bool(tbl.attribute("audit","0"));
qDebug("Info: parsing table %s",m_name.toAscii().data());
- QDomNodeList nl=tbl.elementsByTagName("Column");
//Columns
+ QDomNodeList nl=tbl.elementsByTagName("Column");
for(int i=0;i<nl.size();i++){
QDomElement el=nl.at(i).toElement();
if(el.isNull())continue;
- s_col cl;
- cl.name=el.attribute("name");
- //check name syntax, check it is not doubled
- if(!good.exactMatch(cl.name)){
- qDebug("Error: table %s column %s does not have a regular name.",m_name.toAscii().data(),cl.name.toAscii().data());
+ QPair<bool,s_col> cl=parseColumn(el,m_name);
+ if(!cl.first)return;
+ if(hasColumn(cl.second.name)){
+ qDebug("Error: double definition of column %s in table %s.",cl.second.name.toAscii().data(),m_name.toAscii().data());
m_valid=false;
return;
}
- if(hasColumn(cl.name)){
- qDebug("Error: double definition of column %s in table %s.",cl.name.toAscii().data(),m_name.toAscii().data());
- m_valid=false;
- return;
- }
- cl.isprime=str2bool(el.attribute("primarykey","0"));
- cl.isunique=str2bool(el.attribute("unique","0"));
- cl.isindex=str2bool(el.attribute("index","0"));
- if(el.hasAttribute("null"))
- cl.isnull=str2bool(el.attribute("null"));
- else
- cl.isnull=!str2bool(el.attribute("notnull","0"));
- cl.type=el.attribute("type");
- //TODO: validate type
- cl.foreign=el.attribute("foreignkey");
- //check foreign key exists
- if(cl.foreign!=""){
- QStringList fgn=cl.foreign.split(":");
- if(fgn.size()!=2){
- qDebug("Error: table %s column %s: foreign key definition must use syntax 'table:column'",m_name.toAscii().data(),cl.name.toAscii().data());
- m_valid=false;
- return;
- }
- if(!woc->hasTable(fgn[0])){
- qDebug("Error: table %s column %s: foreign key target table %s does not exist",m_name.toAscii().data(),cl.name.toAscii().data(),fgn[0].toAscii().data());
- m_valid=false;
- return;
- }
- if(!woc->table(fgn[0]).hasColumn(fgn[1])){
- qDebug("Error: table %s column %s: foreign key target table/column %s does not exist",m_name.toAscii().data(),cl.name.toAscii().data(),cl.foreign.toAscii().data());
- m_valid=false;
- return;
- }
- }
- cl.defaultval=el.attribute("default");
- //TODO: validate default against type
- QDomNodeList nl2=el.elementsByTagName("Value");
- int nxval=0;
- //enum values
- for(int j=0;j<nl2.size();j++){
- QDomElement el2=nl2.at(j).toElement();
- if(el2.isNull())continue;
- QString n=el2.attribute("name");
- if(n==""){
- qDebug("Warning: anonymous enum value in table %s column %s. Ignoring it.",m_name.toAscii().data(),cl.name.toAscii().data());
- continue;
- }
- nxval=el2.attribute("value",QString::number(nxval)).toInt(0,0);
- cl.enumvals.append(QPair<QString,int>(n,nxval));
- nxval++;
- }
- m_columns.append(cl);
+ m_columns.append(cl.second);
+ }
+ //Audit Columns
+ nl=tbl.elementsByTagName("AuditColumn");
+ for(int i=0;i<nl.size();i++){
+ QDomElement el=nl.at(i).toElement();
+ if(el.isNull())continue;
+ QPair<bool,s_col> cl=parseColumn(el,m_name);
+ if(!cl.first)return;
+ m_auditcolumns.append(cl.second);
}
//Foreign getter methods
}
}
+
+QPair<bool,WocTable::s_col> WocTable::parseColumn(const QDomElement&el,QString m_name)
+{
+ s_col cl;
+ QRegExp good("[a-z][a-z0-9_]*",Qt::CaseInsensitive);
+ cl.name=el.attribute("name");
+ //check name syntax, check it is not doubled
+ if(!good.exactMatch(cl.name)){
+ qDebug("Error: table %s column %s does not have a regular name.",m_name.toAscii().data(),cl.name.toAscii().data());
+ return QPair<bool,s_col>(false,s_col());
+ }
+ cl.isprime=str2bool(el.attribute("primarykey","0"));
+ cl.isunique=str2bool(el.attribute("unique","0"));
+ cl.isindex=str2bool(el.attribute("index","0"));
+ if(el.hasAttribute("null"))
+ cl.isnull=str2bool(el.attribute("null"));
+ else
+ cl.isnull=!str2bool(el.attribute("notnull","0"));
+ cl.type=el.attribute("type");
+ //TODO: validate type
+ cl.foreign=el.attribute("foreignkey");
+ WocProcessor*woc=WocProcessor::instance();
+ //check foreign key exists
+ if(cl.foreign!=""){
+ QStringList fgn=cl.foreign.split(":");
+ if(fgn.size()!=2){
+ qDebug("Error: table %s column %s: foreign key definition must use syntax 'table:column'",m_name.toAscii().data(),cl.name.toAscii().data());
+ return QPair<bool,s_col>(false,s_col());
+ }
+ if(!woc->hasTable(fgn[0])){
+ qDebug("Error: table %s column %s: foreign key target table %s does not exist",m_name.toAscii().data(),cl.name.toAscii().data(),fgn[0].toAscii().data());
+ return QPair<bool,s_col>(false,s_col());
+ }
+ if(!woc->table(fgn[0]).hasColumn(fgn[1])){
+ qDebug("Error: table %s column %s: foreign key target table/column %s does not exist",m_name.toAscii().data(),cl.name.toAscii().data(),cl.foreign.toAscii().data());
+ return QPair<bool,s_col>(false,s_col());
+ }
+ }
+ cl.defaultval=el.attribute("default");
+ //TODO: validate default against type
+ QDomNodeList nl2=el.elementsByTagName("Value");
+ int nxval=0;
+ //enum values
+ for(int j=0;j<nl2.size();j++){
+ QDomElement el2=nl2.at(j).toElement();
+ if(el2.isNull())continue;
+ QString n=el2.attribute("name");
+ if(n==""){
+ qDebug("Warning: anonymous enum value in table %s column %s. Ignoring it.",m_name.toAscii().data(),cl.name.toAscii().data());
+ continue;
+ }
+ nxval=el2.attribute("value",QString::number(nxval)).toInt(0,0);
+ cl.enumvals.append(QPair<QString,int>(n,nxval));
+ nxval++;
+ }
+ //default calls
+ nl2=el.elementsByTagName("Call");
+ for(int j=0;j<nl2.size();j++){
+ QDomElement el2=nl2.at(j).toElement();
+ if(el2.isNull())continue;
+ QString lang=el2.attribute("lang");
+ QString meth=el2.attribute("method","false");
+ cl.methodcalls.insert(lang,meth);
+ }
+
+ return QPair<bool,s_col>(true,cl);
+}
+
QStringList WocTable::columns()const
{
QStringList r;
return r;
}
+QStringList WocTable::auditColumns()const
+{
+ QStringList r;
+ for(int i=0;i<m_staticauditcolumns.size();i++)
+ r<<m_staticauditcolumns[i].name;
+ for(int i=0;i<m_auditcolumns.size();i++)
+ r<<m_auditcolumns[i].name;
+ return r;
+}
+
QStringList WocTable::primaryColumns()const
{
QStringList r;
return false;
}
+QString WocTable::columnCall(QString col,QString lang)const
+{
+ for(int i=0;i<m_columns.size();i++){
+ s_col cl=m_columns[i];
+ if(cl.name==col){
+ if(!cl.methodcalls.contains(lang))return "";
+ else return cl.methodcalls[lang];
+ }
+ }
+ return "";
+}
+
+QList<WocTable::s_col>WocTable::m_staticauditcolumns;
+void WocTable::parseAuditStatic(const QDomElement&el)
+{
+ QDomNodeList nl=el.elementsByTagName("Column");
+ for(int i=0;i<nl.size();i++){
+ QDomElement el2=nl.at(i).toElement();
+ if(el2.isNull())continue;
+ QPair<bool,s_col>cl=parseColumn(el2,"(global audit settings)");
+ if(!cl.first){
+ WocProcessor::instance()->errorFound();
+ return;
+ }
+ m_staticauditcolumns.append(cl.second);
+ }
+}
+
+WocTable WocTable::auditTable()const
+{
+ WocTable adt;
+ adt.m_valid=m_valid;
+ adt.m_backup=m_backup;
+ adt.m_audit=false;
+ adt.m_name=m_name+"_audit";//enhance the name
+ adt.m_base="WobTable";//revert to default
+ adt.m_foreign=m_foreign;
+ //these stay empty: m_presets, m_auditcolumns
+
+ //now for the complicated stuff
+ //create primary key
+ s_col cl;
+ cl.name="auditid";cl.type="seq64";
+ cl.isindex=cl.isunique=cl.isnull=false;cl.isprime=true;
+ adt.m_columns.append(cl);
+ //copy common columns
+ adt.m_columns.append(m_staticauditcolumns);
+ //copy normal columns
+ for(int i=0;i<m_columns.size();i++){
+ //get and reset
+ cl=m_columns[i];
+ cl.isprime=cl.isunique=false;
+ cl.methodcalls.clear();
+ if(cl.type.left(3)=="seq")cl.type="int"+cl.type.mid(3);
+ //add
+ adt.m_columns.append(cl);
+ }
+ //copy local audit columns
+ adt.m_columns.append(m_auditcolumns);
+
+ //return result
+ return adt;
+}
+
/******************************************************************************
* WocTransaction
bool hasMapping(QString m)const{return m_maps.contains(m);}
/**returns the names of all tables for which a mapping exists*/
QStringList mappingTables()const{return m_maps.keys();}
- /**returns the specific mapping*/
- QList<QPair<QString,QString> >mapping(QString m)const{return m_maps[m];}
+ /**returns the specific mapping; map key=property, map value=column*/
+ QMap<QString,QString> mapping(QString m)const;
+ /**returns the method for a specific mapping or an empty string if it does not exist in the specified language*/
+ QString mapMethod(QString table,QString property,QString lang)const;
private:
//valid: parsing the WOLF succeeded
};
QList<s_prop> m_props;
//mappings: "table-name" => List of ("column-name","property-name")
- QMap<QString,QList<QPair<QString,QString> > >m_maps;
+ struct s_map{
+ QString column,property;
+ QMap<QString,QString>method;//lang->method
+ };
+ QMap<QString,QList<s_map> >m_maps;
//enum types: "type-name" => List of ("constant-name",int-constant-value)
QMap<QString,QList<QPair<QString,int> > >m_enumvals;
//serializers: "name" => List of properties (syntax Objects: "propertyname/Serializer"
bool columnIsUnique(QString)const;
/**returns enum definitions of the column - each pair contains the symbolic name in first and the assigned integer value in second*/
QList<QPair<QString,int> > columnEnums(QString)const;
+ /**returns the insert call of a column for a specific language; empty string if there is none*/
+ QString columnCall(QString col,QString lang)const;
/**returns all enum definitions of the table; see also columnEnums */
QList<QPair<QString,int> > getEnums()const;
/**returns a list of all preset values (to be generated when the DB is created);
each entry in the list is a dictionary with the column name as key and the intended preset value as value - each entry of the list is one DB row, each key-value-pair in the map is one preset value in that row*/
QList<QMap<QString,QString> > presets()const{return m_presets;}
+
+ /**parses the static part of auditing*/
+ static void parseAuditStatic(const QDomElement&);
+ /**returns whether the table is auditable*/
+ bool isAuditable()const{return m_audit;}
+ /**creates and returns the table instance that represents the audit table*/
+ WocTable auditTable()const;
+ /**returns the names of audit columns (except auditid)*/
+ QStringList auditColumns()const;
private:
- bool m_valid,m_backup;
+ bool m_valid,m_backup,m_audit;
QString m_name,m_base;
struct s_col {
QString name,type,foreign,defaultval;
bool isnull,isprime,isindex,isunique;
QList<QPair<QString,int> >enumvals;
+ QMap<QString,QString>methodcalls;
};
- QList<s_col>m_columns;
+ QList<s_col>m_columns,m_auditcolumns;
+ static QList<s_col>m_staticauditcolumns;
QList<QPair<QString,QString> >m_foreign;
QList<QMap<QString,QString> >m_presets;
+
+ //helper method: parses a single column element
+ static QPair<bool,s_col> parseColumn(const QDomElement&,QString);
};
/**internal representation of a transaction*/
void newClass(const WocClass&);
void newTable(const WocTable&);
void newTransaction(const WocTransaction&);
- private slots:
+ public slots:
void errorFound();
private:
QString m_baseDir,m_wobDir,m_verComm,m_verNeedComm,m_verHR,m_projname;
//
$AUTOCLASS["DbEngine"]='./inc/db/db.php';
$AUTOCLASS["MysqlEngine"]='./inc/db/db_mysql.php';
+$AUTOCLASS["BarcodeTable"]='./inc/db/barcodetable.php';
include('./inc/db/db_scheme.php');
?>
\ No newline at end of file
--- /dev/null
+<?
+//
+// PHP Implementation: barcodetable
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+class BarcodeTable extends WobTable
+{
+ private static $NumTicketChars=false;
+ private static function init()
+ {
+ if(self::$NumTicketChars===false){
+ self::$NumTicketChars=$db->getConfig("TicketIDChars")+0;
+ if(self::$NumTicketChars<=5)self::$NumTicketChars=10;
+ }
+ }
+ public static function getNewTicketId()
+ {
+ self::init();
+ do{
+ $tid=getCode39ID(self::$NumTicketChars,RND_TICKET);
+ $res=$db->select("ticket","ticketid","ticketid=".$db->escapeString($tid));
+ if(count($res)==0)return $tid;
+ }while(true);
+ }
+ public static function getNewVoucherId()
+ {
+ self::init();
+ do{
+ $tid=getCode39ID(self::$NumTicketChars,RND_VOUCHER);
+ $res=$db->select("voucher","voucherid","voucherid=".$db->escapeString($tid));
+ if(count($res)==0)return $tid;
+ }while(true);
+ }
+};
+
+?>
\ No newline at end of file
$cm="";
$val=") VALUES (";
while(list($k,$v)=each($values)){
+ //make sure the column exists, ignore the riff-raff
+ if(!$dbScheme->tableHasColumn($table,$k))continue;
$ret.=$cm;$val.=$cm;$cm=",";
//append column name
$ret.=$k;
reset($values);
$cm="";
while(list($k,$v)=each($values)){
+ //make sure the column exists, ignore the riff-raff
+ if(!$dbScheme->tableHasColumn($table,$k))continue;
$ret.=$cm;$cm=",";
//append column name
$ret.=$k."=";
/**The session class*/
class Session
{
- private $sessid="";
- private $user="";
- private $roles;
- private $rights;
+ protected $sessid="";
+ protected $user="";
+ protected $roles;
+ protected $rights;
/**construct the session object, check validity*/
public function __construct($trans)
return $session;
}
+ /**return the name of the currently logged in user*/
+ public static function currentUserName()
+ {
+ global $session;
+ if(isset($session))return $session->getUser();
+ else return "(unknown)";
+ }
+
+ /**initialize system in web session mode (ie. some user called the web page in a browser)*/
+ public static function setWebSession()
+ {
+ global $session;
+ $session=new DummyWebSession;
+ }
+
/**internal: retrieve and remember the rights of this user*/
protected function initRights()
{
/**returns all roles of this user*/
public function getRoles(){return $this->roles;}
- /**creates a new session*/
+ /**creates a new session, called from the Login transaction*/
static public function login($trans)
{
global $db,$ClientSessionTimeout;
$hosts[]=$hst["host"];
//logic check 1: abort if host is unknown
if(count($hres)==0){
- $trans->abortWithError(translate("php::","Unknown Host"),"auth");
+ $trans->abortWithError(translate("Session","Unknown Host"),"auth");
}
//logic check: login is allowed if
// a) $hosts contains _any and the host is known, or
// b) $hosts contains the transmitted host name
$hostname=$trans->gethostname();
if( !in_array($hostname,$hosts) && !in_array("_any",$hosts)){
- $trans->abortWithError(translate("php::","Host/User combination not allowed"),"auth");
+ $trans->abortWithError(translate("Session","Host/User combination not allowed"),"auth");
}
//validate host
$splt=explode(" ",$hres[0]["hostkey"]);
if(count($splt)!=2){
- $trans->abortWithError(translate("php::","Host authentication failed"),"auth");
+ $trans->abortWithError(translate("Session","Host authentication failed"),"auth");
}
$cmp=strtolower(sha1($splt[0].$trans->gethostkey()));
if($cmp != strtolower($splt[1])){
- $trans->abortWithError(translate("php::","Host authentication failed"),"auth");
+ $trans->abortWithError(translate("Session","Host authentication failed"),"auth");
}
//get user data
$ures=$db->select("user","*","uname=".$db->escapeString($trans->getusername()));
if(count($ures)<1){
- $trans->abortWithError(translate("php::","User Authentication failed"),"auth");
+ $trans->abortWithError(translate("Session","User Authentication failed"),"auth");
}
//validate user
$splt=explode(" ",$ures[0]["passwd"]);
if(count($splt)!=2){
- $trans->abortWithError(translate("php::","User Authentication failed"),"auth");
+ $trans->abortWithError(translate("Session","User Authentication failed"),"auth");
}
$cmp=strtolower(sha1($splt[0].$trans->getpassword()));
if($cmp!=strtolower($splt[1])){
- $trans->abortWithError(translate("php::","User Authentication failed"),"auth");
+ $trans->abortWithError(translate("Session","User Authentication failed"),"auth");
}
//create session and return
return $this->user!="";
}
- /**helper function for authenticate*/
- protected function xdie($str)
- {
- //debug version:
-// print($str);
- //all versions
- exit();
- }
-
- /**set my own password*/
+ /**set my own password; called from SetMyPasswd transaction*/
public function setMyPasswd($trans)
{
$old=$trans->getoldpassword();
}
};
-//return all users to client
-function getAllUsersXml()
-{
- global $db;
- header("X-MagicSmoke-Status: Ok");
- $res=$db->select("users","uname,description","");
- $dom=new DomDocument;
- $root=$dom->createElement("Users");
- for($i=0;$i<count($res);$i++){
- $usr=$dom->createElement("User",xq($res[$i]["description"]));
- $usr->setAttributeNode(new DOMAttr("name",$res[$i]["uname"]));
- $root->appendChild($usr);
- }
- $dom->appendChild($root);
- print($dom->saveXML());
-}
-
-//return the roles of a specific user
-function getUserAclXml($user)
+/**dummy class used by browsed pages to represent the virtual web user*/
+class DummyWebSession extends Session
{
- //sanity check
- $user=trim($user);
- if(ereg("^[A-Za-z0-9_\\.,:-]+$",$user)===false){
- header("X-MagicSmoke-Status: SyntaxError");
- die(tr("invalid user name"));
- }
- //go on...
- global $db,$ALLOWEDREQUESTS,$SPECIALROLES;
- header("X-MagicSmoke-Status: Ok");
- //create list of roles
- $roles=$ALLOWEDREQUESTS;
- foreach($SPECIALROLES as $rl)
- $roles[]=$rl;
- //get roles from DB
- $res=$db->select("userrole","role","uname=".$db->escapeString($user));
- $acl=array();
- foreach($res as $rl)$acl[]=$rl["role"];
- $dom=new DOMDocument;
- $root=$dom->createElement("ACL");
- $root->setAttributeNode(new DOMAttr("user",$user));
- foreach($roles as $rl){
- $re=$dom->createElement("Role");
- $re->setAttributeNode(new DOMAttr("name",$rl));
- if(array_search($rl,$acl)===false)$re->setAttributeNode(new DOMAttr("set","0"));
- else $re->setAttributeNode(new DOMAttr("set","1"));
- $root->appendChild($re);
- }
- $dom->appendChild($root);
- print($dom->saveXML());
-}
-
-//set the ACL of a user
-function setUserAclXml($txt)
-{
- //DOM
- $xml=new DOMDocument;
- if(!$xml->loadXML($txt)){
- header("X-MagicSmoke-Status: SyntaxError");
- die(tr("unable to parse XML data"));
- }
- //get user name
- $acl=$xml->getElementsByTagName("ACL");
- if($acl->length != 1){
- header("X-MagicSmoke-Status: SyntaxError");
- die(tr("expected exactly 1 ACL element"));
- }
- global $db,$ALLOWEDREQUESTS,$SPECIALROLES;
- $roles=$ALLOWEDREQUESTS;
- foreach($SPECIALROLES as $rl)
- $roles[]=$rl;
- $usr=$acl->item(0)->getAttribute("user");
- //check user name
- $db->beginTransaction();
- $res=$db->select("users","count(uname)","uname=".$db->escapeString($usr));
- if($res[0][0]!=1){
- header("X-MagicSmoke-Status: SyntaxError");
- $db->rollbackTransaction();
- die(tr("unknown user name"));
- }
- //update roles
- $acl=$xml->getElementsByTagName("Role");
- for($i=0;$i<$acl->length;$i++){
- //does role exist?
- $name=$acl->item($i)->getAttribute("name");
- if(array_search($name,$roles)===false)continue;
- $isset=$acl->item($i)->getAttribute("set")+0;
- if($isset){
- $res=$db->select("userrole","count(role)","uname=".$db->escapeString($usr)." AND role=".$db->escapeString($name));
- if($res[0][0]!=0)continue;
- $db->insert("userrole",array("uname"=>$usr,"role"=>$name));
- }else{
- $db->deleteRows("userrole","uname=".$db->escapeString($usr)." AND role=".$db->escapeString($name));
- }
- }
- $db->commitTransaction();
- header("X-MagicSmoke-Status: Ok");
-}
-
-//return the hosts of a specific user
-function getUserHostsXml($user)
-{
- //sanity check
- $user=trim($user);
- if(ereg("^[A-Za-z0-9_\\.,:-]+$",$user)===false){
- header("X-MagicSmoke-Status: SyntaxError");
- die(tr("invalid user name"));
- }
- //go on...
- global $db;
- header("X-MagicSmoke-Status: Ok");
- //create list of hosts
- $hosts=array();
- $res=$db->select("host","hostname","");
- for($i=0;$i<count($res);$i++){
- $hosts[]=$res[$i]["hostname"];
- }
- //get roles from DB
- $res=$db->select("userhosts","host","uname=".$db->escapeString($user));
- $acl=array();
- foreach($res as $rl)$acl[]=$rl["host"];
- $dom=new DOMDocument;
- $root=$dom->createElement("Hosts");
- $root->setAttributeNode(new DOMAttr("user",$user));
- foreach($hosts as $hs){
- $re=$dom->createElement("Host");
- $re->setAttributeNode(new DOMAttr("name",$hs));
- if(array_search($hs,$acl)===false)$re->setAttributeNode(new DOMAttr("set","0"));
- else $re->setAttributeNode(new DOMAttr("set","1"));
- $root->appendChild($re);
- }
- $dom->appendChild($root);
- print($dom->saveXML());
-}
-
-//set the Hosts of a user
-function setUserHostsXml($txt)
-{
- //DOM
- $xml=new DOMDocument;
- if(!$xml->loadXML($txt)){
- header("X-MagicSmoke-Status: SyntaxError");
- die(tr("unable to parse XML data"));
- }
- //get user name
- $acl=$xml->getElementsByTagName("Hosts");
- if($acl->length != 1){
- header("X-MagicSmoke-Status: SyntaxError");
- die(tr("expected exactly 1 Hosts element"));
- }
- global $db;
- //create list of hosts
- $hosts=array();
- $res=$db->select("host","hostname","");
- for($i=0;$i<count($res);$i++){
- $hosts[]=$res[$i]["hostname"];
- }
- $usr=$acl->item(0)->getAttribute("user");
- //check user name
- $db->beginTransaction();
- $res=$db->select("users","count(uname)","uname=".$db->escapeString($usr));
- if($res[0][0]!=1){
- header("X-MagicSmoke-Status: SyntaxError");
- $db->rollbackTransaction();
- die(tr("unknown user name"));
- }
- //update roles
- $acl=$xml->getElementsByTagName("Host");
- for($i=0;$i<$acl->length;$i++){
- //does role exist?
- $name=$acl->item($i)->getAttribute("name");
- if(array_search($name,$hosts)===false)continue;
- $isset=$acl->item($i)->getAttribute("set")+0;
- if($isset){
- $res=$db->select("userhosts","count(host)","uname=".$db->escapeString($usr)." AND host=".$db->escapeString($name));
- if($res[0][0]!=0)continue;
- $db->insert("userhosts",array("uname"=>$usr,"host"=>$name));
- }else{
- $db->deleteRows("userhosts","uname=".$db->escapeString($usr)." AND host=".$db->escapeString($name));
- }
- }
- $db->commitTransaction();
- header("X-MagicSmoke-Status: Ok");
-}
-
-//helper function: parse User-XML-structure
-function parseUserXml($txt)
-{
- $xml=new DOMDocument;
- if(!$xml->loadXML($txt)){
- header("X-MagicSmoke-Status: SyntaxError");
- die(tr("unable to parse XML data"));
- }
- $ret=array();
- foreach($xml->getElementsByTagName("User") as $el){
- $usr["name"]=$el->getAttribute("name");
- $usr["descr"]="";
- $usr["passwd"]=$el->getAttribute("passwd");
- foreach($el->childNodes as $cn)
- if($cn->nodeType==XML_TEXT_NODE)
- $usr["descr"]=$cn->wholeText;
- $ret[]=$usr;
- }
- return $ret;
-}
-
-//set new description for user
-function setUserDescrXml($txt)
-{
- global $db;
- $usr=parseUserXml($txt);
- for($i=0;$i<count($usr);$i++){
- $db->update("users",array("description"=>$usr[$i]["descr"]),"uname=".$db->escapeString($usr[$i]["name"]));
- }
- header("X-MagicSmoke-Status: Ok");
-}
-
-//add a new user
-function addUserXml($txt)
-{
- global $db;
- $usr=parseUserXml($txt);
- $dom=new DOMDocument;
- $root=$dom->createElement("Users");
- for($i=0;$i<count($usr);$i++){
- //syntax check
- if(ereg("^[A-Za-z0-9_\\.,:-]+$",$usr[$i]["name"])===false)continue;
- //existance check
- $db->beginTransaction();
- $res=$db->select("users","uname","uname='".$usr[$i]["name"]."'");
- if(count($res)==0){
- //create new
- $db->insert("users",array("uname"=>$usr[$i]["name"],"description"=>$usr[$i]["descr"],"passwd"=>$usr[$i]["passwd"]));
- //print data
- $udm=$dom->createElement("User",xq($usr[$i]["descr"]));
- $udm->setAttributeNode(new DOMAttr("name",$usr[$i]["name"]));
- $root->appendChild($udm);
- }
- $db->commitTransaction();
- }
- $dom->appendChild($root);
- print($dom->saveXML());
- header("X-MagicSmoke-Status: Ok");
-}
-
-//delete a user
-function deleteUserXml($txt)
-{
- global $db;
- $lst=explode("\n",trim($txt));
- if($lst===false || count($lst)<1){
- header("X-MagicSmoke-Status: SyntaxError");
- echo tr("Syntax Error");
- return;
- }
- $usr=trim($lst[0]);
- if(count($lst)>1)$nusr=trim($lst[1]);
- else $nusr=false;
- //start transaction
- $db->beginTransaction();
- $b=true;
- //delete ACL
- $b &= $db->deleteRows("userrole","uname=".$db->escapeString($usr)) !== false;
- //delete Hosts
- $b &= $db->deleteRows("userhosts","uname=".$db->escapeString($usr)) !== false;
- //delete open sessions
- $b &= $db->deleteRows("session","user=".$db->escapeString($usr)) !== false;
- //check for success so far
- if(!$b){
- $db->rollbackTransaction();
- echo tr("Cannot remove user: DB error while deleting ACL.");
- return;
- }
- //re-assign DB objects
- $b &= $db->update("order",array("soldby"=>$nusr),"soldby=".$db->escapeString($usr)) !== false;
- $b &= $db->update("order",array("depositat"=>$nusr),"depositat=".$db->escapeString($usr)) !== false;
- $b &= $db->update("ticket",array("reservedby"=>$nusr),"reservedby=".$db->escapeString($usr)) !== false;
- if(!$b){
- header("X-MagicSmoke-Status: Error");
- echo tr("Cannot remove user: unable to replace user.");
- //end transaction
- $db->rollbackTransaction();
- return;
- }
- //attempt to delete User itself
- $b=$db->deleteRows("users","uname=".$db->escapeString($usr)) !== false;
- //say OK or not OK now
- if($b){
- header("X-MagicSmoke-Status: Ok");
- //end transaction
- $db->commitTransaction();
- }else{
- header("X-MagicSmoke-Status: Error");
- echo tr("Cannot remove user: DB error while deleting user.");
- //end transaction
- $db->rollbackTransaction();
- }
-}
-
-//set another users passwd
-function setPasswdXml($txt)
-{
- global $db;
- //parse XML
- $dom=new DOMDocument;
- if(!$dom->loadXML($txt)){
- header("X-MagicSmoke-Status: SyntaxError");
- die(tr("unable to parse XML data"));
- }
- $nl=$dom->getElementsByTagName("SetPasswd");
- if($nl->length!=1){
- header("X-MagicSmoke-Status: SyntaxError");
- die(tr("expected exactly one passwd element"));
- }
- $spw=$nl->item(0);
- $usr=$spw->getAttribute("user");
- $nwp=$spw->getAttribute("newpwd");
- //sanity check
- if($nwp==""){
- header("X-MagicSmoke-Status: SyntaxError");
- die(tr("cannot set an empty password"));
+ public function __construct()
+ {
+ $this->user="(web)";
+ //fake admin, because web pages do their own checks
+ //TODO: do something more sensible (eg. _web role)
+ $this->roles=array("_admin");
+ $this->rights=array();
}
- //set new password
- if($db->update("users",array("passwd"=>$nwp),"uname=".$db->escapeString($usr))===false){
- header("X-MagicSmoke-Status: Error");
- die(tr("Unable to change this password."));
- }else
- header("X-MagicSmoke-Status: Ok");
}
?>
\ No newline at end of file
//
//
+/**thrown by WobTable if a property change is out of range*/
class ValueOutOfRange extends Exception
{
public function __construct($tab,$col,$val)
}
};
-class WobTable
+/**parent class of all tables*/
+abstract class WobTable
{
private $data;
+ private $cdata;
private $isfromdb;
private $table;
+ /**constructs a basic table*/
protected function __construct(array $data,$isfromdb,$table)
{
$this->data=$data;
$this->isfromdb=$isfromdb;
$this->table=$table;
+ $this->cdata=array();
}
+ /**set properties*/
public function __set($name,$value)
{
- global $db,$dbScheme;
- //verify name against scheme
- if(!$dbScheme->tableHasColumn($this->table,$name))return;
- //verify enum vals
+ //check for property
+ if(!$this->hasProperty($name)){
+ $trace=debug_backtrace();
+ trigger_error("Trying to set undefined property ".$name." in ".$trace[0]['file']." on line ".$trace[0]['line'],E_USER_NOTICE);
+ }
+ //verify value (TODO: what about NULL?)
$vm="verifyValue".$name;
if(method_exists($this,$vm))
- if(!$t->$vm($value))
+ if(!$this->$vm($value))
throw ValueOutOfRange($this->table,$name,$value);
- //DB update (if from DB)
- $succ=true;
- if($this->isfromdb){
- $succ=$db->update($this->table,array($name => $value),$this->where());
+ //set
+ $this->cdata[$name]=$value;
+ }
+
+ /**reverts changes to the property*/
+ public function revert($name)
+ {
+ if(!$this->hasProperty($name)){
+ $trace=debug_backtrace();
+ trigger_error("Trying to revert undefined property ".$name." in ".$trace[0]['file']." on line ".$trace[0]['line'],E_USER_NOTICE);
}
- //if successful: store
- if($succ)$this->data[$name]=$value;
+ if(array_key_exists($name,$this->cdata))unset($this->cdata[$name]);
}
+ /**reverts all changes to properties*/
+ public function revertAll()
+ {
+ $this->cdata=array();
+ }
+
+ /**returns the name of the table*/
+ public function tableName(){return $this->table;}
+
+ /**returns whether the table contains a specific column*/
+ public function hasColumn($c)
+ {
+ global $dbScheme;
+ return $dbScheme->tableHasColumn($this->table,$name);
+ }
+
+ /**overridden by woc, returns true if the property exists*/
+ abstract public function hasProperty($c);
+
+ /**returns whether this is an auditable table*/
+ public function isAuditable(){return false;}
+
+ /**overridden by woc, if this an auditable table; used in insert and update*/
+ protected function createAudit(){}
+
+ /**returns the where clause to find this instance (via primary key columns)*/
public function where()
{
global $dbScheme,$db;
return $r;
}
+ /**returns the property*/
public function __get($name)
{
//verify name
+ if(!$this->hasProperty($name)){
+ $trace=debug_backtrace();
+ trigger_error("Accessing undefined property ".$name." in ".$trace[0]['file']." on line ".$trace[0]['line'],E_USER_NOTICE);
+ }
//return value or null
- if(isset($this->data[$name]))return $this->data[$name];
+ if(array_key_exists($name,$this->cdata))return $this->cdata[$name];
+ if(array_key_exists($name,$this->data))return $this->data[$name];
else return null;
}
{
global $db;
//verify name and return true on existence AND notnull
- if(isset($this->data[$name]))return !$db->isNull($this->data[$name]);
+ if(array_key_exists($name,$this->cdata))return isset($this->cdata[$name]);
+ if(array_key_exists($name,$this->data))return isset($this->data[$name]);
else return false;
}
{
global $dbScheme;
//reset to null
- if($dbScheme->tableHasColumn($name))$this->data[$name]=null;
+ if($this->hasProperty($name))$this->cdata[$name]=null;
}
/**insert the object under a new primary key value into the DB (implicitly calls newKey); returns true on success*/
public function insert()
{
- //remove PK from object (so it is set to default)
global $dbScheme;
$this->isfromdb=false;
- $pk=$dbScheme->primaryKeyColumns($this->table);
- foreach($pk as $c)unset($this->data[$c]);
- //optionally create new key
+ //create new key
$this->newKey();
//now insert
- $r=$db->insert($this->table,$this->data);
+ $data=array();
+ foreach($this->data as $k=>$d)$data[$k]=$d;
+ foreach($this->cdata as $k=>$d)$data[$k]=$d;
+ $r=$db->insert($this->table,$data);
if($r===false)return false;
- //TODO: make this a bit more safe:
- if($r!==true)$this->data[$pk[0]]=$r;
+ $this->isfromdb=true;
+ $this->data=$data;
+ $this->cdata=array();
+ createAudit();
+ //assign primary key if sequence (otherwise newKey has done it)
+ $seq=$dbScheme->hasSequence($this->table);
+ if($seq!==false)
+ $this->data[$seq]=$r;
+ //return success
return true;
}
- /**generate a new primary key value for insert and marks the object as not yet in the DB; the default sets the primary key to NULL; call the original first if you overwrite it*/
+ /**generate a new primary key value for insert and marks the object as not yet in the DB; the default sets the primary key to NULL if it is a sequence; call the original first if you overwrite it*/
public function newKey()
{
+ $this->isfromdb=false;
+ $pk=$dbScheme->hasSequence($this->table);
+ if($pk!==false){
+ if(array_key_exists($pk,$this->data))unset($this->data[$pk]);
+ if(array_key_exists($pk,$this->cdata))unset($this->cdata[$pk]);
+ }
+ }
+
+ /**updates the object in the database; returns true on success; fails if it did not come from the DB - use insertOrUpdate in this case; succeeds without asking the database if nothing has changed*/
+ public function update()
+ {
+ if(!$this->isfromdb)return false;
+ if(count($this->cdata)==0)return true;
+ global $db;
+ $succ=$db->update($this->table,$this->cdata,$this->where())!==false;
+ if($succ){
+ foreach($this->cdata as $k=>$d)$this->data[$k]=$d;
+ $this->cdata=array();
+ createAudit();
+ }
+ return $succ;
+ }
+
+ /**updates existing object in the database or inserts it if it does not exist in the DB yet*/
+ public function insertOrUpdate()
+ {
+ if($this->isfromdb)return $this->update();
+ else return $this->insert();
+ }
+
+ /**deletes this instance from the database; returns true if it actually executed*/
+ public function deleteFromDb()
+ {
+ if(!$this->isfromdb)return false;
+ global $db;
+ //obliterate audit data
+ if($this->isAuditable())
+ $db->deleteRows($this->table."_audit",$this->where());
+ //delete data
+ $db->deleteRows($this->table,$this->where());
+ //mark as outsider
+ $this->isfromdb=false;
+ return true;
}
};
protected $aoutput;
protected $toutput;
+ protected static $running="";
+
+ static public function getExecutingName(){return self::$running;}
+
/**called to determine the correct transaction, aborts the script if there is none.*/
static public function getTransactionName(){
global $_SERVER;
print("<WobResponse status=\"error\"><Error type=\"non-wob\">Request is not a Wob Request, Aborting.</Error></WobResponse>\n");
exit();
}
- return $_SERVER["HTTP_X_WOBREQUEST"];
+ self::$running=$_SERVER["HTTP_X_WOBREQUEST"];
+ return self::$running;
}
/**called to determine the session id*/
static public function getHeader($hd)
$lang->setLanguage("de");
+Session::setWebSession();
+
//get page template and process it
switch($mode){
case "eventDetails":