diff --git a/res/update.template b/res/update.template
new file mode 100644
index 0000000..007f149
--- /dev/null
+++ b/res/update.template
@@ -0,0 +1,16 @@
+
+ SLT Vereinsverwaltung
+ Vereinsportal des saarländischen Tanzsportverbands
+ com_clubs
+ component
+ 0
+ __VERSION__
+
+ __DOWNLOAD_URL__
+
+
+ stable
+
+ Christian Wolf
+
+
diff --git a/scripts/create-release.sh b/scripts/create-release.sh
new file mode 100755
index 0000000..122d8a9
--- /dev/null
+++ b/scripts/create-release.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+MAJOR=`cat serial/major`
+MINOR=`cat serial/minor`
+RELEASE=`cat serial/release`
+TOTRELEASE="$MAJOR.$MINOR.$RELEASE"
+
+outname="releases/clubs-$TOTRELEASE.tar.gz"
+
+mkdir -p releases
+
+# First check if the named release exists already
+if [ -f "$outname" ]; then
+ if [ "$1" = '-f' ]; then
+ echo "Overwriting existing file $outname."
+ else
+ echo "The file $outname existes already. Either remove the release from the folder manually or increase the release version."
+ echo "Aborting."
+ exit 1
+ fi
+fi
+
+cp clubs.tar.gz "$outname"
diff --git a/scripts/create-update-xml.sh b/scripts/create-update-xml.sh
new file mode 100755
index 0000000..42ad43a
--- /dev/null
+++ b/scripts/create-update-xml.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# DL_PREFIX="https://slt.wolf-stuttgart.net/update/template"
+
+cat res/prefix.template > slt-update.xml
+
+find releases -name clubs-\* | while read f
+do
+
+ VSTR=`echo "$f" | sed -E 's@releases/clubs-@@; s@^([0-9]+\.[0-9]+\.[0-9]+).*$@\1@'`
+
+ FILE=`echo "$f" | sed 's@releases/@@'`
+ FORMAT=`echo "$f" | sed -E 's@^.*[0-9]+\.[0-9]+\.[0-9]+\.@@'`
+
+ sed '
+ s@__VERSION__@'"$VSTR"'@g;
+ s@__DOWNLOAD_URL__@'"$DL_PREFIX/files/$FILE"'@g;
+ s@__FORMAT__@'"$FORMAT"'@g
+ ' res/update.template >> slt-update.xml
+
+done
+
+cat res/postfix.template >> slt-update.xml
diff --git a/serial/major b/serial/major
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/serial/major
@@ -0,0 +1 @@
+0
diff --git a/serial/minor b/serial/minor
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/serial/minor
@@ -0,0 +1 @@
+0
diff --git a/serial/release b/serial/release
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/serial/release
@@ -0,0 +1 @@
+1
diff --git a/src/admin/abstract/controller.php b/src/admin/abstract/controller.php
index 178f9ec..168197f 100644
--- a/src/admin/abstract/controller.php
+++ b/src/admin/abstract/controller.php
@@ -7,114 +7,175 @@ use Joomla\CMS\Router\Route;
// No direct access.
defined('_JEXEC') or die;
+class DataParsingException extends Exception {}
+class DataInvalidException extends Exception {}
+
abstract class AbstractClubsController extends BaseController
{
+ /**
+ * @return AbstractCommonClubsModelFactory
+ */
+ protected abstract function getFactory();
- protected abstract function getNameOfElement();
+ /**
+ * @return string The name of the underlying object in lower letters.
+ */
+ protected abstract function getSingleBaseName();
- protected function getModelName()
+ /**
+ * @return string The name of the view to show a single object
+ */
+ protected function getSingleViewName()
{
- return $this->getNameOfElement();
+ return $this->getSingleBaseName();
}
- protected function getNameOfView()
+ public function new()
{
- return strtolower($this->getNameOfElement());
+ $factory = $this->getFactory();
+ $obj = $factory->createNew();
+
+ $this->saveToDatabase($obj, 'new');
}
- protected abstract function getDataMapping();
-
- function new()
- {
- $obj = call_user_func(array('Clubs' . $this->getNameOfElement(), 'create' . $this->getNameOfElement()));
-
- // Fetch the posted data
- $values = $this->loadData();
-
- $this->filterPreCheck($values);
-
- // Check the input data
- $error = ! $this->checkDataIsValid($values, true, Null);
-
- $view = $this->getNameOfView();
-
- if($error)
- {
- $urldata = $this->packData($values);
- $this->setRedirect(Route::_("index.php?option=com_clubs&view={$view}&id=new&data={$urldata}", false));
- return;
- }
-
- $this->applyData($obj, $values);
-
- // Do the actual work
- $obj->save();
- $this->setRedirect(Route::_("index.php?option=com_clubs&view={$view}s", false));
- }
-
- function change()
+ public function change()
{
$app = Factory::getApplication();
$input = $app->input;
$id = (int) $input->post->getInt('id');
- $obj = call_user_func(array('Clubs' . $this->getNameOfElement(), 'load' . $this->getNameOfElement()), (int) $id);
+ $factory = $this->getFactory();
+ $obj = $factory->loadById($id);
- // Fetch the posted data
- $values = $this->loadData();
-
- $this->filterPreCheck($values);
-
- // Check the input data
- $error = ! $this->checkDataIsValid($values, false, $obj);
-
- $view = $this->getNameOfView();
-
- if($error)
- {
- $urldata = $this->packData($values);
- $this->setRedirect(Route::_("index.php?option=com_clubs&view={$view}&id={$id}&data={$urldata}", false));
- return;
- }
-
- $this->applyData($obj, $values);
-
- // Do the actual work
- $obj->save();
- $this->setRedirect(Route::_("index.php?option=com_clubs&view={$view}s", false));
+ $this->saveToDatabase($obj, $id);
}
- protected function loadData()
+ /**
+ * @param AbstractCommonClubsModel $obj
+ * @param int $id
+ */
+ protected function saveToDatabase($obj, $id)
+ {
+ try
+ {
+ // Fetch the posted data
+ $values = $this->loadData($this->additionalData());
+
+ $this->filterRaw($values);
+
+ // Check the input data
+ if( ! $this->requiredDataIsAvailable($values) )
+ throw new DataParsingException();
+
+ if( ! $this->rawDataIsValid($values) )
+ throw new DataParsingException();
+
+ $obj->applyAndMergeValues($values, true);
+
+ $this->filterObject($obj, $values);
+
+ // Do some additional tests by the controller
+ if( ! $this->objectValid($obj) )
+ throw new DataInvalidException();
+
+ // Check if the object complains about valitity
+ if( ! $obj->dataIsValid() )
+ throw new DataInvalidException();
+
+ // Do the actual work
+ $obj->save();
+ $this->saveAssocs($obj, $values);
+
+ // Redirect to the list of objects
+ $view = $this->getSingleViewName();
+ $this->setRedirect(Route::_("index.php?option=com_clubs&view={$view}s", false));
+ }
+ catch(DataParsingException $e)
+ {
+ // FIXME Make this robust (are external refs already dereferenced?)
+ $view = $this->getSingleViewName();
+ $obj->setValues($values, true);
+ $urldata = $obj->pack();
+ $this->setRedirect(Route::_("index.php?option=com_clubs&view={$view}&id={$id}&data={$urldata}", false));
+ }
+ catch(DataInvalidException $e)
+ {
+ $view = $this->getSingleViewName();
+ $urldata = $obj->pack();
+ $this->setRedirect(Route::_("index.php?option=com_clubs&view={$view}&id={$id}&data={$urldata}", false));
+ }
+ }
+
+ protected function saveAssocs($obj, $vlaues){}
+
+ protected function additionalData()
+ {
+ return array();
+ }
+
+ protected function loadData($additionalData)
{
$values = array();
+ $factory = $this->getFactory();
$input = Factory::getApplication()->input->post;
- foreach($this->getDataMapping() as $m => $f)
+ foreach($factory->getAttributes() as $column)
{
- $filter = (isset($f['filter'])) ? $f['filter'] : 'string';
-
- $values[$m] = $input->get($m, null, $filter);
+ $values[$column->getAlias()] = $column->getFilter()->getFilteredValue($input, $column->getAlias());
+ }
+
+ foreach($additionalData as $k => $v)
+ {
+ $values[$k] = $v->getFilteredValue($input, $k);
}
return $values;
}
- protected function filterPreCheck(&$values){}
+ protected function filterRaw(&$values){}
- protected function checkDataIsValid($values, bool $isNew, $obj)
+ protected function filterObject($obj){}
+
+ protected function objectValid($obj)
+ {
+ return true;
+ }
+
+ private function requiredDataIsAvailable($values)
+ {
+ $ok = true;
+
+ foreach($this->getFactory()->getAttributes() as $column)
+ {
+ $filter = $column->getFilter();
+ if(! $filter->requiredDataAvailable($values[$column->getAlias()]))
+ {
+ $fname = $filter->getName();
+ Factory::getApplication()->enqueueMessage("Das Feld $fname ist obligatorisch.", 'error');
+ $ok = false;
+ }
+ }
+
+ return $ok;
+ }
+
+ /**
+ * @param array $values
+ * @param AbstractCommonClubsModel $obj
+ * @return boolean
+ */
+ protected function rawDataIsValid($values)
{
$error = false;
- // Check existence of the required fields
- foreach ($this->getDataMapping() as $m => $v)
+
+ $factory = $this->getFactory();
+
+ foreach($factory->getAttributes() as $column)
{
- if(! isset($v['required']) || ! $v['required'])
- continue;
-
- // Field is required
- if(! $this->fieldValid($m, $values[$m], $v))
+ if(! $column->getFilter()->rawValueValid($values[$column->getAlias()]))
{
- $fname = (isset($v['name'])) ? $v['name'] : $m;
- Factory::getApplication()->enqueueMessage("Das Feld $fname ist obligatorisch.", 'error');
+ $fname = $column->getFilter()->getName();
+ Factory::getApplication()->enqueueMessage("Das Feld $fname ist fehlerhaft.", 'error');
$error = true;
}
}
@@ -140,72 +201,19 @@ abstract class AbstractClubsController extends BaseController
return true;
}
- private function packData($values)
- {
- // FIXME Multiple bugs: filtering not working as expected and Mapping msut be checked
- $this->filterPrePacking($values);
-
- $data = array();
- foreach($this->getDataMapping() as $m => $i)
- {
- if(isset($values[$m]))
- $data[$m] = $values[$m];
- }
- $json = json_encode($data);
- return urlencode($json);
- }
-
- protected function filterPrePacking(&$values){}
-
- public function applyData($obj, $values)
- {
- $this->applyDataToObject($obj, $values, $this->getDataMapping());
- }
-
- protected function applyDataToObject($obj, $values, $mapping)
- {
- foreach($mapping as $m => $v)
- {
- $functionName = $this->getSetterMethodName($m, $v);
-
- if($functionName === null)
- {
- continue;
- }
-
- if(isset($v['skip_null_check']))
- $value = $values[$m];
- else
- $value = (isset($values[$m]) && strlen($values[$m]) > 0) ? $values[$m] : null;
-
- $obj->$functionName($value);
- }
- }
-
- private function getSetterMethodName($m, $options)
- {
- if(array_key_exists('setter', $options))
- return $options['setter'];
-
- $firstChar = substr($m, 0, 1);
- $restChars = substr($m, 1);
- return 'set' . strtoupper($firstChar) . $restChars;
- }
-
function delete()
{
$app = Factory::getApplication();
$id = $app->input->get->getInt('id');
- $name = $this->getNameOfElement();
+ $name = $this->getSingleBaseName();
$app->enqueueMessage("Removal of $name with id $id.");
- $className = 'Clubs' . $this->getModelName();
- $functionName = 'load' . $this->getModelName();
- $element = call_user_func(array($className, $functionName), $id);
+ $factory = $this->getFactory();
+ $element = $factory->loadById($id);
$element->delete();
- $view = $this->getNameOfView();
+ $view = $this->getSingleViewName();
$this->setRedirect(Route::_("index.php?option=com_clubs&view={$view}s", false));
}
diff --git a/src/admin/abstract/model.php b/src/admin/abstract/model.php
deleted file mode 100644
index 5ef288f..0000000
--- a/src/admin/abstract/model.php
+++ /dev/null
@@ -1,207 +0,0 @@
-id;
- }
-
- protected abstract function getDataMappings();
- protected abstract function getTableName();
-
-
- protected function loadData(array $data)
- {
- $this->id = $data['id'];
-
- foreach($this->getDataMappings() as $m)
- $this->$m = $data[$m];
- }
-
- protected static function loadElements(string $tableName, string $className, $where = null)
- {
- $dbo = Factory::getDbo();
- $q = $dbo->getQuery(true);
- $q->select('*')
- ->from($tableName);
-
- if(isset($where))
- {
- $q->where($where);
- }
-
- $dbo->setQuery($q);
- $dbo->execute();
- $list = $dbo->loadAssocList();
-
- $ret = array();
- foreach($list as $row)
- {
- $obj = new $className();
- $obj->loadData($row);
-
- $ret[] = $obj;
- }
-
- return $ret;
- }
-
- /**
- * @param int $id
- * @throws Exception
- * @return ClubsOffer
- */
- protected static function loadElement(int $id, string $tableName, string $className)
- {
- $dbo = Factory::getDbo();
- $q = $dbo->getQuery(true);
-
- $q->select('*')->from($tableName);
-
- $q->where('id=' . (int) $id);
- $dbo->setQuery($q);
- $dbo->execute();
-
- $row = $dbo->loadAssoc();
-
- if($row == null)
- {
- throw new Exception("No object of class $className found.");
- // TODO
- }
-
- $obj = new $className();
- $obj->loadData($row);
- $obj->loadCustomData($row);
- return $obj;
- }
-
- protected function loadCustomData($assoc)
- {}
-
- public function save()
- {
- if($this->id === 'new')
- $this->insertElement();
- else
- $this->updateElement();
- }
-
- private function insertElement()
- {
- if(! $this->isDataValid())
- throw new Exception('Data is invalid');
-
- $dbo = Factory::getDbo();
- $q = $dbo->getQuery(true);
-
- $mappings = $this->getDataMappings();
- $values = $this->getDataValues($mappings, $q);
-
- $q->insert($this->getTableName())
- ->columns(array_map(array($q, 'qn'), $mappings))
- ->values(join(',', $values))
- ;
-
- $dbo->transactionStart();
- $dbo->setQuery($q);
- $dbo->execute();
- $this->id = $dbo->insertid();
- $dbo->transactionCommit();
- }
-
- private function updateElement()
- {
- if(! $this->isDataValid())
- throw new Exception('Data is invalid');
-
- $dbo = Factory::getDbo();
- $q = $dbo->getQuery(true);
-
- $mapping = $this->getDataMappings();
- $values = $this->getDataValues($mapping, $q);
-
- $q->update($this->getTableName());
- foreach($mapping as $m)
- $q->set($q->qn($m) . '=' . $values[$m]);
- $q->where("id=". (int) $this->id);
-
- $dbo->setQuery($q);
- $dbo->execute();
- }
-
- private function getDataValues($mapping, $q)
- {
- $rawValues = array();
-
- foreach($mapping as $m)
- $rawValues[$m] = $this->$m;
-
- $this->filter($rawValues);
-
- $quotedValues = array();
-
- foreach($mapping as $m)
- {
- if(is_bool($rawValues[$m]))
- $quotedValues[$m] = $rawValues[$m] ? 'TRUE' : 'FALSE';
- else if(is_numeric($rawValues[$m]))
- $quotedValues[$m] = $rawValues[$m];
- else
- $quotedValues[$m] = $q->q($rawValues[$m]);
- }
-
- $this->postQuoteFilter($quotedValues);
-
- return $quotedValues;
- }
-
- protected function prepareDelete($dbo){}
-
- public function delete()
- {
- if($this->id === 'new')
- return;
-
- $dbo = Factory::getDbo();
- $this->prepareDelete($dbo);
-
- $q = $dbo->getQuery(true);
- $q->delete($this->getTableName())
- ->where('id=' . (int) $this->id);
-
- $dbo->setQuery($q);
- $dbo->execute();
- }
-
- protected function getRequiredDataMappings()
- {
- return $this->getDataMappings();
- }
-
- protected function isDataValid()
- {
- foreach($this->getRequiredDataMappings() as $m)
- {
- if(!isset($this->$m) || is_null($this->$m) || $this->$m === null)
- return false;
- }
- return true;
- }
-
- protected function filter(&$values){}
- protected function postQuoteFilter(&$values){}
-
-
-}
diff --git a/src/admin/abstract/modelfactory.php b/src/admin/abstract/modelfactory.php
deleted file mode 100644
index f23cc98..0000000
--- a/src/admin/abstract/modelfactory.php
+++ /dev/null
@@ -1,177 +0,0 @@
-tableName = $tableName;
- $this->className = $className;
- }
-
- /**
- *
- * @param JDatabaseDriver $dbo
- * @return array
- */
- protected function getJoins($dbo)
- {
- /*
- * Desired structure:
- * array, ech element describing one join type.
- * Each element of the array is a assosiated array describing the join:
- * - Name of the table (must not be main)
- * - Table alias
- * - Type of the join (inner, left, right, outer), default is inner
- * - Condition as a string (might need escaping)
- * - Columns to be inserted in the join, defaults to *
- * example:
- * $ret = array();
- * $ret[] = array(
- * 'name' => '#__table_name',
- * 'alias' => 't1',
- * 'type' => 'right',
- * 'on' => 'main.extid = t1.id'
- * 'select' => array('id','name')
- * );
- * return $ret;
- */
- return array();
- }
-
- /**
- *
- * @param JDatabaseDriver $dbo
- * @param JDatabaseQuery $q
- */
- private function insertJoinRelations($dbo, $q)
- {
- $joins = $this->getJoins($dbo);
- foreach($joins as $j)
- {
- if(is_null($j['name']))
- throw new Exception('No name was given in the join.');
- if(is_null($j['alias']))
- throw new Exception('No alisas was given in the join.');
-
- $jstr = $dbo->qn($j['name'], $j['alias']);
-
- if(is_null($j['on']))
- throw new Exception('No on clause was provided.');
-
- $jstr .= " ON {$j['on']}";
-
- if(is_null($j['type']))
- $j['type'] = 'inner';
-
- switch($j['type'])
- {
- case 'inner':
- $q->innerJoin($jstr);
- break;
-
- case 'outer':
- $q->outerJoin($jstr);
- break;
-
- case 'left':
- $q->leftJoin($jstr);
- break;
-
- case 'right':
- $q->rightJoin($jstr);
- break;
-
- default:
- throw new Exception("Type of join unknown: {$j['type']}.");
- }
-
- $this->addJoinSelectColumns($j, $q);
- }
- }
-
- /**
- *
- * @param array $j
- * @param JDatabaseQuery $q
- */
- private function addJoinSelectColumns($j, $q)
- {
- // TODO Quote names
- if(is_null($j['select']))
- $j['select'] = '*';
-
- if(is_array($j['select']))
- {
- array_map(function(&$str) use ($j) {
- $str = "{$j['alias']}.$str";
- }, $j['select']);
- }
- else
- {
- $q->select("{$j['alias']}.{$j['select']}");
- }
- }
-
- public function loadElement(int $id)
- {
- $condition = "id = $id";
-
- return $this->loadFirstElement($condition);
- }
-
- public function loadFirstElement($condition)
- {
- $objs = $this->loadElements($condition);
-
- if(sizeof($objs) == 0)
- {
- throw new Exception("No object of class {$this->className} found.");
- // TODO
- }
-
- return $objs[0];
- }
-
- public function loadElements($condition = null)
- {
- $dbo = Factory::getDbo();
- $q = $dbo->getQuery(true);
-
- $q->select('main.*')->from($this->tableName, 'main');
- $this->insertJoinRelations($dbo, $q);
-
- if(isset($condition))
- {
- $q->where($condition);
- }
- $dbo->setQuery($q);
- $dbo->execute();
-
- $list = $dbo->loadAssocList();
-
- $ret = array();
- foreach($list as $row)
- {
- $ret[] = $this->createElement($row);
- }
-
- return $ret;
- }
-
- protected function createElement($row)
- {
- $obj = new $this->className();
- $obj->loadData($row);
- $obj->loadCustomData($row);
- return $obj;
- }
-}
diff --git a/src/admin/abstract/view/list.php b/src/admin/abstract/view/list.php
new file mode 100644
index 0000000..d794306
--- /dev/null
+++ b/src/admin/abstract/view/list.php
@@ -0,0 +1,67 @@
+prepared = TRUE;
+
+ $this->objects = $this->loadObjects();
+ $baseUrl = "index.php?option=com_clubs";
+ $viewName = $this->getSingleViewName();
+ $controllerName = $this->getControllerName();
+
+ $this->addUrl = Route::_("$baseUrl&view=$viewName&id=new");
+ $this->changeUrl = Route::_("$baseUrl&view=$viewName&id=__ID__");
+ $this->delUrl = Route::_("$baseUrl&task=$controllerName.delete&id=__ID__");
+ }
+
+ public function display($tpl = null)
+ {
+ if(!$this->prepared)
+ $this->prepareDisplay();
+
+ parent::display($tpl);
+ }
+
+ protected abstract function getSingleBaseName();
+
+ protected function getControllerName()
+ {
+ return $this->getSingleBaseName();
+ }
+
+ protected function getSingleViewName()
+ {
+ return $this->getSingleBaseName();
+ }
+
+ /**
+ * @return AbstractCommonClubsModelFactory
+ */
+ protected abstract function getFactory();
+
+ protected function loadObjects()
+ {
+ $factory = $this->getFactory();
+ return $factory->loadElements();
+ }
+
+}
diff --git a/src/admin/abstract/view/single.php b/src/admin/abstract/view/single.php
index 70d1a6a..92846f3 100644
--- a/src/admin/abstract/view/single.php
+++ b/src/admin/abstract/view/single.php
@@ -11,8 +11,12 @@ abstract class AbstractClubsViewSingle extends HtmlView
{
protected $address;
+ /**
+ * @var AbstractCommonClubsModel
+ */
protected $object;
protected $isNew;
+ protected $id;
private $prepared = FALSE;
@@ -23,34 +27,32 @@ abstract class AbstractClubsViewSingle extends HtmlView
$input = Factory::getApplication()->input;
$id = $input->get->get('id');
- $modelClass = 'Clubs' . $this->getModelName();
+ $controllerName = $this->getControllerName();
- $controller = $this->getControllerName();
if($id === 'new')
{
- $this->address = Route::_("index.php?option=com_clubs&task={$controller}.new");
- $this->object = call_user_func(array($modelClass, 'create' . $this->getModelName()));
+ $this->address = Route::_("index.php?option=com_clubs&task={$controllerName}.new");
+ $this->object = $this->createNewObject();
$this->isNew = true;
}
else if(is_numeric($id))
{
- $this->address = Route::_("index.php?option=com_clubs&task={$controller}.change");
- $this->object = call_user_func(array($modelClass, 'load' . $this->getModelName()), (int) $id);
+ $id = (int) $id;
+ $this->address = Route::_("index.php?option=com_clubs&task={$controllerName}.change&id=$id");
+ $this->object = $this->loadObject($id);
$this->isNew = false;
}
else
- throw new Exception('Need an object id.');
-
- if($input->get->get('data', null, 'json') != null)
+ throw new Exception('Need a valid object id.');
+
+ $jsonData = $input->get->get('data', null, 'json');
+ if($jsonData !== null)
{
- // Restore previous data
- $dataurl = $input->get->get('data', null, 'json');
- $data = json_decode($dataurl, true);
-
- $controller = $this->getElementController();
- $controller->applyData($this->object, $data);
+ $this->object->unpack($jsonData);
}
+
+ $this->id = $id;
}
public function display($tpl = null)
@@ -61,26 +63,23 @@ abstract class AbstractClubsViewSingle extends HtmlView
parent::display($tpl);
}
- protected abstract function getViewName();
+ protected abstract function getControllerName();
- protected function getControllerName()
+ /**
+ * @return AbstractCommonClubsModelFactory
+ */
+ protected abstract function getFactory();
+
+ protected function createNewObject()
{
- return $this->getViewName();
+ $factory = $this->getFactory();
+ return $factory->createNew();
}
- protected function getModelName()
+ protected function loadObject($id)
{
- $name = $this->getViewName();
- return $this->capitalize($name);
+ $factory = $this->getFactory();
+ return $factory->loadById($id);
}
- private function capitalize($s)
- {
- $first = substr($s, 0, 1);
- $rest = substr($s, 1);
- return strtoupper($first) . $rest;
- }
-
- protected abstract function getElementController();
-
}
diff --git a/src/admin/clubs.php b/src/admin/clubs.php
index f52ed19..726f58f 100644
--- a/src/admin/clubs.php
+++ b/src/admin/clubs.php
@@ -8,6 +8,9 @@ defined('_JEXEC') or die;
JLoader::discover('Clubs', JPATH_ROOT . '/administrator/components/com_clubs/mymodels');
JLoader::registerPrefix('AbstractClubs', JPATH_ROOT . '/administrator/components/com_clubs/abstract');
+JLoader::registerPrefix('AbstractCommonClubs', JPATH_ROOT . '/administrator/components/com_clubs/common/abstract');
+JLoader::registerPrefix('CommonClubsModel', JPATH_ROOT . '/administrator/components/com_clubs/common/models');
+JLoader::registerPrefix('CommonClubsControllerMapping', JPATH_ROOT . '/administrator/components/com_clubs/common/controllermappings');
$controller = BaseController::getInstance("Clubs");
$input = Factory::getApplication()->input;
diff --git a/src/admin/common/abstract/controller/mapping.php b/src/admin/common/abstract/controller/mapping.php
new file mode 100644
index 0000000..b445609
--- /dev/null
+++ b/src/admin/common/abstract/controller/mapping.php
@@ -0,0 +1,55 @@
+name = $name;
+ $this->required = $required;
+ }
+
+
+ /**
+ * @param mixed $value
+ * @return bool
+ */
+ public function requiredDataAvailable($value)
+ {
+ if($this->required && ($value === null || $value === ''))
+ return false;
+
+ return true;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * @param JInput $input
+ * @param string $name
+ * @return string
+ */
+ public abstract function getFilteredValue($input, $name);
+
+ /**
+ * @param mixed $value
+ * @return boolean
+ */
+ public function rawValueValid($value)
+ {
+ return true;
+ }
+
+}
diff --git a/src/admin/common/abstract/model.php b/src/admin/common/abstract/model.php
new file mode 100644
index 0000000..e0859c5
--- /dev/null
+++ b/src/admin/common/abstract/model.php
@@ -0,0 +1,385 @@
+id;
+ }
+
+ public function setId($id)
+ {
+ $this->id = $id;
+ }
+
+ private $values = null;
+
+ protected function getValues($force = false)
+ {
+ if(is_null($this->values) || $force)
+ $this->loadDataFromDatabase();
+
+ return $this->values;
+ }
+
+ public function isNew()
+ {
+ return $this->new;
+ }
+
+ public function setValues($values, $unpack = false)
+ {
+ if($unpack)
+ $this->values = $this->unpackExternalReferencesFromKeys($values);
+ else
+ $this->values = $values;
+ }
+
+ public function applyAndMergeValues($values, $unpack = true)
+ {
+ $vals = $this->getValues();
+
+ if($unpack)
+ $vals = $this->packExternalReferencesAsKeys($vals);
+
+ foreach($this->getFactory()->getAttributes() as $column)
+ {
+ if(array_key_exists($column->getAlias(), $values))
+ {
+ $vals[$column->getAlias()] = $values[$column->getAlias()];
+ }
+ }
+
+ if($unpack)
+ $vals = $this->unpackExternalReferencesFromKeys($vals);
+
+ $this->setValues($vals, false);
+ }
+
+ protected function setValue($key, $value)
+ {
+ if(is_null($this->values))
+ $this->loadDataFromDatabase();
+
+ $this->values[$key] = $value;
+ }
+
+ public function markAsNew($new)
+ {
+ $this->new = $new;
+ }
+
+ public function fillDefaultValues()
+ {}
+
+ /**
+ * @return AbstractCommonClubsModelFactory
+ */
+ protected abstract function getFactory();
+
+ public function save()
+ {
+ $factory = $this->getFactory();
+ $attribs = $factory->getAttributes();
+
+ $db = Factory::getDbo();
+ $q = $db->getQuery(true);
+
+ $db->transactionStart();
+
+ if($this->new)
+ $this->prepareInsert($attribs, $factory, $q);
+ else
+ $this->prepareUpdate($attribs, $factory, $q);
+
+ $db->setQuery($q);
+ $db->execute();
+
+ if($this->new)
+ {
+ $this->finishInsert($db);
+ }
+
+ $db->transactionCommit();
+ }
+
+ private function loadDataFromDatabase()
+ {
+ $factory = $this->getFactory();
+ $attribs = $factory->getAttributes();
+
+ $db = Factory::getDbo();
+ $q = $db->getQuery(true);
+
+ foreach($attribs as $a)
+ {
+ $a->select($q);
+ }
+ $q->from($factory->getTableName());
+ $q->where("id = {$this->id}");
+
+ $joins = $factory->getJoins();
+ foreach($joins as $j)
+ {
+ $j->join($q);
+ }
+
+ $db->setQuery($q);
+ $db->execute();
+
+ $values = $db->loadAssoc();
+
+ $values = $this->unpackExternalReferencesFromKeys($values);
+
+ $this->values = $values;
+ }
+
+ private function packExternalReferencesAsKeys($vals)
+ {
+ foreach($this->getFactory()->getAttributes() as $a)
+ {
+ $alias = $a->getAlias();
+ $vals[$alias] = $a->packValue($vals[$alias]);
+ }
+
+ // XXX Joins
+ return $vals;
+ }
+
+ private function unpackExternalReferencesFromKeys($vals)
+ {
+ $factory = $this->getFactory();
+
+ foreach($factory->getAttributes() as $a)
+ {
+ $alias = $a->getAlias();
+ if(isset($vals[$alias]))
+ $vals[$alias] = $a->unpackValue($vals[$alias]);
+ }
+
+ $joins = $factory->getJoins();
+ foreach($joins as $join)
+ {
+ $join->unpackExternalReferencesFromKeys($vals);
+ }
+
+ return $vals;
+ }
+
+
+ /**
+ *
+ * @param array $rawData
+ * @param AbstractCommonClubsModelColumn[] $attribs
+ * @param JDatabaseQuery $q
+ * @return string[]|number[]|NULL[]
+ */
+ private function quoteData($rawData, $attribs, $q)
+ {
+ $quotedData = array();
+
+ foreach($attribs as $a)
+ {
+ $alias = $a->getAlias();
+ $quotedData[$alias] = $a->getQuotedValue($q, $rawData[$alias]);
+ }
+
+ return $quotedData;
+ }
+
+ protected function filterDatabaseRawData($values)
+ {
+ return $values;
+ }
+
+ protected function filterDatabaseQuotedData($quoted)
+ {
+ return $quoted;
+ }
+
+ /**
+ *
+ * @param array $attribs
+ * @param JDatabaseQuery $q
+ * @return array
+ */
+ private function getQuotedData($attribs, $q)
+ {
+ $rawData = $this->getValues();
+ $rawData = $this->filterDatabaseRawData($rawData);
+
+ $quotedData = $this->quoteData($rawData, $attribs, $q);
+ $quotedData = $this->filterDatabaseQuotedData($quotedData);
+
+ return $quotedData;
+ }
+
+ /**
+ *
+ * @param AbstractCommonClubsModelColumn[] $attribs
+ * @param AbstractCommonClubsModelFactory $factory
+ * @param JDatabaseQuery $q
+ */
+ private function prepareInsert($attribs, $factory, $q)
+ {
+ $q->insert($factory->getTableName());
+
+ $dbcols = array();
+ foreach($attribs as $a)
+ {
+ $dbcols[] = $a->getColumn();
+ }
+
+ $q->columns($q->qn($dbcols));
+
+ $quotedData = $this->getQuotedData($attribs, $q);
+
+ $q->values(join(', ', $quotedData));
+ }
+
+ /**
+ *
+ * @param JDatabaseDriver $db
+ */
+ private function finishInsert($db)
+ {
+ $this->id = $db->insertid();
+ $this->new = false;
+ }
+
+ /**
+ *
+ * @param AbstractCommonClubsModelColumn[] $attribs
+ * @param AbstractCommonClubsModelFactory $factory
+ * @param JDatabaseQuery $q
+ */
+ private function prepareUpdate($attribs, $factory, $q)
+ {
+ $q->update($factory->getTableName());
+
+ $dbcols = array();
+ foreach($attribs as $a)
+ $dbcols[] = $a->getColumn();
+
+ $quotedData = $this->getQuotedData($attribs, $q);
+
+ $q->set(array_map(function($col, $data){
+ return "$col = $data";
+ }, $dbcols, $quotedData));
+
+ $q->where("id = {$this->id}");
+ }
+
+ /**
+ *
+ * @param JDatabaseDriver $db
+ */
+ protected function prepareDelete($db)
+ {}
+
+ public function delete()
+ {
+ $db = Factory::getDbo();
+ $q = $db->getQuery(true);
+
+ $factory = $this->getFactory();
+
+ $q->delete($factory->getTableName());
+ $q->where("id = {$this->id}");
+
+ $db->transactionStart(true);
+ $this->prepareDelete($db);
+ $db->setQuery($q);
+ $db->execute();
+ $db->transactionCommit(true);
+ }
+
+ /**
+ *
+ * @param AbstractCommonClubsModelFactory $factory
+ * @param string $colName
+ * @param array $constraints
+ */
+ protected function fetchAssociatedElements($factory, $colName, $constraints = null, $sorting = null)
+ {
+ $condition = "main.$colName = {$this->id}";
+
+ if(isset($constraints))
+ {
+ if(is_array($constraints))
+ $allConstraints = clone $constraints;
+ elseif(is_string($constraints))
+ $allConstraints = array($constraints);
+ else
+ throw new Exception('Unknown type of constraint');
+
+ // Add the manual condition to match the current object
+ $allConstraints[] = $condition;
+
+ return $factory->loadElements($allConstraints, $sorting);
+ }
+ else
+ return $factory->loadElements($condition, $sorting);
+ }
+
+ protected function filterPackData($values)
+ {
+ return $values;
+ }
+
+ protected function filterUnpackData($values)
+ {
+ return $values;
+ }
+
+ /**
+ * @return string
+ */
+ public function pack()
+ {
+ $vals = $this->getValues();
+
+ $vals = $this->packExternalReferencesAsKeys($vals);
+ $vals = $this->filterPackData($vals);
+
+ $json = json_encode($vals);
+ return urlencode($json);
+ }
+
+ /**
+ * @param string $str
+ * @param boolean $decode
+ */
+ public function unpack($str, $decode = false)
+ {
+ if($decode)
+ $json = urldecode($str);
+ else
+ $json = $str;
+ $data = json_decode($json, true);
+
+ $vals = $this->unpackExternalReferencesFromKeys($data);
+ $vals = $this->filterUnpackData($vals);
+
+ $this->setValues($vals);
+ }
+
+ public function dataIsValid()
+ {
+ return true;
+ }
+
+}
diff --git a/src/admin/common/abstract/model/column.php b/src/admin/common/abstract/model/column.php
new file mode 100644
index 0000000..cfacc87
--- /dev/null
+++ b/src/admin/common/abstract/model/column.php
@@ -0,0 +1,77 @@
+alias;
+ }
+
+ public function getColumn()
+ {
+ return $this->column;
+ }
+
+ public abstract function isSimpleType();
+
+ public function __construct($alias, $filter, $column = null)
+ {
+ $this->alias = $alias;
+ $this->filter = $filter;
+ if(isset($column))
+ $this->column = $column;
+ else
+ $this->column = $alias;
+ }
+
+ /**
+ * @param JDatabaseQuery $q
+ */
+ public function select($q)
+ {
+ $q->select($q->qn($this->column, $this->alias));
+ }
+
+ /**
+ *
+ * @param JDatabaseQuery $q
+ * @param mixed $value
+ */
+ public abstract function getQuotedValue($q,$value);
+
+ /**
+ *
+ * @param JDatabaseQuery $q
+ */
+ public function getQuotedColumnName($q)
+ {
+ return $q->qn($this->column);
+ }
+
+ public function packValue($value)
+ {
+ return $value;
+ }
+
+ public function unpackValue($value)
+ {
+ return $value;
+ }
+
+ public function getFilter()
+ {
+ return $this->filter;
+ }
+
+}
diff --git a/src/admin/common/abstract/model/factory.php b/src/admin/common/abstract/model/factory.php
new file mode 100644
index 0000000..434b72a
--- /dev/null
+++ b/src/admin/common/abstract/model/factory.php
@@ -0,0 +1,208 @@
+array('col'=>'Name', type=>'string'),
+ * 'size'=>array('col'=>'area', type=>'int')
+ * )
+ *
+ * The inner arrays contain the following entries:
+ * - col: The name of the column in the database. Defaults to the key name
+ * - type: The type of the column. If nothing is specified, string is assumed.
+ * - string
+ * - int
+ * - float
+ * - ref
+ * - optional: boolean, if true, the field can be NULL
+ * - ref: (only with type='ref') The name of the class that is referenced
+ */
+ protected abstract function fetchAttributes();
+
+ private $attributes = null;
+ /**
+ * @param boolean $force
+ * @return AbstractCommonClubsModelColumn[]
+ */
+ public function getAttributes($force = False)
+ {
+ if($this->attributes === null || $force)
+ $this->attributes = $this->fetchAttributes();
+
+ return $this->attributes;
+ }
+
+ public abstract function getTableName();
+ public abstract function getClassName();
+
+ // TODO Als Klassen formulieren
+ /*
+ * This method returns the relevant join operations on the data.
+ * The return value is an associated arrray whose keys are the names of the tables in the join.
+ * Each value of such joins is again an associative array.
+ * These arrays have the following entries:
+ * - alias: The alias name of the table to use. Mandatory
+ * - type: The type of the join. Can be inner, left, right or outer. Defaults to inner.
+ * - on: Join constraint as a string representation.
+ * - cols: The columns to insert in the query. Same structure as fetchAttributes() method
+ *
+ * Example:
+ * array(
+ * 'mytable'=>array(
+ * 'alias'=>'t1',
+ * 'type'=>'left',
+ * 'on'=>'main.id = t1.clubid',
+ * 'cols'=>array(
+ * 'name'=>array(),
+ * 'count'=>array('type'=>'int', 'col'=>'numElements'
+ * )
+ * )
+ * )
+ */
+ protected function fetchJoins()
+ {
+ return array();
+ }
+
+ private $joins = null;
+ /**
+ * @return AbstractCommonClubsModelJoin[]
+ */
+ public function getJoins($force = False)
+ {
+ if($this->joins === null || $force)
+ $this->joins = $this->fetchJoins();
+
+ return $this->joins;
+ }
+
+ /**
+ *
+ * @param string $condition
+ * @param string|array $sorting
+ * @return AbstractCommonClubsModel[]
+ */
+ public function loadElements($condition = null, $sorting = null, $callback = null)
+ {
+ $db = Factory::getDbo();
+ $q = $db->getQuery(true);
+
+// $columns = array_map(function($arr) use ($q){ return $q->qn('main' . $arr['col']); }, $this->fetchAttributes());
+// $columns = array();
+// foreach($this->fetchAttributes() as $k=>$v)
+// {
+// $columns[] = $q->qn('main' . $v['col'], $k);
+// }
+
+ $q->select('main.id AS id');//->select($columns);
+ $q->from($this->getTableName() . ' AS main');
+
+ if($condition !== null)
+ $q->where($condition);
+
+ if($sorting !== null)
+ $q->order($sorting);
+
+ if($callback !== null)
+ {
+ $callback($q);
+ }
+
+ $db->setQuery($q);
+ $db->execute();
+
+ $rows = $db->loadAssocList();
+ $ret = array();
+ foreach($rows as $row)
+ {
+ $ret[] = $this->generateObject($row);
+ }
+
+ return $ret;
+ }
+
+ /**
+ * @param int $id
+ * @return AbstractCommonClubsModel
+ */
+ public function loadById($id, $throwErr = true)
+ {
+ $arr = $this->loadElements("main.id = " . ((int)$id) );
+ if(sizeof($arr) == 0)
+ {
+ if($throwErr)
+ throw new ElementNotFoundException();
+ else
+ return null;
+ }
+
+ return $arr[0];
+ }
+
+ private function generatePlainObject($id)
+ {
+ $name = $this->getClassName();
+ $obj = new $name();
+
+ $obj->setId($id);
+
+ return $obj;
+ }
+
+ /**
+ * @param array $row
+ * @return AbstractCommonClubsModel
+ */
+ protected function generateObject($row)
+ {
+ $obj = $this->generatePlainObject($row['id']);
+ $obj->markAsNew(false);
+
+ //unset($row['id']);
+ //$obj->setValues($row);
+
+ // Do not trigger cache if no needed
+ //$obj->getValues();
+
+ return $obj;
+ }
+
+ /**
+ * @return AbstractCommonClubsModel
+ */
+ public function createNew()
+ {
+ $obj = $this->generatePlainObject('new');
+ $obj->markAsNew(true);
+
+ $values = array();
+ foreach($this->getAttributes() as $a)
+ {
+ $values[$a->getAlias()] = null;
+ }
+// $attribs = array_map(function($v){
+// return Null;
+// }, $this->getAttributes());
+ $obj->setValues($values);
+
+ $obj->fillDefaultValues();
+
+ return $obj;
+ }
+}
diff --git a/src/admin/common/abstract/model/join.php b/src/admin/common/abstract/model/join.php
new file mode 100644
index 0000000..878f146
--- /dev/null
+++ b/src/admin/common/abstract/model/join.php
@@ -0,0 +1,84 @@
+alias = $alias;
+ $this->condition = $condition;
+ $this->columns = $colums;
+
+ if(empty($tablename))
+ $this->tablename = $alias;
+ else
+ $this->tablename = $alias;
+ }
+
+ public function getAlias()
+ {
+ return $this->alias;
+ }
+
+ public function getTableName()
+ {
+ return $this->tablename;
+ }
+
+ public function getOnCondition()
+ {
+ return $this->condition;
+ }
+
+ public function getColumns()
+ {
+ return $this->columns;
+ }
+
+ /**
+ *
+ * @param JDatabaseQuery $q
+ */
+ public function join($q)
+ {
+ $str = "{$this->tablename} AS {$this->alias}";
+ if(isset($this->condition))
+ $str .= " ON {$this->condition}";
+ $this->addJoin($q, $str);
+
+ foreach($this->columns as $c)
+ {
+ $qc = $q->q("{$this->alias}." . $c->getColumn(), $c->getAlias());
+ $q->select($qc);
+ }
+ }
+
+ /**
+ *
+ * @param JDatabaseQuery $q
+ * @param String $str
+ */
+ protected abstract function addJoin($q, $str);
+
+ public function unpackExternalReferencesFromKeys(&$vals)
+ {
+ foreach($this->columns as $col)
+ {
+ $alias = $col->getAlias();
+ $vals[$alias] = $col->unpackValue($vals[$alias]);
+ }
+ }
+
+}
diff --git a/src/admin/common/controllermappings/cmd.php b/src/admin/common/controllermappings/cmd.php
new file mode 100644
index 0000000..04a48c4
--- /dev/null
+++ b/src/admin/common/controllermappings/cmd.php
@@ -0,0 +1,14 @@
+getCmd($name);
+ }
+
+}
diff --git a/src/admin/common/controllermappings/float.php b/src/admin/common/controllermappings/float.php
new file mode 100644
index 0000000..a3167ae
--- /dev/null
+++ b/src/admin/common/controllermappings/float.php
@@ -0,0 +1,14 @@
+getFloat($name);
+ }
+
+}
diff --git a/src/admin/common/controllermappings/int.php b/src/admin/common/controllermappings/int.php
new file mode 100644
index 0000000..bac15d7
--- /dev/null
+++ b/src/admin/common/controllermappings/int.php
@@ -0,0 +1,14 @@
+getInt($name);
+ }
+
+}
diff --git a/src/admin/common/controllermappings/ref.php b/src/admin/common/controllermappings/ref.php
new file mode 100644
index 0000000..24d9d3f
--- /dev/null
+++ b/src/admin/common/controllermappings/ref.php
@@ -0,0 +1,44 @@
+factory = $factory;
+ }
+
+ public function getFilteredValue($input, $name)
+ {
+ return $input->getInt($name);
+ }
+
+ public function rawValueValid($value)
+ {
+ try
+ {
+ $this->factory->loadById((int) $value);
+ }
+ catch(ElementNotFoundException $e)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/src/admin/common/controllermappings/string.php b/src/admin/common/controllermappings/string.php
new file mode 100644
index 0000000..5f14cfa
--- /dev/null
+++ b/src/admin/common/controllermappings/string.php
@@ -0,0 +1,14 @@
+getString($name);
+ }
+
+}
diff --git a/src/admin/common/models/club.php b/src/admin/common/models/club.php
new file mode 100644
index 0000000..37717da
--- /dev/null
+++ b/src/admin/common/models/club.php
@@ -0,0 +1,157 @@
+getValues()['name'];
+ }
+
+ public function getAddress()
+ {
+ return $this->getValues()['address'];
+ }
+
+ public function getCity()
+ {
+ return $this->getValues()['city'];
+ }
+
+ public function getHomepage()
+ {
+ return $this->getValues()['homepage'];
+ }
+
+ public function getMail()
+ {
+ return $this->getValues()['mail'];
+ }
+
+ public function getIban()
+ {
+ return $this->getValues()['iban'];
+ }
+
+ public function getBic()
+ {
+ return $this->getValues()['bic'];
+ }
+
+ public function isCharitable()
+ {
+ return $this->getValues()['charitable'];
+ }
+
+ public function getPresident()
+ {
+ return $this->getValues()['president'];
+ }
+
+ public function getPlaces()
+ {
+ return $this->fetchAssociatedElements(new CommonClubsModelFactoryPlace(), 'clubid');
+ }
+
+ private function getOfferAssocs()
+ {
+ return $this->fetchAssociatedElements(new CommonClubsModelFactoryOfferassoc(), 'clubid');
+ }
+
+ public function getOffers()
+ {
+ $assocs = $this->getOfferAssocs();
+
+ $offersFactory = new CommonClubsModelFactoryOffer();
+ $allOffers = $offersFactory->loadElements();
+
+ $ret = array();
+ foreach($allOffers as $offer)
+ {
+ $arr = array(
+ 'offer' => $offer,
+ 'valid' => false
+ );
+
+ $id = $offer->getId();
+ foreach($assocs as $a)
+ {
+ $oid = $a->getOffer()->getId();
+ if($id === $oid)
+ {
+ $arr['valid'] = true;
+ break;
+ }
+ }
+
+ $ret[] = $arr;
+ }
+ return $ret;
+ }
+
+ /**
+ * @param int[] $ids
+ */
+ public function setOfferIds($ids)
+ {
+ $dbo = $this->getFactory()->loadById($this->getId());
+ $currentOffersAssocs = $dbo->getOfferAssocs();
+ $currentIds = array_map(function($obj){
+ return $obj->getOffer()->getId();
+ }, $currentOffersAssocs);
+
+ $newIds = array_diff($ids, $currentIds);
+ $delIds = array_diff($currentIds, $ids);
+
+ $offerAssocFactory = new CommonClubsModelFactoryOfferassoc();
+ $offerFactory = new CommonClubsModelFactoryOffer();
+
+ foreach($delIds as $id)
+ {
+ $delId = (int) $id;
+ $delObjs = $offerAssocFactory->loadElements("clubid = {$this->getId()} AND offerid = $delId");
+ foreach($delObjs as $o)
+ $o->delete();
+ }
+
+ foreach($newIds as $id)
+ {
+ $newId = (int) $id;
+ $o = $offerAssocFactory->createNew();
+ $o->setOffer($offerFactory->loadById($newId));
+ $o->setClub($this);
+ $o->save();
+ }
+ }
+
+ public function getUsers()
+ {
+ return $this->fetchAssociatedElements(new CommonClubsModelFactoryUserassoc(), 'clubid');
+ }
+
+ protected function prepareDelete($db)
+ {
+ $q = $db->getQuery(true);
+ $q->delete('#__club_user_assocs')->where("clubid = {$this->getId()}");
+ $db->setQuery($q);
+ $db->execute();
+
+ $q = $db->getQuery(true);
+ $q->delete('#__club_places')->where("clubid = {$this->getId()}");
+ $db->setQuery($q);
+ $db->execute();
+
+ $q = $db->getQuery(true);
+ $q->delete('#__club_offer_assocs')->where("clubid = {$this->getId()}");
+ $db->setQuery($q);
+ $db->execute();
+ }
+}
diff --git a/src/admin/common/models/column/float.php b/src/admin/common/models/column/float.php
new file mode 100644
index 0000000..be81642
--- /dev/null
+++ b/src/admin/common/models/column/float.php
@@ -0,0 +1,22 @@
+className = $className;
+ }
+
+ public function isSimpleType()
+ {
+ return false;
+ }
+
+ public function getQuotedValue($q, $value)
+ {
+ if(is_null($value))
+ return 'NULL';
+ else
+ {
+ if(! ( $value instanceof $this->className ) )
+ throw new WrongRefTypeException();
+
+ $id = $value->getId();
+ if($id === 'new')
+ throw new AssociatedObjectUnsavedException();
+
+ return $id;
+ }
+ }
+
+ public function packValue($value)
+ {
+ if(is_null($value))
+ return null;
+
+ if(! ($value instanceof $this->className) )
+ throw new WrongRefTypeException();
+
+ $id = $value->getId();
+
+ if($id === 'new')
+ throw new AssociatedObjectUnsavedException();
+
+ return (int) $id;
+ }
+
+ public function unpackValue($value)
+ {
+ if(empty($value))
+ return null;
+
+ if(is_string($value) && preg_match('/^[0-9]+$/', $value))
+ $value = (int) $value;
+
+ if(! is_int($value))
+ throw new Exception('Reference with non-integer value');
+
+ $factoryName = $this->getFactoryNameOfClass($this->className); // XXX Use attribute?
+ $factory = new $factoryName();
+ return $factory->loadById($value);
+ }
+
+ private const CLASSNAME_MAP = array(
+
+ );
+
+ /**
+ * @todo This must be done better and more cleanly
+ * @param string $className
+ * @return AbstractCommonClubsModelFactory
+ */
+ private function getFactoryNameOfClass($className)
+ {
+ if(empty(self::CLASSNAME_MAP[$className]))
+ {
+ $parts = array();
+ if(preg_match('/^CommonClubsModel(.*)/', $className, $parts))
+ {
+ return "CommonClubsModelFactory{$parts[1]}";
+ }
+ throw new Exception("Unknown mapping of class $className");
+ }
+
+ return self::CLASSNAME_MAP[$className];
+ }
+
+}
diff --git a/src/admin/common/models/column/string.php b/src/admin/common/models/column/string.php
new file mode 100644
index 0000000..fe2140f
--- /dev/null
+++ b/src/admin/common/models/column/string.php
@@ -0,0 +1,22 @@
+q($value);
+ }
+
+
+}
diff --git a/src/admin/common/models/factory/club.php b/src/admin/common/models/factory/club.php
new file mode 100644
index 0000000..684db95
--- /dev/null
+++ b/src/admin/common/models/factory/club.php
@@ -0,0 +1,34 @@
+ `state` enum('regular', 'vacant', 'temporary') NOT NULL DEFAULT 'vacant',
+ );
+ }
+
+ public function getTableName()
+ {
+ return '#__club_user_assocs';
+ }
+
+ public function getClassName()
+ {
+ return 'CommonClubsModelUserassoc';
+ }
+
+}
diff --git a/src/admin/common/models/join/innner.php b/src/admin/common/models/join/innner.php
new file mode 100644
index 0000000..4b30dbd
--- /dev/null
+++ b/src/admin/common/models/join/innner.php
@@ -0,0 +1,12 @@
+innerJoin($str);
+ }
+}
diff --git a/src/admin/common/models/join/left.php b/src/admin/common/models/join/left.php
new file mode 100644
index 0000000..dfaa740
--- /dev/null
+++ b/src/admin/common/models/join/left.php
@@ -0,0 +1,12 @@
+leftJoin($str);
+ }
+}
diff --git a/src/admin/common/models/join/outer.php b/src/admin/common/models/join/outer.php
new file mode 100644
index 0000000..dfe527d
--- /dev/null
+++ b/src/admin/common/models/join/outer.php
@@ -0,0 +1,12 @@
+outerJoin($str);
+ }
+}
diff --git a/src/admin/common/models/join/right.php b/src/admin/common/models/join/right.php
new file mode 100644
index 0000000..9758e17
--- /dev/null
+++ b/src/admin/common/models/join/right.php
@@ -0,0 +1,12 @@
+rightJoin($str);
+ }
+}
diff --git a/src/admin/common/models/offer.php b/src/admin/common/models/offer.php
new file mode 100644
index 0000000..8040504
--- /dev/null
+++ b/src/admin/common/models/offer.php
@@ -0,0 +1,37 @@
+getValues()['name'];
+ }
+
+ public function setName($name)
+ {
+ $this->setValue('name', $name);
+ }
+
+ /*public function getClubs()
+ {
+ return $this->fetchAssociatedElements(new CommonClubsModelFactoryClub(), '');
+ }*/
+
+ protected function prepareDelete($db)
+ {
+ $q = $db->getQuery(true);
+ $q->delete('#__club_offer_assocs');
+ $q->where("offerid = {$this->getId()}");
+ $db->setQuery($q);
+ $db->execute();
+ }
+}
+
diff --git a/src/admin/common/models/offerassoc.php b/src/admin/common/models/offerassoc.php
new file mode 100644
index 0000000..5f59cd8
--- /dev/null
+++ b/src/admin/common/models/offerassoc.php
@@ -0,0 +1,49 @@
+getValues()['club'];
+ }
+
+ /**
+ *
+ * @param CommonClubsModelClub $club
+ */
+ public function setClub($club)
+ {
+ $this->setValue('club', $club);
+ }
+
+ /**
+ *
+ * @return CommonClubsModelOffer
+ */
+ public function getOffer()
+ {
+ return $this->getValues()['offer'];
+ }
+
+ /**
+ *
+ * @param CommonClubsModelOffer $offer
+ */
+ public function setOffer($offer)
+ {
+ $this->setValue('offer', $offer);
+ }
+
+}
diff --git a/src/admin/common/models/place.php b/src/admin/common/models/place.php
new file mode 100644
index 0000000..0b55d8b
--- /dev/null
+++ b/src/admin/common/models/place.php
@@ -0,0 +1,43 @@
+getValues()['name'];
+ }
+
+ public function getClub()
+ {
+ return $this->getValues()['club'];
+ }
+
+ public function getArea()
+ {
+ return $this->getValues()['area'];
+ }
+
+ public function setName($name)
+ {
+ $this->setValue('name', $name);
+ }
+
+ public function setArea($area)
+ {
+ $this->setValue('area', $area);
+ }
+
+ public function setClub($club)
+ {
+ $this->setValue('club', $club);
+ }
+
+}
\ No newline at end of file
diff --git a/src/admin/common/models/position.php b/src/admin/common/models/position.php
new file mode 100644
index 0000000..0c836ae
--- /dev/null
+++ b/src/admin/common/models/position.php
@@ -0,0 +1,32 @@
+getValues()['name'];
+ }
+
+ public function setName($name)
+ {
+ $this->setValue('name', $name);
+ }
+
+ protected function prepareDelete($db)
+ {
+ $q = $db->getQuery(true);
+ $q->delete('#__club_user_assocs');
+ $q->where("positionid = {$this->getId()}");
+ $db->setQuery($q);
+ $db->execute();
+ }
+
+}
diff --git a/src/admin/common/models/user.php b/src/admin/common/models/user.php
new file mode 100644
index 0000000..0ad1b5e
--- /dev/null
+++ b/src/admin/common/models/user.php
@@ -0,0 +1,205 @@
+getValues()['name'];
+ }
+
+ public function setName($name)
+ {
+ $this->setValue('name', $name);
+ }
+
+ public function getUsername()
+ {
+ return $this->getValues()['user'];
+ }
+
+ public function setUsername($user)
+ {
+ // XXX Check for validity
+ $this->setValue('user', $user);
+ }
+
+ public function getAddress()
+ {
+ return $this->getValues()['address'];
+ }
+
+ public function setAddress($address)
+ {
+ $this->setValue('address', $address);
+ }
+
+ public function getCity()
+ {
+ return $this->getValues()['city'];
+ }
+
+ public function setCity($city)
+ {
+ $this->setValue('city', $city);
+ }
+
+ public function getMail()
+ {
+ return $this->getValues()['mail'];
+ }
+
+ public function setMail($mail) {
+ $this->setValue('mail', $mail);
+ }
+
+ public function getPhone()
+ {
+ return $this->getValues()['phone'];
+ }
+
+ public function setPhone($phone)
+ {
+ $this->setValue('phone', $phone);
+ }
+
+ public function getMobile()
+ {
+ return $this->getValues()['mobile'];
+ }
+
+ public function setMobile($mobile)
+ {
+ $this->setValue('mobile', $mobile);
+ }
+
+ public function isPasswordValid($password)
+ {
+ $hash = $this->getValues()['password'];
+
+ if(password_verify($password, $hash))
+ return true;
+ else
+ return false;
+ }
+
+ public function checkRehashNeeded($newPassword, $check = false)
+ {
+ $hash = $this->getValues()['password'];
+ if(password_needs_rehash($hash, PASSWORD_DEFAULT))
+ {
+ if($check)
+ {
+ if(! $this->isPasswordValid($newPassword))
+ throw new Exception('Password did not match.');
+ }
+
+ $this->setPassword($newPassword);
+ return true;
+ }
+ else
+ return false;
+ }
+
+ public function setPassword($password)
+ {
+ $hash = password_hash($password, PASSWORD_DEFAULT);
+ $this->setValue('password', $hash);
+ }
+
+ public function isPasswordSet()
+ {
+ $password = $this->getValues()['password'];
+ return isset($password) && strlen($password) > 0;
+ }
+
+ public function getPositions()
+ {
+ return $this->fetchAssociatedElements(new CommonClubsModelFactoryUserassoc(), 'userid');
+ }
+
+ public function isPasswordSuitable($password)
+ {
+ if(strlen($password) < 8)
+ return false;
+
+ $pwdLower = strtolower($password);
+ $userLower = strtolower($this->getName());
+
+ if(strpos($pwdLower, $userLower) || strpos($userLower, $pwdLower))
+ return false;
+
+ if(
+ preg_match('/.*[a-z].*/', $password) === false ||
+ preg_match('/.*[A-Z].*/', $password) === false
+ )
+ return false;
+
+ return true;
+ }
+
+ public function isUsernameFree($user)
+ {
+ $factory = new CommonClubsModelFactoryUser();
+ $users = $factory->loadElements(null, null, function($q) use ($user){
+ $q->where('main.user = ' . $q->q($user));
+ });
+
+ if(sizeof($users) == 0)
+ return true;
+ elseif(sizeof($users) == 1)
+ {
+ if($this->getId() == $users[0]->getId())
+ return true;
+ else
+ return false;
+ }
+ else
+ throw new Exception('The database is inconsistent!');
+ }
+
+ protected function prepareDelete($db)
+ {
+ $q = $db->getQuery(true);
+ $q->delete('#__club_user_assocs')->where("userid = {$this->getId()}");
+ $db->setQuery($q);
+ $db->execute();
+ }
+
+ public function dataIsValid()
+ {
+ if(! parent::dataIsValid())
+ return false;
+
+ if(! $this->usernameIsValid())
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ private function usernameIsValid()
+ {
+ $factory = $this->getFactory();
+ $medb = $factory->loadById($this->getId(), false);
+
+ if($medb !== null && $medb->getUserName() === $this->getUsername())
+ // No change was made
+ return true;
+
+ if(! $this->isUsernameFree($this->getUsername()) )
+ return false;
+
+ return true;
+ }
+
+}
+
\ No newline at end of file
diff --git a/src/admin/common/models/userassoc.php b/src/admin/common/models/userassoc.php
new file mode 100644
index 0000000..ab1aa10
--- /dev/null
+++ b/src/admin/common/models/userassoc.php
@@ -0,0 +1,119 @@
+getValues()['user'];
+ }
+
+ /**
+ *
+ * @return CommonClubsModelPosition
+ */
+ public function getPosition()
+ {
+ return $this->getValues()['position'];
+ }
+
+ /**
+ *
+ * @return CommonClubsModelClub
+ */
+ public function getClub()
+ {
+ return $this->getValues()['club'];
+ }
+
+ public function setUser($user)
+ {
+ $this->setValue('user', $user);
+ }
+
+ public function setPosition($position)
+ {
+ $this->setValue('position', $position);
+ }
+
+ public function setClub($club)
+ {
+ $this->setValue('club', $club);
+ }
+
+ public function isAdmin()
+ {
+ return $this->getValues()['admin'] == 1;
+ }
+
+ public function setAdmin($admin)
+ {
+ if($admin)
+ $this->setValue('admin', 1);
+ else
+ $this->setValue('admin', 0);
+ }
+
+ public function getAddress()
+ {
+ return $this->getValues()['address'];
+ }
+
+ public function setAddress($address)
+ {
+ $this->setValue('address', $address);
+ }
+
+ public function getMail()
+ {
+ return $this->getValues()['mail'];
+ }
+
+ public function setMail($mail)
+ {
+ $this->setValue('mail', $mail);
+ }
+
+ public function getPhone()
+ {
+ return $this->getValues()['phone'];
+ }
+
+ public function setPhone($phone)
+ {
+ $this->setValue('phone', $phone);
+ }
+
+ public function getState()
+ {
+ return $this->getValues()['state'];
+ }
+
+ public function setState($state)
+ {
+ switch(strtolower($state))
+ {
+ case 'vacant':
+ case 'temporary':
+ case 'regular':
+ $state = strtolower($state);
+ break;
+
+ default:
+ throw new Exception("Unknown state \"$state\" found.");
+ }
+ $this->setValue('state', $state);
+ }
+
+}
diff --git a/src/admin/controllers/club.php b/src/admin/controllers/club.php
index 8083f6a..75d2b8d 100644
--- a/src/admin/controllers/club.php
+++ b/src/admin/controllers/club.php
@@ -6,28 +6,13 @@ defined('_JEXEC') or die;
class ClubsControllerClub extends AbstractClubsController
{
- protected function getNameOfElement()
+
+ protected function getSingleBaseName()
{
return 'club';
}
-
- protected function getDataMapping()
- {
- return array(
-// 'name' => array('required'=>true, 'name'=>'Bezeichnung', 'filter'=>'string')
- 'name' => array('required'=>true, 'name'=>'Club-Name', 'filter'=>'string'),
- 'address' => array('required'=>true, 'name'=>'Adresse', 'filter'=>'string'),
- 'city' => array('required'=>true, 'name'=>'Stadt', 'filter'=>'string'),
- 'homepage' => array('required'=>false, 'name'=>'Homepage', 'filter'=>'string'),
- 'mail' => array('required'=>true, 'name'=>'E-Mail', 'filter'=>'string'),
- 'iban' => array('required'=>true, 'name'=>'IBAN', 'filter'=>'string'),
- 'bic' => array('required'=>true, 'name'=>'BIC', 'filter'=>'string'),
- 'charitable' => array('skip_null_check'=>True),
- 'president' => array('required'=>true, 'name'=>'Vorsitzender', 'skip_null_check'=>True, 'setter'=>'setPresidentId')
- );
- }
-
- protected function filterPreCheck(&$values)
+
+ protected function filterRaw(&$values)
{
if(is_null($values['charitable']))
$values['charitable'] = false;
@@ -41,4 +26,21 @@ class ClubsControllerClub extends AbstractClubsController
{
$values['president'] = $values['president']->getId();
}
+ protected function getFactory()
+ {
+ return new CommonClubsModelFactoryClub();
+ }
+
+ protected function additionalData()
+ {
+ return array(
+ 'offers' => new CommonClubsControllerMappingInt('Angebot')
+ );
+ }
+
+ protected function saveAssocs($obj, $values)
+ {
+ $obj->setOfferIds($values['offers']);
+ }
+
}
diff --git a/src/admin/controllers/clubposition.json.php b/src/admin/controllers/clubposition.json.php
new file mode 100644
index 0000000..b946e53
--- /dev/null
+++ b/src/admin/controllers/clubposition.json.php
@@ -0,0 +1,91 @@
+input->post;
+
+ $id = $input->getCmd('id', 'new');
+ $clubid = $input->getInt('clubid');
+ $positionid = $input->getInt('positionid');
+ $state = $input->getCmd('state', 'regular');
+ $admin = $input->getCmd('admin', '0');
+ $userid = $input->getInt('userid', -1);
+ $address = $input->getString('address');
+ $mail = $input->getString('mail');
+ $phone = $input->getString('phone');
+
+ $clubFactory = new CommonClubsModelFactoryClub();
+ $club = $clubFactory->loadById($clubid);
+ $positionFactory = new CommonClubsModelFactoryPosition();
+ $position = $positionFactory->loadById($positionid);
+
+ $assocFactory = new CommonClubsModelFactoryUserassoc();
+
+ if($id === 'new')
+ {
+ $assoc = $assocFactory->createNew();
+ }
+ else
+ {
+ $assoc = $assocFactory->loadById((int) $id);
+ }
+
+ if($userid != -1)
+ {
+ $userFactory = new CommonClubsModelFactoryUser();
+ $user = $userFactory->loadById($userid);
+ }
+ else
+ {
+ $user = null;
+ }
+
+ if($state === 'vacant')
+ $user = null;
+
+ $assoc->setUser($user);
+
+ $assoc->setState($state);
+ $assoc->setAddress($address === '' ? null : $address);
+ $assoc->setMail($mail === '' ? null : $mail);
+ $assoc->setPhone($phone === '' ? null : $phone);
+ $assoc->setClub($club);
+ $assoc->setAdmin($admin);
+ $assoc->setPosition($position);
+
+ $assoc->save();
+
+ $ret = array('new' => ($id === 'new'), 'id' => $assoc->getId());
+
+ echo new JsonResponse($ret, null, false, true);
+
+// jexit();
+ }
+
+ public function delete()
+ {
+ $app = Factory::getApplication();
+ $input = $app->input->get;
+
+ $id = $input->getInt('id');
+ $factory = new CommonClubsModelFactoryUserassoc();
+ $ua = $factory->loadById($id);
+ $ua->delete();
+
+ $ret = array('id' => $id);
+
+ echo new JsonResponse($ret, null, false, true);
+ }
+
+}
diff --git a/src/admin/controllers/offer.php b/src/admin/controllers/offer.php
index 384ba1e..323c928 100644
--- a/src/admin/controllers/offer.php
+++ b/src/admin/controllers/offer.php
@@ -6,18 +6,15 @@ defined('_JEXEC') or die;
class ClubsControllerOffer extends AbstractClubsController
{
- protected function getNameOfElement()
+ protected function getSingleBaseName()
{
return 'offer';
}
- protected function getDataMapping()
+ protected function getFactory()
{
- return array(
- 'name' => array('required'=>true, 'name'=>'Bezeichnung', 'filter'=>'string')
- );
+ return new CommonClubsModelFactoryOffer();
}
-
}
diff --git a/src/admin/controllers/position.php b/src/admin/controllers/position.php
index f647c8d..3810df6 100644
--- a/src/admin/controllers/position.php
+++ b/src/admin/controllers/position.php
@@ -6,16 +6,15 @@ defined('_JEXEC') or die;
class ClubsControllerPosition extends AbstractClubsController
{
- protected function getNameOfElement()
+ protected function getFactory()
+ {
+ return new CommonClubsModelFactoryPosition();
+ }
+
+ protected function getSingleBaseName()
{
return 'position';
}
- protected function getDataMapping()
- {
- return array(
- 'name'=>array('required'=>true, 'filter'=>'string', 'name'=>'Bezeichung')
- );
- }
}
diff --git a/src/admin/controllers/user.php b/src/admin/controllers/user.php
index 4cd1f0d..a6af1e8 100644
--- a/src/admin/controllers/user.php
+++ b/src/admin/controllers/user.php
@@ -8,112 +8,99 @@ defined('_JEXEC') or die;
class ClubsControllerUser extends AbstractClubsController
{
- private function checkUserName($username, $obj = null)
- {
- $id = -1;
-
- if(!is_null($obj))
- $id = $obj->getId();
-
- return ClubsUser::isUserNameFree($username, $id);
- }
-
- protected function getNameOfElement()
+ protected function getSingleBaseName()
{
return 'user';
}
-
- protected function getDataMapping()
+
+ protected function rawDataIsValid($values)
{
- return array(
- 'user'=>array('required'=>true, 'name'=>'Benutzername', 'filter'=>'cmd'),
- 'pwd'=>array('required'=>false, 'name'=>'Passwort', 'filter'=>'string', 'setter'=>'setPassword'),
- 'pwdConfirm'=>array('required'=>false, 'name'=>'Passwortwiederholung', 'filter'=>'string', 'setter'=>null),
- 'name'=>array('required'=>true, 'name'=>'Bürgerlicher Name', 'filter'=>'string'),
- 'address'=>array('required'=>true, 'name'=>'Adresse', 'filter'=>'string'),
- 'city'=>array('required'=>true, 'name'=>'Stadt', 'filter'=>'string'),
- 'mail'=>array('required'=>true, 'name'=>'E-Mail', 'filter'=>'string'),
- 'phone'=>array('required'=>false, 'name'=>'Telefonnummer', 'filter'=>'string'),
- 'mobile'=>array('required'=>false, 'name'=>'Handynummer', 'filter'=>'string')
-
- );
- }
- /**
- * {@inheritDoc}
- * @see AbstractClubsController::checkData()
- */
- protected function checkDataIsValid($values, $isNew, $obj)
- {
- if(! parent::checkDataIsValid($values, $isNew, $obj))
+ if(! parent::rawDataIsValid($values))
return false;
- // TODO Auto-generated method stub
- if(isset($values['pwd']) && strlen($values['pwd']) > 0)
+ if($this->passwordIsSet($values))
{
- $pwd = $values['pwd'];
- $pwdConfirm = $values['pwdConfirm'];
-
- if(trim($pwd) != trim($pwdConfirm))
- {
- Factory::getApplication()->enqueueMessage('Die Passwörter stimmen nicht überein.', 'error');
+ if( ! $this->passwordIsValid($values))
return false;
- }
-
- if(! ClubsUser::checkPasswordStrength(trim($pwd)))
- {
- Factory::getApplication()->enqueueMessage('Das Passwort ist zu schwach.', 'error');
- return false;
- }
-
- }
- else
- {
- if($isNew)
- {
- Factory::getApplication()->enqueueMessage('Für einen neuen Benutzer muss ein Passwort vergeben werden.', 'error');
- return false;
- }
- }
-
- if(! $this->checkUserName(trim($values['user']), $obj))
- {
- Factory::getApplication()->enqueueMessage('Username ' . $$values['user'] . ' ist nicht gültig.', 'error');
- return false;
}
return true;
}
- /**
- * {@inheritDoc}
- * @see AbstractClubsController::filterPrePacking()
- */
- protected function filterPrePacking(&$values)
+ private function passwordIsSet($values)
{
- parent::filterPrePacking($values);
- unset($values['pwd']);
- unset($values['pwdConfirm']);
+ return isset($values['pwd']) && strlen($values['pwd']) > 0;
+ }
+
+ private function passwordIsValid($values)
+ {
+ $pwd = $values['pwd'];
+ $pwdConfirm = $values['pwdConfirm'];
+
+ if(trim($pwd) != trim($pwdConfirm))
+ {
+ Factory::getApplication()->enqueueMessage('Die Passwörter stimmen nicht überein.', 'error');
+ return false;
+ }
+
+ // FIXME Check password strength
+// if(! ClubsUser::checkPasswordStrength(trim($pwd)))
+// {
+// Factory::getApplication()->enqueueMessage('Das Passwort ist zu schwach.', 'error');
+// return false;
+// }
+
+ return true;
+ }
+
+ protected function getFactory()
+ {
+ return new CommonClubsModelFactoryUser();
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ * @see AbstractClubsController::filterObject()
+ * @param CommonClubsModelUser $obj
+ */
+ protected function filterObject($obj, $values)
+ {
+// if($obj->isNew() && (empty($values['pwd']) || strlen($values['pwd']) == 0) )
+
+ if(isset($values['pwd']) && strlen($values['pwd']) > 0)
+ {
+ $obj->setPassword($values['pwd']);
+ }
}
/**
* {@inheritDoc}
- * @see AbstractClubsController::applyData()
+ * @see AbstractClubsController::objectValid()
+ * @param CommonClubsModelUser $obj
*/
- public function applyData($obj, $values)
+ protected function objectValid($obj)
{
- // TODO Auto-generated method stub
- $mapping = $this->getDataMapping();
-
- if(strlen($values['pwd']) == 0)
+ if(! $obj->isPasswordSet())
{
- unset($values['pwd']);
- unset($mapping['pwd']);
+ Factory::getApplication()->enqueueMessage('Kein Passwort wurde vergeben.', 'error');
+ return false;
}
- $this->applyDataToObject($obj, $values, $mapping);
+ return true;
}
+ protected function filterRaw(&$values)
+ {
+ unset($values['password']);
+ }
-
+ protected function additionalData()
+ {
+ return array(
+ 'pwd' => new CommonClubsControllerMappingString('Passwort'),
+ 'pwdConfirm' => new CommonClubsControllerMappingString('Passwortwiederholung')
+ );
+ }
}
diff --git a/src/admin/mymodels/club.php b/src/admin/mymodels/club.php
deleted file mode 100644
index 7a5c464..0000000
--- a/src/admin/mymodels/club.php
+++ /dev/null
@@ -1,252 +0,0 @@
-address;
- }
-
- /**
- * @return string
- */
- public function getCity()
- {
- return $this->city;
- }
-
- /**
- * @return string
- */
- public function getHomepage()
- {
- return $this->homepage;
- }
-
- /**
- * @return string
- */
- public function getMail()
- {
- return $this->mail;
- }
-
- /**
- * @return string
- */
- public function getIban()
- {
- return $this->iban;
- }
-
- /**
- * @return string
- */
- public function getBic()
- {
- return $this->bic;
- }
-
- /**
- * @return bool
- */
- public function isCharitable()
- {
- return $this->charitable;
- }
-
- /**
- * @return int
- */
- public function getPresidentId()
- {
- return $this->president->getId();
- }
-
- /**
- * @return ClubsUser
- */
- public function getPresident()
- {
- return $this->president;
- }
-
- /**
- * @param string $address
- */
- public function setAddress( $address)
- {
- $this->address = $address;
- }
-
- /**
- * @param string $city
- */
- public function setCity($city)
- {
- $this->city = $city;
- }
-
- /**
- * @param string $homapge
- */
- public function setHomepage($homapge)
- {
- $this->homepage = $homapge;
- }
-
- /**
- * @param string $mail
- */
- public function setMail($mail)
- {
- $this->mail = $mail;
- }
-
- /**
- * @param string $iban
- */
- public function setIban($iban)
- {
- $this->iban = $iban;
- }
-
- /**
- * @param string $bic
- */
- public function setBic($bic)
- {
- $this->bic = $bic;
- }
-
- /**
- * @param bool $charitable
- */
- public function setCharitable(bool $charitable)
- {
- $this->charitable = $charitable;
- }
-
- /**
- * @param int $presidentId
- */
- public function setPresidentId(int $presidentId)
- {
- $this->president = ClubsUser::loadUser($presidentId);
- }
-
- /**
- * @param ClubsUser $user
- */
- public function setPresident(ClubsUser $user)
- {
- $this->president = $user;
- }
-
- /**
- * @return string
- */
- public function getName()
- {
- return $this->name;
- }
-
- /**
- * @param string $name
- */
- public function setName($name)
- {
- $this->name = $name;
- }
-
-
-
- public static function loadClubs()
- {
- return self::loadElements(self::tableName, self::className);
- }
-
- public static function loadClub($id)
- {
- return self::loadElement($id, self::tableName, self::className);
- }
-
- protected function __construct()
- {}
-
- public static function createClub()
- {
- $club = new ClubsClub();
- $club->id = 'new';
- return $club;
- }
-
-
-
-
-
- public function getPlaces()
- {
- return ClubsPlace::loadPlacesOfClub($this->id);
- }
-
-
- public function getOffers()
- {
- return 0;
- }
-
-
- protected function loadCustomData($assoc)
- {
- parent::loadCustomData($assoc);
- $this->president = ClubsUser::loadUser($assoc['president']);
- }
-
- protected function postQuoteFilter(&$values)
- {
- parent::postQuoteFilter($values);
- $values['president'] = $this->president->getId();
- }
-
- protected function prepareDelete($dbo)
- {}
-
- protected function getDataMappings()
- {
- return array('name', 'address', 'city', 'homepage', 'mail', 'iban', 'bic', 'charitable', 'president');
- }
-
- protected function getRequiredDataMappings()
- {
- return array('name', 'address', 'city', 'mail', 'iban', 'bic');
- }
-
- private const tableName = '#__club_clubs';
- private const className = 'ClubsClub';
- protected function getTableName()
- {
- return self::tableName;
- }
-
-
-
-}
diff --git a/src/admin/mymodels/offer.php b/src/admin/mymodels/offer.php
deleted file mode 100644
index b3d1f1c..0000000
--- a/src/admin/mymodels/offer.php
+++ /dev/null
@@ -1,78 +0,0 @@
-name;
- }
-
- /**
- * @param string $name
- */
- public function setName($name)
- {
- $this->name = $name;
- }
-
- protected function __construct()
- {}
-
- private const tableName = '#__club_offers';
- private const className = 'ClubsOffer';
-
- public static function getFactory()
- {
- return new class extends AbstractClubsModelFactory {
- public function __construct()
- {
- parent::__construct($this->tableName, $this->className);
- }
-
- protected function getJoins($dbo)
- {
- $ret = array();
- return $ret;
- }
-
- };
- }
-
- public static function loadOffers()
- {
- return self::loadElements(self::tableName, self::className);
- }
-
-
- public static function loadOffer(int $id)
- {
- return self::loadElement($id, self::tableName, self::className);
- }
-
- public static function createOffer()
- {
- $offer = new ClubsOffer();
- $offer->id = 'new';
- return $offer;
- }
-
- protected function getDataMappings()
- {
- return array('name');
- }
-
- protected function getTableName()
- {
- return self::tableName;
- }
-
-}
diff --git a/src/admin/mymodels/offerassociation.php b/src/admin/mymodels/offerassociation.php
deleted file mode 100644
index 2329066..0000000
--- a/src/admin/mymodels/offerassociation.php
+++ /dev/null
@@ -1,78 +0,0 @@
-offerid);
- }
-
- public function getClub()
- {
- return ClubsClub::loadClub($this->clubid);
- }
-
- public function setOffer($offer)
- {
- $this->offerid = $offer->getId();
- }
-
- public function getName()
- {
- return $this->getOffer()->getName();
- }
-
- public function setClub($club)
- {
- $this->clubid = $club->getId();
- }
-
- protected function __construct()
- {}
-
- public static function getFactory()
- {
- return new ClubsOfferAssociationFactory();
- }
-
- private const tableName = '#__club_offer_assocs';
- private const className = 'ClubsOfferAssociation';
-
- public static function loadOfferAssociationsOfClub($club)
- {
- $cid = $club->getId();
- return self::loadElements(self::tableName, self::className, "clubid = $cid");
- // FIXME Use join to make access faster
- }
-
-
- public static function loadOfferAssociation(int $id)
- {
- return self::loadElement($id, self::tableName, self::className);
- }
-
- public static function createOfferAssociation()
- {
- $offer = new ClubsOfferAssociation();
-// $offer->id = 'new';
- return $offer;
- }
-
- protected function getDataMappings()
- {
-// return array('name');
- }
-
- protected function getTableName()
- {
- return self::tableName;
- }
-
-}
diff --git a/src/admin/mymodels/offerassociationfactory.php b/src/admin/mymodels/offerassociationfactory.php
deleted file mode 100644
index 5853657..0000000
--- a/src/admin/mymodels/offerassociationfactory.php
+++ /dev/null
@@ -1,32 +0,0 @@
- '#__club_offers',
- 'alias' => 'offer',
- 'on' => 'main.offerid = offer.id',
- 'select' => 'id as offerId'
- );
- $ret[] = array(
- 'name' => '#__club_clubs',
- 'alias' => 'club',
- 'on' => 'main.clubid = club.id',
- 'select' => 'id AS clubId'
- );
- return $ret;
- }
-
-}
diff --git a/src/admin/mymodels/place.php b/src/admin/mymodels/place.php
deleted file mode 100644
index c1b7fcd..0000000
--- a/src/admin/mymodels/place.php
+++ /dev/null
@@ -1,113 +0,0 @@
-name;
- }
-
- /**
- * @param string $name
- */
- public function setName(string $name)
- {
- $this->name = $name;
- }
-
- /**
- * @return string
- */
- public function getAddress()
- {
- return $this->address;
- }
-
- /**
- * @return string
- */
- public function getArea()
- {
- return $this->area;
- }
-
- /**
- * @param string $address
- */
- public function setAddress(string $address)
- {
- $this->address = $address;
- }
-
- /**
- * @param string $area
- */
- public function setArea(string $area)
- {
- $this->area = $area;
- }
-
-
- public function getClub()
- {
- return ClubsClub::loadClub($this->clubid);
- }
-
- public function setClub($club)
- {
- $this->clubid = $club->getId();
- }
-
-
- protected function __construct()
- {}
-
- public static function loadPlaces()
- {
- return self::loadElements(self::tableName, self::className);
- }
-
- public static function loadPlacesOfClub($clubId)
- {
- return self::loadElements(self::tableName, self::className, "clubid = $clubId");
- }
-
- public static function loadPlace(int $id)
- {
- return self::loadElement($id, self::tableName, self::className);
- }
-
- public static function createPlace()
- {
- $place = new ClubsPlace();
- $place->id = 'new';
- return $place;
- }
-
- protected function getDataMappings()
- {
- return array('name', 'address', 'area', 'clubid');
- }
-
- private const tableName = '#__club_places';
- private const className = 'ClubsPlace';
-
- protected function getTableName()
- {
- return self::tableName;
- }
-
-
-}
diff --git a/src/admin/mymodels/position.php b/src/admin/mymodels/position.php
deleted file mode 100644
index 79d9a39..0000000
--- a/src/admin/mymodels/position.php
+++ /dev/null
@@ -1,66 +0,0 @@
-name;
- }
-
- /**
- * @param string $name
- */
- public function setName(string $name)
- {
- $this->name = $name;
- }
-
- protected function __construct()
- {}
-
- private const tableName = '#__club_positions';
- private const className = 'ClubsPosition';
-
- public static function loadPositions()
- {
- return self::loadElements(self::tableName, self::className);
- }
-
-// public static function loadPositions($clubId)
-// {
-// return self::loadElements(self::tableName, self::className, "clubid = $clubId");
-// }
-
- public static function loadPosition(int $id)
- {
- return self::loadElement($id, self::tableName, self::className);
- }
-
- public static function createPosition()
- {
- $position = new ClubsPosition();
- $position->id = 'new';
- return $position;
- }
-
- protected function getDataMappings()
- {
- return array('name');
- }
-
- protected function getTableName()
- {
- return self::tableName;
- }
-
-
-
-}
diff --git a/src/admin/mymodels/user.php b/src/admin/mymodels/user.php
deleted file mode 100644
index 892a772..0000000
--- a/src/admin/mymodels/user.php
+++ /dev/null
@@ -1,298 +0,0 @@
-mail;
- }
-
- /**
- * @param string $mail
- */
- public function setMail($mail)
- {
- $this->mail = $mail;
- }
-
- /**
- * @return string
- */
- public function getUser()
- {
- return $this->user;
- }
-
- /**
- * @return string
- */
- public function getHash()
- {
- return $this->password;
- }
-
- /**
- * @return string
- */
- public function getName()
- {
- return $this->name;
- }
-
- /**
- * @return string
- */
- public function getAddress()
- {
- return $this->address;
- }
-
- /**
- * @return string
- */
- public function getCity()
- {
- return $this->city;
- }
-
- /**
- * @return string
- */
- public function getPhone()
- {
- return $this->phone;
- }
-
- /**
- * @return string
- */
- public function getMobile()
- {
- return $this->mobile;
- }
-
- /**
- * @param string $user
- */
- public function setUser($user, bool $force = false)
- {
- if($this->id === 'new')
- $valid = self::isUserNameFree($user);
- else
- $valid = self::isUserNameFree($user, $this->id);
-
- if(!$force && ! $valid)
- throw new UserInvalidException();
-
- $this->user = $user;
- }
-
- /**
- * @param string $hash
- */
- public function setPassword(string $password)
- {
- if(! $this->checkPasswordStrength($password))
- throw new PasswordInvalidException();
-
- $this->password = password_hash($password, PASSWORD_DEFAULT);
- }
-
- public function isPasswordValid(string $password)
- {
- $valid = password_verify($password, $this->password);
-
- if($valid)
- {
- $this->checkForRehashing($password);
- }
-
- return $valid;
- }
-
- /**
- * @param string $name
- */
- public function setName($name)
- {
- $this->name = $name;
- }
-
- /**
- * @param string $address
- */
- public function setAddress($address)
- {
- $this->address = $address;
- }
-
- /**
- * @param string $city
- */
- public function setCity($city)
- {
- $this->city = $city;
- }
-
- /**
- * @param string $phone
- */
- public function setPhone($phone)
- {
- $this->phone = $phone;
- }
-
- /**
- * @param string $mobile
- */
- public function setMobile($mobile)
- {
- $this->mobile = $mobile;
- }
-
- protected function __construct()
- {}
-
- private const tableName = '#__club_users';
- private const className = 'ClubsUser';
-
- public static function loadUsers()
- {
- return self::loadElements(self::tableName, self::className);
- }
-
- public static function loadUser(int $id)
- {
- return self::loadElement($id, self::tableName, self::className);
- }
-
- public static function createUser()
- {
- $user = new ClubsUser();
- $user->id = 'new';
- return $user;
- }
-
- private function updateUser()
- {
- $dbo = Factory::getDbo();
- $q = $dbo->getQuery(true);
-
- $vuser = $q->q($this->user);
- $vpassword = $q->q($this->password);
- $vname = $q->q($this->name);
- $vaddress = $q->q($this->address);
- $vcity = $q->q($this->city);
- $vmail = $q->q($this->mail);
- $vphone = empty($this->phone) ? 'NULL' : $q->q($this->phone);
- $vmobile = empty($this->mobile) ? 'NULL' : $q->q($this->mobile);
- // FIXME Check null vlaues
- $q->update('#__club_users')
- ->set(array(
- "user=$vuser",
- "password=$vpassword",
- "name=$vname",
- "address = $vaddress",
- "city=$vcity",
- "mail=$vmail",
- "phone=$vphone",
- "mobile=$vmobile"
- ))
- ->where("id=". (int) $this->id)
- ;
-
- $dbo->setQuery($q);
- $dbo->execute();
- }
-
- private function checkForRehashing(string $password)
- {
- if($this->id === 'new')
- return;
-
- if(password_needs_rehash($this->password, PASSWORD_DEFAULT) || true)
- {
- $copy = ClubsUser::loadUser($this->id);
- $copy->password = password_hash($password, PASSWORD_DEFAULT);
- $copy->save();
-
-// $this->password = password_hash($password, PASSWORD_DEFAULT);
-
-// $dbo = Factory::getDbo();
-
-// $q = $dbo->getQuery(true);
-// $q->update(self::tableName)->set('password=' . $q->q($this->password))->where('id=' . (int) $this->id);
-// $dbo->setQuery($q);
-// $dbo->execute();
- }
- }
-
- public static function isUserNameFree($username, int $id = -1)
- {
- $db = Factory::getDbo();
- $q = $db->getQuery(true);
- $q->select('COUNT(*)')->from(self::tableName)
- ->where('id <> ' . (int) $id)
- ->where('user = ' . $q->q($username));
- $db->setQuery($q);
- $db->execute();
- $row = $db->loadRow();
- return $row[0] == 0;
- }
-
- public static function checkPasswordStrength($pwd)
- {
- if(strlen($pwd) < 6)
- return false;
-
- if(preg_match_all('/[A-Z]/', $pwd) === false)
- return false;
-
- if(preg_match_all('/[a-z]/', $pwd) === false)
- return false;
-
- if(preg_match_all('/[0-9]/', $pwd) === false)
- return false;
-
- return true;
- }
-
- protected function getDataMappings()
- {
- return array('user', 'password', 'name', 'address', 'city', 'mail', 'phone', 'mobile');
- }
-
- protected function getRequiredDataMappings()
- {
- return array('user', 'password', 'name', 'address', 'city', 'mail');
- }
-
- protected function getTableName()
- {
- return self::tableName;
- }
-
-}
diff --git a/src/admin/res/club/admin-club.css b/src/admin/res/club/admin-club.css
new file mode 100644
index 0000000..5ed57ba
--- /dev/null
+++ b/src/admin/res/club/admin-club.css
@@ -0,0 +1,51 @@
+
+#dialog-club {
+ width: 100vw;
+ height: 100vh;
+ position: fixed;
+ left: 0pt;
+ top: 0pt;
+ z-index: 1500;
+ /*border-style: solid;*/
+}
+
+#dialog-club > .dialog {
+ background-color: white;
+ width: 70vw;
+ height: 60vh;
+ position: absolute;
+ left: 15vw;
+ top: 20vh;
+ /*z-index: 100;*/
+ border-style: solid;
+ /*visibility: visible;*/
+ overflow: auto;
+ padding: 1em;
+}
+
+#dialog-club > .background {
+ background-color: gray;
+ width: 100vw;
+ height: 100vh;
+ position: absolute;
+ left: 0pt;
+ top: 0pt;
+ /*z-index: 1000;*/
+ opacity: 0.5;
+}
+
+.dialog-hidden {
+ display: none;
+}
+
+.dialog-entry-hidden {
+ visibility: hidden;
+}
+
+.form-disabled {
+ overflow: hidden;
+}
+
+#hidden-id {
+ display: none;
+}
diff --git a/src/admin/res/club/club.js b/src/admin/res/club/club.js
new file mode 100644
index 0000000..ca4b89f
--- /dev/null
+++ b/src/admin/res/club/club.js
@@ -0,0 +1,102 @@
+
+jQuery(function($){
+
+ function closeDialog() {
+ $('#dialog-club > .dialog').html('');
+ $('body').removeClass('form-disabled');
+ $('#dialog-club').addClass('dialog-hidden');
+ }
+
+ function openDialog(data) {
+// console.log(data);
+ $('#dialog-club > .dialog').html(data);
+ $('body').addClass('form-disabled');
+ $('#dialog-club').removeClass('dialog-hidden');
+ }
+
+ $('#new-position').click(function(ev){
+ ev.preventDefault();
+
+ var url = $('#new-position').attr('href');
+ $.get(url, function(data){
+ openDialog(data);
+ });
+
+ });
+
+ $(document).on('click', '#clubposition-abort', function(ev){
+ ev.preventDefault();
+ closeDialog();
+ });
+
+ $(document).on('change', '#clubposition-state', function(){
+ if($('#clubposition-state').val() == "vacant")
+ $('#clubposition-user').addClass('dialog-entry-hidden');
+ else
+ $('#clubposition-user').removeClass('dialog-entry-hidden');
+ });
+
+ $(document).on('click', '#clubposition-save', function(ev){
+ ev.preventDefault();
+
+ var data = $('#clubposition-form').serializeArray();
+
+ $.post($('#clubposition-form').attr('action'), data, function(data){
+// console.log(data)
+
+ if(data.success)
+ {
+ console.log("all right!");
+
+ var url = "index.php?option=com_clubs&view=clubposition&layout=row&id=" + data.data.id + "&club=" + $('#hidden-id').html();
+ console.log(url);
+
+ if(data.data.new) {
+ $.get(url, function(data2){
+ $("#userassocs").append(data2);
+ closeDialog();
+ });
+ } else {
+ $.get(url, function(data2){
+ $('#userassoc-' + data.data.id).html(data2);
+ closeDialog();
+ });
+ }
+ }
+ else
+ {
+ alert(data.message);
+ }
+ });
+ });
+
+ $(document).on('click', '.edit-position', function(ev){
+ ev.preventDefault();
+
+ var url = ev.currentTarget.href;
+
+ $.get(url, function(data){
+ openDialog(data);
+ });
+ });
+
+ $(document).on('click', '.del-position', function(ev){
+ ev.preventDefault();
+
+ if(confirm("Der Eintrag wird endgültig gelöscht werden. OK?")) {
+ var url = ev.currentTarget.href;
+ $.get(url, function(d){
+ if(d.success) {
+ $('#userassoc-' + d.data.id).remove();
+ }
+ });
+ }
+
+ });
+
+ $(window).on('beforeunload', function(){return "Wollen Sie die Seite wirklich verlassen? Möglicherweise sind nicht alle Daten gesichert.";});
+ $('.form-exit').click(function(){
+ $(window).off('beforeunload');
+ });
+
+});
diff --git a/src/admin/res/clubs.js b/src/admin/res/clubs.js
new file mode 100644
index 0000000..be3e993
--- /dev/null
+++ b/src/admin/res/clubs.js
@@ -0,0 +1,8 @@
+
+jQuery(function($){
+ $('#mya').click(function()
+ {
+ //alert("a");
+ console.log("a");
+ });
+});
diff --git a/src/admin/sql/mysql/install.sql b/src/admin/sql/mysql/install.sql
new file mode 100644
index 0000000..076c280
--- /dev/null
+++ b/src/admin/sql/mysql/install.sql
@@ -0,0 +1,68 @@
+
+CREATE TABLE IF NOT EXISTS `#__club_clubs` (
+ `id` int(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ `name` varchar(100) NOT NULL,
+ `address` tinytext NOT NULL,
+ `city` varchar(50) NOT NULL,
+ `homepage` varchar(100) DEFAULT NULL,
+ `mail` varchar(100) NOT NULL,
+ `iban` char(34) NOT NULL,
+ `bic` char(11) NOT NULL,
+ `charitable` tinyint(1) NOT NULL,
+ `president` int(10) NOT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `#__club_keys` (
+ `privkey` text NOT NULL,
+ `publickey` text NOT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `#__club_offer_assocs` (
+ `id` int(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ `clubid` int(10) NOT NULL,
+ `offerid` int(10) NOT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `#__club_offers` (
+ `id` int(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ `name` varchar(100) NOT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `#__club_places` (
+ `id` int(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ `clubid` int(10) NOT NULL,
+ `name` varchar(100) NOT NULL,
+ `address` tinytext NOT NULL,
+ `area` int(10) DEFAULT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `#__club_positions` (
+ `id` int(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ `name` varchar(100) NOT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `#__club_user_assocs` (
+ `id` int(10) NOT NULL AUTO_INCREMENT,
+ `clubid` int(10) NOT NULL,
+ `userid` int(10) DEFAULT NULL,
+ `positionid` int(10) NOT NULL,
+ `admin` tinyint(1) NOT NULL DEFAULT 0,
+ `state` enum('regular','vacant','temporary') NOT NULL DEFAULT 'vacant',
+ `address` tinytext DEFAULT NULL,
+ `mail` varchar(100) DEFAULT NULL,
+ `phone` varchar(50) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `#__club_users` (
+ `id` int(10) NOT NULL AUTO_INCREMENT,
+ `user` varchar(30) NOT NULL,
+ `password` varchar(150) DEFAULT NULL,
+ `name` varchar(255) NOT NULL,
+ `address` tinytext NOT NULL,
+ `city` varchar(50) NOT NULL,
+ `mail` varchar(100) NOT NULL,
+ `phone` varchar(50) DEFAULT NULL,
+ `mobile` varchar(50) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+);
diff --git a/src/admin/sql/mysql/uninstall.sql b/src/admin/sql/mysql/uninstall.sql
new file mode 100644
index 0000000..61d1555
--- /dev/null
+++ b/src/admin/sql/mysql/uninstall.sql
@@ -0,0 +1,9 @@
+
+DROP TABLE IF EXISTS `#__club_clubs`;
+DROP TABLE IF EXISTS `#__club_keys`;
+DROP TABLE IF EXISTS `#__club_offer_assocs`;
+DROP TABLE IF EXISTS `#__club_offers`;
+DROP TABLE IF EXISTS `#__club_places`;
+DROP TABLE IF EXISTS `#__club_positions`;
+DROP TABLE IF EXISTS `#__club_user_assocs`;
+DROP TABLE IF EXISTS `#__club_users`;
diff --git a/src/admin/sql/mysql/updates/0.0.1.sql b/src/admin/sql/mysql/updates/0.0.1.sql
new file mode 100644
index 0000000..e69de29
diff --git a/src/admin/sql/updates/mysql/0.0.1.sql b/src/admin/sql/updates/mysql/0.0.1.sql
deleted file mode 100644
index fd82b06..0000000
--- a/src/admin/sql/updates/mysql/0.0.1.sql
+++ /dev/null
@@ -1,18 +0,0 @@
-DROP TABLE IF EXISTS `#__club_keys`;
-CREATE TABLE `#__club_keys` (
- `privkey` text NOT NULL,
- `publickey` text NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-INSERT INTO `#__club_keys` VALUES ('-----BEGIN PRIVATE KEY-----\nMIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDvZHhLHHqmfnnP\noj5Y7AtS0UvEN8XLzNdHj/0nHBVHrXDMNul8phbCaevuaXcYTZvb9JBTAO019Bnu\nCoj6KFrk0Cw/zcVgVHryguNCr2DeLaxAXyArfkKNZPuG/kTw1mxE6ebeR886JVU0\nfQpIi3zDGAHpXxaKO7EttnvQK8NRd4h5O5EI6dCnmMn/8xY/d5G7AsZKuAxq01ZB\nmmUrkRKrQtBTwUeJWhtfT+XjOa1n1FVIwmqz4O2sqbfm0pa6PX0BNT0CUp0RI1wN\nGmF6bh/WkQ8h3jmTamzZ2cQUwDnL7ByAJqexJrrPacRbE6EotCGODjuBXDSy02PJ\nZk0fThZpAgMBAAECggEBANJaU0WU8cUo73pekzBpwY11MYFqjJiHF0ffo0/hYmWI\nZsxbGBGak/cjQdhNvgOR9nlxTfxRnR7CrqI3iaNfIHdc4PTzqBL8SMid8HohRxoT\nwf8SV19AY9SAvnAhL4z8rUhky6PYL6RlN5iWoxmZz/hSOSPKlTDEQOztI6CJQ+hp\nUFEiOLq/TSWB1DYEu6qAQRyI5wcC1QMo+zB/zBwIuM3DsB2f6Xtj86kXzU/bGeDj\nNLbsCuhRbFyMgvcJ3z6KQTvREZOGkeF22HA+ZVH7bWf00PqCEjq2I/XFHZGK61X4\nWLgNOUmVZSmGv2Kd9UJaC8VffkBnrV3XFN1n97gcP4ECgYEA/Joaw3VrbWpKsquf\nMiTuMJVyvcV9fmVhWhPNuioCwWwBx2mjGz/texd/67KNWPr7r1IGCIBnYfs3Dy+k\nOo+lAWT7oaec24dH4vjiljWrvFvZXmkpTa6j8RSqhhIVTUFSnXBkvxkEzcnUMbxK\n6A4gdggSfcMpeo3DmjGqNWTXlbkCgYEA8pzgD2VFEYq4/fgDhxKeoWSt1UPJtPxT\n4iYPXWKGdWLsEKg36oYiRXSTdan5aRwiZUXpDoFJU8vVCfmdVb2qpwPp66LwYFax\nAYuA3aPTi9npT4nDOBygVGSTY0TsxmL5asndyxl99OdoskLmS3N2UzeWMy7prRTt\nWZL7uWnU3jECgYEA+8EHLYkIcXs/SYV823gtIKTCP9rlsSSPezxDjOgz6NyhhUKG\nejEjmcuZBarl7ynt0BU6yBxZbTD39h2wW2EwvgwMMlggIDda8R7GjZieOdN89/ht\nXuvQnwTO02KQcnfJQ/pxnnfr7sHZx1v3eAIkXh67dzYcT/WcXkBjeGWx65kCgYEA\n0WU8rY0GU+GbUPfic45Kg5nVvx/G1AKEk8etszf6PQ6oGKhXun8SzUeUjhWqQmIZ\n/badM/u6QizHLtjWRs5wn73tA4eaWEv6cg7ppmJjj20AxbltWNy8NJqp6x/uDDwY\ncWbRmx3hbKLd5h1/jteU5LYxWPPAk7ZgNNN7l8gUBcECgYEAzVVKQ5dn58iHkH1i\nB3UUnTrqPD/cn7WigcWn7A6vpxqbGARkAyIXV/xqLoD8pX1G7JhqFKArC+UJzUuC\n6hgL1Hq+OJXTaN2NzcvQaIvLzsOWQebFtNfFxi0tzAE0t2/JfuFxeam0WZunaNgg\nAabygognDdEZW9HBvCydJ5N8e+s=\n-----END PRIVATE KEY-----\n','-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA72R4Sxx6pn55z6I+WOwL\nUtFLxDfFy8zXR4/9JxwVR61wzDbpfKYWwmnr7ml3GE2b2/SQUwDtNfQZ7gqI+iha\n5NAsP83FYFR68oLjQq9g3i2sQF8gK35CjWT7hv5E8NZsROnm3kfPOiVVNH0KSIt8\nwxgB6V8WijuxLbZ70CvDUXeIeTuRCOnQp5jJ//MWP3eRuwLGSrgMatNWQZplK5ES\nq0LQU8FHiVobX0/l4zmtZ9RVSMJqs+DtrKm35tKWuj19ATU9AlKdESNcDRphem4f\n1pEPId45k2ps2dnEFMA5y+wcgCansSa6z2nEWxOhKLQhjg47gVw0stNjyWZNH04W\naQIDAQAB\n-----END PUBLIC KEY-----\n');
-
-
-DROP TABLE IF EXISTS `#__club_users`;
-CREATE TABLE `#__club_users` (
- `id` int(10) NOT NULL AUTO_INCREMENT,
- `user` varchar(30) NOT NULL,
- `password` varchar(150) DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-
-INSERT INTO `#__club_users` VALUES (1,'chris','$2y$10$2/aeOfLlLwFx7JYXpaAOH.CG0ZtvkzTuK6nojvSIuOYlTbSd07CqC');
diff --git a/src/admin/views/club/tmpl/default.php b/src/admin/views/club/tmpl/default.php
index 59167e6..480d21d 100644
--- a/src/admin/views/club/tmpl/default.php
+++ b/src/admin/views/club/tmpl/default.php
@@ -7,8 +7,9 @@ defined('_JEXEC') or die;
?>
-
+
+
+
Ein Test
+
object->getId(); ?>
+
+
diff --git a/src/admin/views/club/view.html.php b/src/admin/views/club/view.html.php
index 1d1e477..82acea2 100644
--- a/src/admin/views/club/view.html.php
+++ b/src/admin/views/club/view.html.php
@@ -1,5 +1,6 @@
prepareDisplay();
- $this->users = ClubsUser::loadUsers();
+ $userFactory = new CommonClubsModelFactoryUser();
+ $this->users = $userFactory->loadElements();
- if(! $this->isNew)
- {
- $offers = ClubsOffer::loadOffers();
- $currentOffers = $this->object->getOffers();
-
- $this->offers = array_map(function($offer) use ($currentOffers){
- $mark = False;
- return array('offer'=>$offer, 'mark'=>$mark);
- }, $offers);
- }
+ JHtmlJquery::framework();
+ Factory::getDocument()->addScript('components/com_clubs/res/club/club.js');
+ Factory::getDocument()->addStyleSheet('components/com_clubs/res/club/admin-club.css');
+
+// $this->
parent::display($tpl);
}
- protected function getViewName()
+ protected function getControllerName()
{
return 'club';
}
- protected function getElementController()
+
+ protected function getFactory()
{
- return new ClubsControllerClub();
+ return new CommonClubsModelFactoryClub();
}
+
}
diff --git a/src/admin/views/clubposition/tmpl/edit.php b/src/admin/views/clubposition/tmpl/edit.php
new file mode 100644
index 0000000..877851e
--- /dev/null
+++ b/src/admin/views/clubposition/tmpl/edit.php
@@ -0,0 +1,90 @@
+
+
+
+
+Speichern
+Abbrechen
+
diff --git a/src/admin/views/clubposition/tmpl/row.php b/src/admin/views/clubposition/tmpl/row.php
new file mode 100644
index 0000000..8f1543f
--- /dev/null
+++ b/src/admin/views/clubposition/tmpl/row.php
@@ -0,0 +1,17 @@
+
+assoc->getPosition()->getName()); ?> |
+username; ?> |
+usercity; ?> |
+assoc->isAdmin()) echo ""; ?> |
+
+
+
+ |
+assoc->getId(); ?> |
diff --git a/src/admin/views/clubposition/view.html.php b/src/admin/views/clubposition/view.html.php
new file mode 100644
index 0000000..502125d
--- /dev/null
+++ b/src/admin/views/clubposition/view.html.php
@@ -0,0 +1,62 @@
+input->get;
+ $positonFactory = new CommonClubsModelFactoryPosition();
+ $userFactory = new CommonClubsModelFactoryUser();
+ $this->positions = $positonFactory->loadElements();
+ $this->users = $userFactory->loadElements();
+
+ $id = $input->getCmd('id', 'new');
+ $assocFactory = new CommonClubsModelFactoryUserassoc();
+
+ if($id !== 'new')
+ {
+ $id = (int) $id;
+
+ $this->assoc = $assocFactory->loadById($id);
+ }
+ else
+ {
+ $this->assoc = $assocFactory->createNew();
+ }
+
+ $this->id = $id;
+ $this->clubid = $input->getInt('club');
+
+ $this->username = 'Derzeit vakant.';
+ $this->usercity = '';
+ if($this->assoc->getUser() !== null)
+ {
+ $u = $this->assoc->getUser();
+ $this->username = htmlentities($u->getName());
+ $this->usercity = htmlentities($u->getCity());
+ }
+
+ parent::display($tpl);
+
+ jexit();
+ }
+ protected function getControllerName()
+ {
+ return 'position';
+ }
+
+ protected function getFactory()
+ {
+ return new CommonClubsModelFactoryPosition();
+ }
+
+}
diff --git a/src/admin/views/clubs/tmpl/default.php b/src/admin/views/clubs/tmpl/default.php
index 33c30ea..0dbab60 100644
--- a/src/admin/views/clubs/tmpl/default.php
+++ b/src/admin/views/clubs/tmpl/default.php
@@ -1,7 +1,6 @@
Bezeichnung |
- Stadt |
+ Stadt |
Homepage |
- E-Mail |
- Löschen? |
- id |
+ E-Mail |
+ |
+ id |
-clubs as $club): ?>
-getId()); ?>
+objects as $club): ?>
getHomepage()); ?>
getMail()); ?>
- getName()); ?> |
+ getId(), $this->changeUrl); ?>'>getName()); ?> |
getCity()); ?> |
|
|
- |
+ getId(), $this->delUrl); ?>'>Löschen |
getId()); ?> |
-
+
diff --git a/src/admin/views/clubs/view.html.php b/src/admin/views/clubs/view.html.php
index 09de821..91f0630 100644
--- a/src/admin/views/clubs/view.html.php
+++ b/src/admin/views/clubs/view.html.php
@@ -1,21 +1,27 @@
offers = ClubsOffer::loadOffers();
- $this->clubs = ClubsClub::loadClubs();
-
- ToolbarHelper::title('Club-Management - Clubs');
+ ToolbarHelper::title('Club-Management - Clubs', 'cube');
parent::display($tpl);
}
+ protected function getFactory()
+ {
+ return new CommonClubsModelFactoryClub();
+ }
+
+ protected function getSingleBaseName()
+ {
+ return 'club';
+ }
+
}
diff --git a/src/admin/views/offer/view.html.php b/src/admin/views/offer/view.html.php
index aa35699..e1a2bad 100644
--- a/src/admin/views/offer/view.html.php
+++ b/src/admin/views/offer/view.html.php
@@ -11,19 +11,20 @@ class ClubsViewOffer extends AbstractClubsViewSingle
{
function display($tpl = null)
{
-
- ToolbarHelper::title('Club-Management - Angebot');
+ ToolbarHelper::title('Club-Management - Angebot', 'file');
parent::display($tpl);
}
- protected function getViewName()
+ protected function getFactory()
+ {
+ return new CommonClubsModelFactoryOffer();
+ }
+ protected function getControllerName()
{
return 'offer';
}
- protected function getElementController()
- {
- return new ClubsControllerOffer();
- }
+
+
}
diff --git a/src/admin/views/offers/tmpl/default.php b/src/admin/views/offers/tmpl/default.php
index 433af8d..470fbd5 100644
--- a/src/admin/views/offers/tmpl/default.php
+++ b/src/admin/views/offers/tmpl/default.php
@@ -11,18 +11,18 @@ defined('_JEXEC') or die;
Bezeichnung |
- Löschen? |
+ |
id |
-offers as $offer): ?>
+objects as $offer): ?>
getId()); ?>
- getName()); ?> |
- getId()); ?>'>Del |
+ getId(), $this->changeUrl); ?>'>getName()); ?> |
+ getId(), $this->delUrl); ?>'>Löschen |
getId()); ?> |
-
+
diff --git a/src/admin/views/offers/view.html.php b/src/admin/views/offers/view.html.php
index 36b7fbb..dff78b7 100644
--- a/src/admin/views/offers/view.html.php
+++ b/src/admin/views/offers/view.html.php
@@ -1,20 +1,27 @@
offers = ClubsOffer::loadOffers();
-
- ToolbarHelper::title('Club-Management - Angebote');
+ ToolbarHelper::title('Club-Management - Angebote', 'list');
parent::display($tpl);
}
+ protected function getFactory()
+ {
+ return new CommonClubsModelFactoryOffer();
+ }
+
+ protected function getSingleBaseName()
+ {
+ return 'offer';
+ }
+
}
diff --git a/src/admin/views/position/view.html.php b/src/admin/views/position/view.html.php
index bfd13a0..150fedc 100644
--- a/src/admin/views/position/view.html.php
+++ b/src/admin/views/position/view.html.php
@@ -9,19 +9,20 @@ JLoader::register("ClubsControllerPosition", JPATH_ROOT . "/administrator/compon
class ClubsViewPosition extends AbstractClubsViewSingle
{
- protected function getViewName()
+
+ function display($tpl = null)
+ {
+ ToolbarHelper::title('Club-Management - Position', 'users');
+ parent::display($tpl);
+ }
+ protected function getControllerName()
{
return 'position';
}
- protected function getElementController()
+ protected function getFactory()
{
- return new ClubsControllerPosition();
+ return new CommonClubsModelFactoryPosition();
}
- function display($tpl = null)
- {
- ToolbarHelper::title('Club-Management - Position');
- parent::display($tpl);
- }
}
diff --git a/src/admin/views/positions/tmpl/default.php b/src/admin/views/positions/tmpl/default.php
index ff8a4fa..6fbb9b3 100644
--- a/src/admin/views/positions/tmpl/default.php
+++ b/src/admin/views/positions/tmpl/default.php
@@ -1,7 +1,6 @@
Bezeichnung |
- Löschen? |
+ |
id |
-positions as $position): ?>
-getId()); ?>
+objects as $position): ?>
- getName()); ?> |
- getId()); ?>'>Del |
+ getId(), $this->changeUrl); ?>'>getName()); ?> |
+ getId(), $this->delUrl); ?>'>Löschen |
getId()); ?> |
-
+
diff --git a/src/admin/views/positions/view.html.php b/src/admin/views/positions/view.html.php
index d165d50..dd7d94c 100644
--- a/src/admin/views/positions/view.html.php
+++ b/src/admin/views/positions/view.html.php
@@ -1,20 +1,27 @@
positions = ClubsPosition::loadPositions();
-
- ToolbarHelper::title('Club-Management - Positionen');
+ ToolbarHelper::title('Club-Management - Positionen', 'users');
parent::display($tpl);
}
+ protected function getFactory()
+ {
+ return new CommonClubsModelFactoryPosition();
+ }
+
+ protected function getSingleBaseName()
+ {
+ return 'position';
+ }
+
}
diff --git a/src/admin/views/test/tmpl/default.php b/src/admin/views/test/tmpl/default.php
new file mode 100644
index 0000000..c114058
--- /dev/null
+++ b/src/admin/views/test/tmpl/default.php
@@ -0,0 +1,24 @@
+
+
+ClubName: club->getName(); ?>
+ClubName: club->getAddress(); ?>
+ClubName: club->getCity(); ?>
+ClubName: club->getHomepage(); ?>
+ClubName: club->getMail(); ?>
+ClubName: club->getIban(); ?>
+ClubName: club->getBic(); ?>
+ClubName: club->isCharitable(); ?>
+ClubName: club->getPresident()->getName(); ?>
+club->getPlaces() as $place): ?>
+Place: getName(); ?>
+
+
+Output
+log); ?>
+
+Test Link
diff --git a/src/admin/views/test/tmpl/foo.php b/src/admin/views/test/tmpl/foo.php
new file mode 100644
index 0000000..24670a8
--- /dev/null
+++ b/src/admin/views/test/tmpl/foo.php
@@ -0,0 +1,8 @@
+
+This is foo.
diff --git a/src/admin/views/test/view.html.php b/src/admin/views/test/view.html.php
new file mode 100644
index 0000000..c080266
--- /dev/null
+++ b/src/admin/views/test/view.html.php
@@ -0,0 +1,64 @@
+log = '';
+
+ $factory = new CommonClubsModelFactoryClub();
+ $this->clubs = $factory->loadElements();
+
+ $this->club = $this->clubs[0];
+
+ $c = $factory->loadById(1);
+ $p = $c->getPresident();
+ $id = $p->getId();
+
+ $places = $c->getPlaces();
+// $places[0]->setName("abc");
+// $places[0]->save();
+
+ $pfactory = new CommonClubsModelFactoryPlace();
+ $np = $pfactory->createNew();
+ $np->setName('MyName');
+ $np->setClub($c);
+// $np->save();
+ $np->getId();
+
+ $np = $c->getPlaces()[2];
+ $np->getName();
+// $np->setName('foo2 with new Name');
+// $np->save();
+// $np->delete();
+ $this->log = $np;
+
+ parent::display($tpl);
+ //Factory::getDocument()->addScript( "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" );
+ JHtmlJquery::framework();
+ Factory::getDocument()->addScript('components/com_clubs/res/clubs.js');
+ //jexit();
+ }
+
+ protected function getViewName()
+ {
+ return 'club';
+ }
+ protected function getElementController()
+ {
+ return new ClubsControllerClub();
+ }
+
+
+}
diff --git a/src/admin/views/user/tmpl/default.php b/src/admin/views/user/tmpl/default.php
index cf6632b..e57da72 100644
--- a/src/admin/views/user/tmpl/default.php
+++ b/src/admin/views/user/tmpl/default.php
@@ -8,11 +8,12 @@ defined('_JEXEC') or die;
?>
diff --git a/src/admin/views/user/view.html.php b/src/admin/views/user/view.html.php
index 1fc6cd1..263da44 100644
--- a/src/admin/views/user/view.html.php
+++ b/src/admin/views/user/view.html.php
@@ -1,54 +1,71 @@
input;
- $id = $input->get->get('id');
+ $this->prepareDisplay();
- if($id === 'new')
+ if($this->isNew)
{
- $this->address = Route::_('index.php?option=com_clubs&task=user.new');
- $this->user = ClubsUser::createUser();
- $this->isNew = true;
- }
- else if(is_numeric($id))
- {
- $this->address = Route::_('index.php?option=com_clubs&task=user.change');
- $this->user = ClubsUser::loadUser((int) $id);
- $this->isNew = false;
+ $this->jobs = array();
}
else
- throw new Exception('Need a user id.');
-
- if($input->get->get('data', null, 'json') != null)
{
- // Restore previous data
- $dataurl = $input->get->get('data', null, 'json');
- $data = json_decode($dataurl, true);
+ $factory = new CommonClubsModelFactoryUser();
+ $user = $factory->loadById($this->id);
- $this->user->setUser($data['user'], true);
- $this->user->setName($data['name']);
- $this->user->setAddress($data['address']);
- $this->user->setCity($data['city']);
- $this->user->setMail($data['mail']);
- $this->user->setPhone($data['phone']);
- $this->user->setMobile($data['mobile']);
+ $positions = $user->getPositions();
+ $clubFactory = new CommonClubsModelFactoryClub();
+ $clubsPresident = $clubFactory->loadElements("main.president = {$this->id}");
+
+ $jobs = array();
+
+ foreach($clubsPresident as $club)
+ {
+ $job = array(
+ 'club' => $club->getName(),
+ 'city' => $club->getCity(),
+ 'position' => 'Vorsitzender',
+ 'url' => Route::_("index.php?option=com_clubs&view=club&id={$club->getId()}")
+ );
+ $jobs[] = $job;
+ }
+ foreach($positions as $p)
+ {
+ $c = $p->getClub();
+ $job = array(
+ 'club' => $c->getName(),
+ 'city' => $c->getCity(),
+ 'position' => $p->getPosition()->getName(),
+ 'url' => Route::_("index.php?option=com_clubs&view=club&id={$c->getId()}")
+ );
+ $jobs[] = $job;
+ }
+ $this->jobs = $jobs;
}
- ToolbarHelper::title('Club-Management - Person');
+ ToolbarHelper::title('Club-Management - Person', 'user');
parent::display($tpl);
}
+ protected function getControllerName()
+ {
+ return 'user';
+ }
+
+ protected function getFactory()
+ {
+ return new CommonClubsModelFactoryUser();
+ }
+
+
}
diff --git a/src/admin/views/users/tmpl/default.php b/src/admin/views/users/tmpl/default.php
index fd1c66f..066d170 100644
--- a/src/admin/views/users/tmpl/default.php
+++ b/src/admin/views/users/tmpl/default.php
@@ -1,6 +1,5 @@
Name
Ort |
E-Mail |
- Löschen? |
+ |
id |
-users as $user): ?>
-getId()); ?>
+objects as $user): ?>
+getId(), $this->changeUrl); ?>
- getUser()); ?> |
+ getUserName()); ?> |
getName()); ?> |
getCity()); ?> |
getMail()); ?> |
- getId()); ?>'>Del |
+ getId(), $this->delUrl); ?>'>Löschen |
getId()); ?> |
-
+
diff --git a/src/admin/views/users/view.html.php b/src/admin/views/users/view.html.php
index 2b9ce88..6389d88 100644
--- a/src/admin/views/users/view.html.php
+++ b/src/admin/views/users/view.html.php
@@ -1,22 +1,27 @@
users = ClubsUser::loadUsers();
-
ToolbarHelper::title('Club-Management - Personen', 'user');
parent::display($tpl);
}
+ protected function getFactory()
+ {
+ return new CommonClubsModelFactoryUser();
+ }
+
+ protected function getSingleBaseName()
+ {
+ return 'user';
+ }
+
}
diff --git a/src/clubs.xml b/src/clubs.xml
index 518fc17..1351157 100644
--- a/src/clubs.xml
+++ b/src/clubs.xml
@@ -5,8 +5,9 @@
type="component">
- Vereinsmanagement
+ Vereinsportal
Vereinsportal des saarländischen Tanzsportverbands
+ com_clubs
30.03.2019
@@ -25,11 +26,13 @@
-
+
clubs.php
controller.php
- controller
+ controllers
+ css
helpers
+ js
models
views
@@ -46,27 +49,36 @@
+
+
+
+
-
+
+ abstract
+ common
+ controllers
+ res
+ sql
+ views
clubs.php
controller.php
- sql
- sql/mysql/install.sql
+ sql/mysql/install.sql
- sql/mysql/uninstall.sql
+ sql/mysql/uninstall.sql
- sql/updates/mysql
+ sql/mysql/updates