diff --git a/.buildpath b/.buildpath index e9e2cb4..2c3078b 100644 --- a/.buildpath +++ b/.buildpath @@ -1,6 +1,12 @@ + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..751b666 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/clubs.tar.gz +/slt-update.xml + diff --git a/.settings/org.eclipse.php.core.prefs b/.settings/org.eclipse.php.core.prefs index d0241b4..d8b1429 100644 --- a/.settings/org.eclipse.php.core.prefs +++ b/.settings/org.eclipse.php.core.prefs @@ -1,2 +1,2 @@ eclipse.preferences.version=1 -include_path=1;/srv/slt-dev +include_path=1;/srv/slt-dev\u00051;/srv/http/slt\u00051;/home/private/slt/joomla diff --git a/.settings/org.eclipse.php.ui.prefs b/.settings/org.eclipse.php.ui.prefs new file mode 100644 index 0000000..9a3362f --- /dev/null +++ b/.settings/org.eclipse.php.ui.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.php.ui.text.custom_code_templates= diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..327d4c9 --- /dev/null +++ b/Makefile @@ -0,0 +1,47 @@ + +# UPDATE_PATH=/srv/slt-update +PACKAGES = clubs.tar.gz + +export DL_PREFIX=https://slt.wolf-stuttgart.net/update/com_clubs + +RSYNC_OPTIONS=-rltDz --delete --delete-delay --delete-excluded --exclude '.gitignore' --exclude '.dummy' +RSYNC_USER=christian +RSYNC_HOST=hh.wolf-stuttgart.net +DL_PATH=/srv/http/slt/update/com_clubs + +all: package + +package: $(PACKAGES) + +.PHONY: clubs.tar.gz +clubs.tar.gz: + tar czf $@ -C src . + +.PHONY: release +release: clubs.tar.gz + ./scripts/create-release.sh + +.PHONY: release-force +release-force: clubs.tar.gz + ./scripts/create-release.sh -f + +.PHONY: upload +upload: release + $(MAKE) reupload + +.PHONY: slt-update.xml +slt-update.xml: + ./scripts/create-update-xml.sh + +.PHONY: reupload +reupload: slt-update.xml + @echo Pushing files + @rsync $(RSYNC_OPTIONS) releases/ $(RSYNC_USER)@$(RSYNC_HOST):$(DL_PATH)/files -v + + @echo Pushing XML configuration + @rsync $(RSYNC_OPTIONS) slt-update.xml $(RSYNC_USER)@$(RSYNC_HOST):$(DL_PATH) + +# +# .PHONY: update +# update: $(PACKAGES) +# cp slt.xml slt1.tar.gz $(UPDATE_PATH) diff --git a/releases/.dummy b/releases/.dummy new file mode 100644 index 0000000..e69de29 diff --git a/releases/clubs-0.0.1.tar.gz b/releases/clubs-0.0.1.tar.gz new file mode 100644 index 0000000..c5c6b8c Binary files /dev/null and b/releases/clubs-0.0.1.tar.gz differ diff --git a/res/postfix.template b/res/postfix.template new file mode 100644 index 0000000..769fb5f --- /dev/null +++ b/res/postfix.template @@ -0,0 +1 @@ + diff --git a/res/prefix.template b/res/prefix.template new file mode 100644 index 0000000..ab72107 --- /dev/null +++ b/res/prefix.template @@ -0,0 +1,2 @@ + + 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; ?> -
+ +

Stammdaten

@@ -66,15 +67,6 @@ defined('_JEXEC') or die; isNew): ?> - - - - @@ -82,6 +74,64 @@ defined('_JEXEC') or die;
Bezeichnung
Angebote - offers as $o): ?> - getId(); ?>' > - getName()); ?>
- -
ID object->getId(); ?>
-
'>Zurück zur Übersicht + +isNew): ?> +

Angebote

+object->getOffers() as $oconf): ?> + getId(); ?>' > + getName()); ?>
+ + +

Posten

+object->getUsers()) == 0 ): ?> +

Dem Verein ist bisher kein Posten zugewiesen.

+ + + + + + + + + + + object->getUsers() as $ua): ?> + getUser(); + if($user == null) + { + $username = 'Derzeit vakant'; + $usercity = ''; + } + else + { + $username = htmlentities($user->getName()); + $usercity = htmlentities($user->getCity()); + } + ?> + + + + + + + + + +
RolleNameStadtAdmin?ID
getPosition()->getName()); ?>isAdmin()) echo ""; ?> + + + getId(); ?>
+ +

Neuen Posten einfügen

+ + +
' class='form-exit'>Zurück zur Übersicht
+
+
+
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 @@ + + +
+ + +

Posten bearbeiten

+ + + + + + + + + + + assoc->getState() === 'vacant') echo 'class="dialog-entry-hidden"'; ?>> + + + + + + + + + + + + + + + + + + + +
Funktion: + +
Status + +
Person: + +
Admin: + assoc->isAdmin() ? 'checked' : ''; ?>> +
Adresse (optional): + +
E-Mail (optional): + +
Telefon-Nr. (optional): + +
+ +
+ +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()); ?> -
'>Neuen Verein anlegen
+
Neuen Verein anlegen
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()); ?> -
'>Neues Angebot anlegen
+
Neues Angebot anlegen
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()); ?> -
'>Neuen Posten anlegen
+
Neuen Posten anlegen
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; ?>
- +

Stammdaten

+ - + @@ -24,36 +25,57 @@ defined('_JEXEC') or die; - + - + - + - + - + isNew): ?> - +
Username
Passwort
Bürgerlicher Name
Adresse - +
Stadt
E-Mail
Telefon
Handy
IDuser->getId(); ?>object->getId(); ?>
+isNew): ?> +

Verknüpfungen

+ jobs) == 0): ?> +

Es wurden keine Verknüpfungen zu der Person gefunden.

+ + + + + + + + jobs as $job): ?> + + + + + + +
PostenVereinStadt
' target='_blank'>
+ +
'>Zurück zur Übersicht
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()); ?> -
'>Neuen Benutzer anlegen
+
Neuen Benutzer anlegen
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 @@ Vereinsmanagement + Posten + Trainingsangebote + Personen + Vereine - + + 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