2 Commits

Author SHA1 Message Date
343395c661 Added some more requirements 2019-05-21 16:06:32 +02:00
16bbb09c8c Created basic structure to use rmtoo 2019-05-21 15:44:05 +02:00
133 changed files with 2440 additions and 3633 deletions

View File

@@ -1,12 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<buildpath>
<buildpathentry kind="src" path="src"/>
<buildpathentry external="true" kind="lib" path="/home/private/slt/joomla">
<accessrules>
<accessrule kind="nonaccessible" pattern="administrator/components/com_clubs"/>
</accessrules>
</buildpathentry>
<buildpathentry external="true" kind="lib" path="/home/private/slt/joomla"/>
<buildpathentry external="true" kind="lib" path="/srv/slt-dev"/>
<buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/>
<buildpathentry external="true" kind="lib" path="/srv/http/slt"/>
</buildpath>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_DISABLED_BUILDER" value="org.eclipse.texlipse.builder.TexlipseBuilder"/>
<mapAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
</launchConfiguration>

3
.gitignore vendored
View File

@@ -1,3 +0,0 @@
/clubs.tar.gz
/slt-update.xml

View File

@@ -5,6 +5,16 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/org.eclipse.texlipse.builder.TexlipseBuilder.launch</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
@@ -22,6 +32,7 @@
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.texlipse.builder.TexlipseNature</nature>
<nature>org.eclipse.php.core.PHPNature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
</natures>

View File

@@ -1,2 +1,2 @@
eclipse.preferences.version=1
include_path=1;/srv/slt-dev\u00051;/srv/http/slt\u00051;/home/private/slt/joomla
include_path=1;/srv/slt-dev

View File

@@ -1,2 +0,0 @@
eclipse.preferences.version=1
org.eclipse.php.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>

View File

@@ -1,47 +0,0 @@
# 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)

Binary file not shown.

2
requirements/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/artifacts/
/.rmtoo_dependencies

63
requirements/Config.yml Normal file
View File

@@ -0,0 +1,63 @@
---
global:
modules:
directories:
- .
processing:
analytics:
stop_on_errors: false
requirements:
input:
commit_interval:
begin: FILES
end: FILES
default_language: de_DE
dependency_notation:
- Solved by
directory: requirements
inventors:
- flonatel
- wolf
stakeholders:
- development
- management
- users
topics:
ts_common:
sources:
- - filesystem
- requirements_dirs:
- requirements/model
- requirements
topics_dirs:
- topics
topic_root_node: ReqsDocument
constraints_dirs:
- constraints
testcases_dirs:
- testcases
output:
graph:
- output_filename: artifacts/req-graph1.dot
graph2:
- output_filename: artifacts/req-graph2.dot
html:
- footer: html/footer.html
header: html/header.html
output_directory: artifacts/html
#LatexJinja2:
latex2:
- output_filename: artifacts/reqtopics.tex
#template_path: latex/LatexJinja2
prios:
- output_filename: artifacts/reqsprios.tex
stats_burndown1:
- output_filename: artifacts/stats_burndown.csv
start_date: '2011-05-01'
stats_reqs_cnt:
- output_filename: artifacts/stats_reqs_cnt.csv
stats_sprint_burndown1:
- output_filename: artifacts/stats_sprint_burndown.csv
start_date: '2011-05-01'
version1:
- output_filename: artifacts/reqs-version.txt

69
requirements/Makefile Normal file
View File

@@ -0,0 +1,69 @@
.PHONY: all
.PHONY: all_html
all: artifacts/requirements.pdf artifacts/req-graph1.png \
artifacts/req-graph2.png all_html
# Adding new files (especially requirements) can not automatically
# handled. The 'force' target tries to handle this.
.PHONY: force
force:
rm .rmtoo_dependencies
${MAKE} all
#
# This is the way the rmtoo must be called.
# (The RMTOO_CALL variable is set in the setenv.sh script)
# You can override the default Config.py file by setting
# the RMTOO_CONFIG variable from the command line.
# ie:
# make RMTOO_CONFIG=YourConfig.json
#
RMTOO_CALL ?= rmtoo
RMTOO_CONFIG=Config.yml
RMTOO_CONTRIB_DIR ?= /usr/share/rmtoo
CALL_RMTOO=${RMTOO_CALL} -y file://${RMTOO_CONFIG}
#
# Dependency handling
# The file .rmtoo_dependencies is created by rmtoo itself.
#
include .rmtoo_dependencies
all_html: ${OUTPUT_HTML}
# And how to make the dependencies
.rmtoo_dependencies:
${CALL_RMTOO} \
--create-makefile-dependencies=.rmtoo_dependencies
artifacts/req-graph1.png: artifacts/req-graph1.dot
unflatten -l 23 artifacts/req-graph1.dot | \
dot -Tpng -o artifacts/req-graph1.png
artifacts/req-graph2.png: artifacts/req-graph2.dot
dot -Tpng -o artifacts/req-graph2.png artifacts/req-graph2.dot
# Two calls are needed: one for the requirments converting and one for
# backlog creation.
artifacts/requirements.pdf: ${REQS_LATEX2} latex/requirements.tex
# (cd artifacts && \
# gnuplot ${RMTOO_CONTRIB_DIR}/contrib/gnuplot_stats_reqs_cnt.inc && \
# epstopdf stats_reqs_cnt.eps)
# (cd artifacts && \
# gnuplot ${RMTOO_CONTRIB_DIR}/contrib/gnuplot_stats_burndown.inc && \
# epstopdf stats_burndown.eps)
# (cd artifacts && \
# gnuplot ${RMTOO_CONTRIB_DIR}/contrib/gnuplot_stats_sprint_burndown.inc && \
# epstopdf stats_sprint_burndown.eps)
(cd artifacts && pdflatex ../latex/requirements.tex; \
pdflatex ../latex/requirements.tex; \
pdflatex ../latex/requirements.tex)
.PHONY: clean
clean:
rm -fr artifacts/html
rm -f artifacts/* \
add_data.py*
rm -fr debian/rmtoo build

View File

@@ -0,0 +1,8 @@
<hr/>
<span class="footer_text"><p>This document is part of the rmtoo
requirements documentation and was generated
by <a href="http://rmtoo.gnu4u.org">rmtoo</a> itself.</p>
<p>rmtoo is copyright 2010 by flonatel. rmtoo is distributed under
GPL V3.</p></span>
</body>
</html>

View File

@@ -0,0 +1,167 @@
<!DOCTYPE html>
<html>
<head>
<title>rmtoo</title>
<meta name="generator" content="rmtoo">
<style type="text/css">
<!--
h1, h2, h3 {
font-family:sans;
}
a:link, a:visited, a:active, a:hover {
text-decoration:none;
font-weight:bold;
color:#407cbf;
}
.fltext {
font-family:sans;
}
.footer_text {
font-family:sans;
font-size:small;
}
.requirment_end {
background-image:url(../trenner01.png);
margin:0px;
padding:0px;
height:2px;
}
.dlt_description {
font-family:sans;
font-size:medium;
font-weight:bold;
}
.dlv_description {
font-family:sans;
font-size:medium;
}
.dlt_rationale {
font-family:sans;
font-weight:bold;
}
.dlv_rationale {
font-family:sans;
}
.dlt_note {
font-family:sans;
font-size:small;
font-weight:bold;
}
.dlv_note {
font-family:sans;
font-size:small;
}
.dlt_depends_on {
font-family:sans;
font-size:small;
font-weight:bold;
}
.dlv_depends_on {
font-family:sans;
font-size:small;
}
.dlt_dependent {
font-family:sans;
font-size:small;
font-weight:bold;
}
.dlv_dependent {
font-family:sans;
font-size:small;
}
.dlt_id {
font-family:sans;
font-size:small;
font-weight:bold;
}
.dlv_id {
font-family:sans;
font-size:small;
}
.dlt_priority {
font-family:sans;
font-size:small;
font-weight:bold;
}
.dlv_priority {
font-family:sans;
font-size:small;
}
.dlt_owner {
font-family:sans;
font-size:small;
font-weight:bold;
}
.dlv_owner {
font-family:sans;
font-size:small;
}
.dlt_invented_on {
font-family:sans;
font-size:small;
font-weight:bold;
}
.dlv_invented_on {
font-family:sans;
font-size:small;
}
.dlt_invented_by {
font-family:sans;
font-size:small;
font-weight:bold;
}
.dlv_invented_by {
font-family:sans;
font-size:small;
}
.dlt_status {
font-family:sans;
font-size:small;
font-weight:bold;
}
.dlv_status {
font-family:sans;
font-size:small;
}
.dlt_class {
font-family:sans;
font-size:small;
font-weight:bold;
}
.dlv_class {
font-family:sans;
font-size:small;
}
-->
</style>
</head>
<body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

View File

@@ -0,0 +1,80 @@
\documentclass{report}
\usepackage[ngerman]{babel}
\usepackage{longtable}
\usepackage{graphicx}
% When latex aborts with
% pdfTeX error (ext4): \pdfendlink ended up in different nesting level than \pd
% fstartlink.
% Comment that line with draft out and inpect the errornous page
\usepackage[pdfauthor={flonatel},%
%draft,%
pdftitle={Requirment for project},%
pdfsubject={Requirment description for project},%
pdfkeywords={placeholder for some keywords},%
pagebackref=true,%
pdftex, bookmarks=true, colorlinks=true]{hyperref}
\usepackage[a4paper]{geometry}
\usepackage[titles]{tocloft}
\usepackage{fancyhdr}
\setlength{\cftsubsecnumwidth}{4em}
\pagestyle{fancy}
\fancyhead{}
\fancyfoot{}
\fancyhead[L]{\rightmark}
\fancyfoot[R]{\thepage}
% \fancyfoot[L]{Version \input{../artifacts/reqs-version.txt}}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
\parindent0em
\begin{document}
\thispagestyle{empty}
\mbox{}
\vfill
{\LARGE\textbf{Requirements for project}}
\vfill
{\Large\textbf{written by You}}
\vfill
09. October 2010
\vfill
% Requirements Version: \input{../artifacts/reqs-version.txt}
\vfill
\newpage
\tableofcontents
\newpage
\chapter{Status}
\input{../artifacts/reqsprios.tex}
\input{../artifacts/reqtopics.tex}
% \chapter{Statistics}
% \section{Burndown diagram for Sprint}
% \includegraphics{../artifacts/stats_sprint_burndown.pdf}
%
% \section{Burndown diagram for Project}
% \includegraphics{../artifacts/stats_burndown.pdf}
%
% \section{Requirements Count Statistics}
% \includegraphics{../artifacts/stats_reqs_cnt.pdf}
\end{document}

12
requirements/req.template Normal file
View File

@@ -0,0 +1,12 @@
Name: projectdfg
Type: requirement | design decision
Invented on:
Invented by: wolf
Owner: development | management | users
Description:
Rationale:
Status: not done
#Solved by:
#Priority:
#Effort estimation: 5
#Topic:

View File

@@ -0,0 +1,13 @@
Name: Definition Abstractes DB Objekt
Type: design decision
Invented on: 2019-05-21
Invented by: wolf
Owner: development
Description: Jedes Objekt in der Datenbank wird durch ein
Objekt in der Sprache repräsentiert.
Rationale:
Status: not done
Solved by: adbo-id adbo-simple adbo-lists
#Priority:
#Effort estimation: 5
Topic: model

View File

@@ -0,0 +1,13 @@
Name: Objekt-ID
Type: design decision
Invented on: 2019-05-21
Invented by: wolf
Owner: development
Description: Jedes Objekt der Datenbank hat einen eindeutigen Schlüssel
genannt \emph{id}.
Rationale:
Status: not done
#Solved by:
#Priority:
#Effort estimation: 5
Topic: model

View File

@@ -0,0 +1,13 @@
Name: Listen im Objekt
Type: design decision
Invented on: 2019-05-21
Invented by: wolf
Owner: development
Description: 1:n Beziehungen können vom gemeinsamen
Objekt aus abgefragt werden mittels Funktionsaufrufen.
Rationale:
Status: not done
#Solved by:
#Priority:
#Effort estimation: 5
Topic: model

View File

@@ -0,0 +1,15 @@
Name: n:m-Beziehungen
Type: design decision
Invented on: 2019-05-21
Invented by: wolf
Owner: development
Description: n:m Beziehugen werden wie 1:n-Beziehungen im
Objektbaum abgebildet. Im Unterschied zu einfachen Listen
muss allerdings eine Liste bei beiden Objekten erstellt werden,
so dass eine Navigation möglich ist.
Rationale:
Status: not done
#Solved by:
#Priority:
#Effort estimation: 5
Topic: model

View File

@@ -0,0 +1,14 @@
Name: Assoziative Listen
Type: design decision
Invented on: 2019-05-21
Invented by: wolf
Owner: development
Description: Relationen der Kardinalität 1:n werden als
Objekte einer separaten Tabelle mit einem Fremdschlüssel
abgelegt.
Rationale:
Status: not done
Solved by: adbo-lists-attribs adbo-lists-lists
#Priority:
#Effort estimation: 5
Topic: model

View File

@@ -0,0 +1,15 @@
Name: Triviale Attibute im Objekt
Type: design decision
Invented on: 2019-05-21
Invented by: wolf
Owner: development
Description: Einfache Attribute im Sinne einer 1:1 Beziehung
werden direkt im Objekt gespeichert. Dazu werden die Daten
in einer innerhalb der Klassenhierarchie sichtbaren Eigenschaft
\emph{values} abgelegt als assoziatives Array.
Rationale:
Status: not done
#Solved by:
#Priority:
#Effort estimation: 5
Topic: model

View File

@@ -0,0 +1,13 @@
Name: Einfache Objektstruktur
Type: design decision
Invented on: 2019-05-21
Invented by: wolf
Owner: development
Description: Einfache Attribute eines Objekts werden als Spalten
in der DB-Tabelle abgespeichert.
Rationale:
Status: not done
Solved by: adbo-simple-attribs
#Priority:
#Effort estimation: 5
Topic: model

View File

@@ -0,0 +1,13 @@
Name: Aufrufe cachen
Type: design decision
Invented on: 2019-05-21
Invented by: wolf
Owner: development
Description: DB-Aufrufe sollen soweit es möglich ist,
zwischengespeichert werden.
Rationale:
Status: not done
#Solved by:
#Priority:
#Effort estimation: 5
Topic: model

View File

@@ -0,0 +1,13 @@
Name: Anbindung der SQL
Type: design decision
Invented on: 2019-05-21
Invented by: wolf
Owner: development
Description: Die Daten in der Datenbank müssen durch einfache
Funktionsaufrufe abrufbar sein.
Rationale:
Status: not done
Solved by: abstract-object cache
#Priority:
Effort estimation: 0
Topic: model

View File

@@ -0,0 +1,12 @@
Name: projectdfg
Type: master requirement
Invented on: 2010-10-09
Invented by: flonatel
Owner: development
Description: \textsl{project} \textbf{must} exists.
Rationale: The world needs a good, usable and free \textsl{project}.
Status: not done
Solved by: sql-interface
Priority: development:10
Effort estimation: 5
Topic: ReqsDocument

View File

@@ -0,0 +1,4 @@
Name: project
Text: This is placeholder for some introductional text.
IncludeRequirements: full
SubTopic: model

View File

@@ -0,0 +1,3 @@
Name: Datenbank-Modelle
Text: Abhängigkeiten der Model-Klassen
IncludeRequirements: full

View File

@@ -1 +0,0 @@
</updates>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<updates>

View File

@@ -1,16 +0,0 @@
<update>
<name>SLT Vereinsverwaltung</name>
<description>Vereinsportal des saarländischen Tanzsportverbands</description>
<element>com_clubs</element>
<type>component</type>
<client>0</client>
<version>__VERSION__</version>
<downloads>
<downloadurl type="full" format="__FORMAT__">__DOWNLOAD_URL__</downloadurl>
</downloads>
<tags>
<tag>stable</tag>
</tags>
<maintainer>Christian Wolf</maintainer>
<targetplatform name="joomla" version=".*"/>
</update>

View File

@@ -1,23 +0,0 @@
#!/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"

View File

@@ -1,23 +0,0 @@
#!/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

View File

@@ -1 +0,0 @@
0

View File

@@ -1 +0,0 @@
0

View File

@@ -1 +0,0 @@
1

View File

@@ -7,175 +7,114 @@ 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();
/**
* @return string The name of the underlying object in lower letters.
*/
protected abstract function getSingleBaseName();
protected abstract function getNameOfElement();
/**
* @return string The name of the view to show a single object
*/
protected function getSingleViewName()
protected function getModelName()
{
return $this->getSingleBaseName();
return $this->getNameOfElement();
}
public function new()
protected function getNameOfView()
{
$factory = $this->getFactory();
$obj = $factory->createNew();
return strtolower($this->getNameOfElement());
}
protected abstract function getDataMapping();
function new()
{
$obj = call_user_func(array('Clubs' . $this->getNameOfElement(), 'create' . $this->getNameOfElement()));
$this->saveToDatabase($obj, 'new');
// 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));
}
public function change()
function change()
{
$app = Factory::getApplication();
$input = $app->input;
$id = (int) $input->post->getInt('id');
$factory = $this->getFactory();
$obj = $factory->loadById($id);
$obj = call_user_func(array('Clubs' . $this->getNameOfElement(), 'load' . $this->getNameOfElement()), (int) $id);
$this->saveToDatabase($obj, $id);
}
/**
* @param AbstractCommonClubsModel $obj
* @param int $id
*/
protected function saveToDatabase($obj, $id)
{
try
// 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)
{
// 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();
$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));
}
protected function saveAssocs($obj, $vlaues){}
protected function additionalData()
{
return array();
}
protected function loadData($additionalData)
protected function loadData()
{
$values = array();
$factory = $this->getFactory();
$input = Factory::getApplication()->input->post;
foreach($factory->getAttributes() as $column)
foreach($this->getDataMapping() as $m => $f)
{
$values[$column->getAlias()] = $column->getFilter()->getFilteredValue($input, $column->getAlias());
}
foreach($additionalData as $k => $v)
{
$values[$k] = $v->getFilteredValue($input, $k);
$filter = (isset($f['filter'])) ? $f['filter'] : 'string';
$values[$m] = $input->get($m, null, $filter);
}
return $values;
}
protected function filterRaw(&$values){}
protected function filterPreCheck(&$values){}
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)
protected function checkDataIsValid($values, bool $isNew, $obj)
{
$error = false;
$factory = $this->getFactory();
foreach($factory->getAttributes() as $column)
// Check existence of the required fields
foreach ($this->getDataMapping() as $m => $v)
{
if(! $column->getFilter()->rawValueValid($values[$column->getAlias()]))
if(! isset($v['required']) || ! $v['required'])
continue;
// Field is required
if(! $this->fieldValid($m, $values[$m], $v))
{
$fname = $column->getFilter()->getName();
Factory::getApplication()->enqueueMessage("Das Feld $fname ist fehlerhaft.", 'error');
$fname = (isset($v['name'])) ? $v['name'] : $m;
Factory::getApplication()->enqueueMessage("Das Feld $fname ist obligatorisch.", 'error');
$error = true;
}
}
@@ -201,19 +140,72 @@ 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->getSingleBaseName();
$name = $this->getNameOfElement();
$app->enqueueMessage("Removal of $name with id $id.");
$factory = $this->getFactory();
$element = $factory->loadById($id);
$className = 'Clubs' . $this->getModelName();
$functionName = 'load' . $this->getModelName();
$element = call_user_func(array($className, $functionName), $id);
$element->delete();
$view = $this->getSingleViewName();
$view = $this->getNameOfView();
$this->setRedirect(Route::_("index.php?option=com_clubs&view={$view}s", false));
}

View File

@@ -0,0 +1,207 @@
<?php
// No direct access.
use Joomla\CMS\Factory;
defined('_JEXEC') or die;
abstract class AbstractClubsModel
{
protected $id;
/**
* @return int
*/
public function getId()
{
return $this->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){}
}

View File

@@ -0,0 +1,177 @@
<?php
// No direct access.
use Joomla\CMS\Factory;
defined('_JEXEC') or die;
abstract class AbstractClubsModelFactory
{
protected $tableName;
protected $className;
public function __construct($tableName, $className)
{
$this->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;
}
}

View File

@@ -1,67 +0,0 @@
<?php
// No direct access.
use Joomla\CMS\MVC\View\HtmlView;
use Joomla\CMS\Router\Route;
defined('_JEXEC') or die;
abstract class AbstractClubsViewList extends HtmlView
{
/**
* @var AbstractCommonClubsModel
*/
protected $objects;
protected $delUrl;
protected $addUrl;
protected $changeUrl;
private $prepared = FALSE;
public function prepareDisplay()
{
$this->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();
}
}

View File

@@ -11,12 +11,8 @@ abstract class AbstractClubsViewSingle extends HtmlView
{
protected $address;
/**
* @var AbstractCommonClubsModel
*/
protected $object;
protected $isNew;
protected $id;
private $prepared = FALSE;
@@ -27,32 +23,34 @@ abstract class AbstractClubsViewSingle extends HtmlView
$input = Factory::getApplication()->input;
$id = $input->get->get('id');
$controllerName = $this->getControllerName();
$modelClass = 'Clubs' . $this->getModelName();
$controller = $this->getControllerName();
if($id === 'new')
{
$this->address = Route::_("index.php?option=com_clubs&task={$controllerName}.new");
$this->object = $this->createNewObject();
$this->address = Route::_("index.php?option=com_clubs&task={$controller}.new");
$this->object = call_user_func(array($modelClass, 'create' . $this->getModelName()));
$this->isNew = true;
}
else if(is_numeric($id))
{
$id = (int) $id;
$this->address = Route::_("index.php?option=com_clubs&task={$controllerName}.change&id=$id");
$this->object = $this->loadObject($id);
$this->address = Route::_("index.php?option=com_clubs&task={$controller}.change");
$this->object = call_user_func(array($modelClass, 'load' . $this->getModelName()), (int) $id);
$this->isNew = false;
}
else
throw new Exception('Need a valid object id.');
$jsonData = $input->get->get('data', null, 'json');
if($jsonData !== null)
throw new Exception('Need an object id.');
if($input->get->get('data', null, 'json') != null)
{
$this->object->unpack($jsonData);
// Restore previous data
$dataurl = $input->get->get('data', null, 'json');
$data = json_decode($dataurl, true);
$controller = $this->getElementController();
$controller->applyData($this->object, $data);
}
$this->id = $id;
}
public function display($tpl = null)
@@ -63,23 +61,26 @@ abstract class AbstractClubsViewSingle extends HtmlView
parent::display($tpl);
}
protected abstract function getControllerName();
protected abstract function getViewName();
/**
* @return AbstractCommonClubsModelFactory
*/
protected abstract function getFactory();
protected function createNewObject()
protected function getControllerName()
{
$factory = $this->getFactory();
return $factory->createNew();
return $this->getViewName();
}
protected function loadObject($id)
protected function getModelName()
{
$factory = $this->getFactory();
return $factory->loadById($id);
$name = $this->getViewName();
return $this->capitalize($name);
}
private function capitalize($s)
{
$first = substr($s, 0, 1);
$rest = substr($s, 1);
return strtoupper($first) . $rest;
}
protected abstract function getElementController();
}

View File

@@ -9,10 +9,6 @@ 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;

View File

@@ -1,55 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
abstract class AbstractCommonClubsControllerMapping
{
protected $required;
protected $name;
public function __construct($name, $required = true)
{
$this->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;
}
}

View File

@@ -1,385 +0,0 @@
<?php
use Joomla\CMS\Factory;
// No direct access.
defined('_JEXEC') or die;
abstract class AbstractCommonClubsModel
{
// TODO Add data validator
// TODO Make setting of values attribute fail in case of problems
// FIXME Add Joins in select statements
private $id;
private $new;
public function getId()
{
return $this->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;
}
}

View File

@@ -1,78 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
abstract class AbstractCommonClubsModelColumn
{
protected $alias;
protected $column;
/**
* @var AbstractCommonClubsControllerMapping
*/
protected $filter;
public function getAlias()
{
return $this->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;
}
}

View File

@@ -1,208 +0,0 @@
<?php
// No direct access.
use Joomla\CMS\Factory;
defined('_JEXEC') or die;
class ElementNotFoundException extends Exception
{}
abstract class AbstractCommonClubsModelFactory
{
// TODO Attribures as objects allowing to use polymophism in filtering/parsing/checking/sql building
/*
* This method should return an array to configure the trivially accessible values.
* The key must be a unique key describing the information and will be reused in the getValues() method.
* The value of each key should be an associative array describing the object field.
* Example of an array returned by this method is
* array(
* 'name'=>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;
}
}

View File

@@ -1,84 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
abstract class AbstractCommonClubsModelJoin
{
protected $tablename;
protected $alias;
protected $condition;
/**
* @var AbstractCommonClubsModelColumn[]
*/
protected $columns;
public function __construct($alias, $condition, $colums, $tablename = null)
{
/// XXX Some checks need to be performed
$this->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]);
}
}
}

View File

@@ -1,14 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsControllerMappingCmd extends AbstractCommonClubsControllerMapping
{
public function getFilteredValue($input, $name)
{
return $input->getCmd($name);
}
}

View File

@@ -1,14 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsControllerMappingFloat extends AbstractCommonClubsControllerMapping
{
public function getFilteredValue($input, $name)
{
return $input->getFloat($name);
}
}

View File

@@ -1,14 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsControllerMappingInt extends AbstractCommonClubsControllerMapping
{
public function getFilteredValue($input, $name)
{
return $input->getInt($name);
}
}

View File

@@ -1,44 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsControllerMappingRef extends AbstractCommonClubsControllerMapping
{
/**
* @var AbstractCommonClubsModelFactory
*/
protected $factory;
/**
* @param string $name
* @param AbstractCommonClubsModelFactory $factory
* @param boolean $required
*/
public function __construct($name, $factory, $required = true)
{
parent::__construct($name, $required);
$this->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;
}
}

View File

@@ -1,14 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsControllerMappingString extends AbstractCommonClubsControllerMapping
{
public function getFilteredValue($input, $name)
{
return $input->getString($name);
}
}

View File

@@ -1,160 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelClub extends AbstractCommonClubsModel
{
protected function getFactory()
{
return new CommonClubsModelFactoryClub();
}
public function getName()
{
return $this->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)
{
if(empty($ids))
$ids = array();
$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();
}
}

View File

@@ -1,22 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelColumnFloat extends AbstractCommonClubsModelColumn
{
public function isSimpleType()
{
return true;
}
public function getQuotedValue($q, $value)
{
if(is_null($value))
return 'NULL';
else
return (float) $value;
}
}

View File

@@ -1,22 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelColumnInt extends AbstractCommonClubsModelColumn
{
public function isSimpleType()
{
return true;
}
public function getQuotedValue($q, $value)
{
if(is_null($value))
return 'NULL';
else
return (int) $value;
}
}

View File

@@ -1,105 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class WrongRefTypeException extends Exception
{}
class AssociatedObjectUnsavedException extends Exception
{}
class CommonClubsModelColumnRef extends AbstractCommonClubsModelColumn
{
protected $className;
public function __construct($alias, $className, $column, $filter)
{
parent::__construct($alias, $filter, $column);
if(empty($className))
throw new Exception('Classname must be non-empty.');
$this->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];
}
}

View File

@@ -1,22 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelColumnString extends AbstractCommonClubsModelColumn
{
public function isSimpleType()
{
return true;
}
public function getQuotedValue($q, $value)
{
if(is_null($value))
return 'NULL';
else
return $q->q($value);
}
}

View File

@@ -1,34 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelFactoryClub extends AbstractCommonClubsModelFactory
{
public function fetchAttributes()
{
return array(
new CommonClubsModelColumnString('name', new CommonClubsControllerMappingString('Clubname')),
new CommonClubsModelColumnString('address', new CommonClubsControllerMappingString('Adresse')),
new CommonClubsModelColumnString('city', new CommonClubsControllerMappingString('Stadt')),
new CommonClubsModelColumnString('homepage', new CommonClubsControllerMappingString('Homepaage', false)),
new CommonClubsModelColumnString('mail', new CommonClubsControllerMappingString('E-Mail')),
new CommonClubsModelColumnString('iban', new CommonClubsControllerMappingCmd('IBAN')),
new CommonClubsModelColumnString('bic', new CommonClubsControllerMappingCmd('BIC')),
new CommonClubsModelColumnInt('charitable', new CommonClubsControllerMappingInt('Gemeinnützigkeit')),
new CommonClubsModelColumnRef('president', 'CommonClubsModelUser', 'president', new CommonClubsControllerMappingRef('Vorsitzender', new CommonClubsModelFactoryUser()))
);
}
public function getTableName()
{
return '#__club_clubs';
}
public function getClassName()
{
return 'CommonClubsModelClub';
}
}

View File

@@ -1,24 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelFactoryOffer extends AbstractCommonClubsModelFactory
{
protected function fetchAttributes()
{
return array(
new CommonClubsModelColumnString('name', new CommonClubsControllerMappingString('Bezeichnung'))
);
}
public function getTableName()
{
return '#__club_offers';
}
public function getClassName()
{
return 'CommonClubsModelOffer';
}
}

View File

@@ -1,25 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelFactoryOfferassoc extends AbstractCommonClubsModelFactory
{
protected function fetchAttributes()
{
return array(
new CommonClubsModelColumnRef('club', 'CommonClubsModelClub', 'clubid', new CommonClubsControllerMappingRef('Club', new CommonClubsModelFactoryClub())),
new CommonClubsModelColumnRef('offer', 'CommonClubsModelOffer', 'offerid', new CommonClubsControllerMappingRef('Angebot', new CommonClubsModelFactoryOffer()))
);
}
public function getTableName()
{
return '#__club_offer_assocs';
}
public function getClassName()
{
return 'CommonClubsModelOfferassoc';
}
}

View File

@@ -1,28 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelFactoryPlace extends AbstractCommonClubsModelFactory
{
public function fetchAttributes()
{
return array(
new CommonClubsModelColumnString('name', new CommonClubsControllerMappingString('Bezeichnung')),
new CommonClubsModelColumnRef('club', 'CommonClubsModelClub', 'clubid', new CommonClubsControllerMappingRef('Club', new CommonClubsModelFactoryClub())),
new CommonClubsModelColumnInt('area', new CommonClubsControllerMappingInt('Fläche', false))
);
}
public function getTableName()
{
return '#__club_places';
}
public function getClassName()
{
return 'CommonClubsModelPlace';
}
}

View File

@@ -1,25 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelFactoryPosition extends AbstractCommonClubsModelFactory
{
protected function fetchAttributes()
{
return array(
new CommonClubsModelColumnString('name', new CommonClubsControllerMappingString('Bezeichnung'))
);
}
public function getTableName()
{
return '#__club_positions';
}
public function getClassName()
{
return 'CommonClubsModelPosition';
}
}

View File

@@ -1,33 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelFactoryUser extends AbstractCommonClubsModelFactory
{
public function fetchAttributes()
{
return array(
new CommonClubsModelColumnString('user', new CommonClubsControllerMappingCmd('Benutzername')),
new CommonClubsModelColumnString('name', new CommonClubsControllerMappingString('Bürgerlicher Name')),
new CommonClubsModelColumnString('password', new CommonClubsControllerMappingString('Passwort', false)),
new CommonClubsModelColumnString('address', new CommonClubsControllerMappingString('Adresse')),
new CommonClubsModelColumnString('city', new CommonClubsControllerMappingString('Stadt')),
new CommonClubsModelColumnString('mail', new CommonClubsControllerMappingString('E-Mail')),
new CommonClubsModelColumnString('phone', new CommonClubsControllerMappingString('Telefonnummer', false)),
new CommonClubsModelColumnString('mobile', new CommonClubsControllerMappingString('Handynummer', false))
);
}
public function getTableName()
{
return '#__club_users';
}
public function getClassName()
{
return 'CommonClubsModelUser';
}
}

View File

@@ -1,33 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelFactoryUserassoc extends AbstractCommonClubsModelFactory
{
protected function fetchAttributes()
{
return array(
new CommonClubsModelColumnRef('user', 'CommonClubsModelUser', 'userid', new CommonClubsControllerMappingRef('User', new CommonClubsModelFactoryUser())),
new CommonClubsModelColumnRef('club', 'CommonClubsModelClub', 'clubid', new CommonClubsControllerMappingRef('Club', new CommonClubsModelFactoryClub())),
new CommonClubsModelColumnRef('position', 'CommonClubsModelPosition', 'positionid', new CommonClubsControllerMappingRef('Position', new CommonClubsModelFactoryPosition())),
new CommonClubsModelColumnInt('admin', new CommonClubsControllerMappingInt('Admin')),
new CommonClubsModelColumnString('address', new CommonClubsControllerMappingString('Adresse', false)),
new CommonClubsModelColumnString('mail', new CommonClubsControllerMappingString('E-Mail', false)),
new CommonClubsModelColumnString('phone', new CommonClubsControllerMappingString('Telefonnummer', false)),
new CommonClubsModelColumnString('state', new CommonClubsControllerMappingString('Status'))
// -> `state` enum('regular', 'vacant', 'temporary') NOT NULL DEFAULT 'vacant',
);
}
public function getTableName()
{
return '#__club_user_assocs';
}
public function getClassName()
{
return 'CommonClubsModelUserassoc';
}
}

View File

@@ -1,12 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelJoinInner extends AbstractCommonClubsModelJoin
{
protected function addJoin($q, $str)
{
$q->innerJoin($str);
}
}

View File

@@ -1,12 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelJoinLeft extends AbstractCommonClubsModelJoin
{
protected function addJoin($q, $str)
{
$q->leftJoin($str);
}
}

View File

@@ -1,12 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelJoinOuter extends AbstractCommonClubsModelJoin
{
protected function addJoin($q, $str)
{
$q->outerJoin($str);
}
}

View File

@@ -1,12 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelJoinRight extends AbstractCommonClubsModelJoin
{
protected function addJoin($q, $str)
{
$q->rightJoin($str);
}
}

View File

@@ -1,37 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelOffer extends AbstractCommonClubsModel
{
protected function getFactory()
{
return new CommonClubsModelFactoryOffer();
}
public function getName()
{
return $this->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();
}
}

View File

@@ -1,49 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelOfferassoc extends AbstractCommonClubsModel
{
protected function getFactory()
{
return new CommonClubsModelFactoryOfferassoc();
}
/**
*
* @return CommonClubsModelClub
*/
public function getClub()
{
return $this->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);
}
}

View File

@@ -1,43 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelPlace extends AbstractCommonClubsModel
{
protected function getFactory()
{
return new CommonClubsModelFactoryPlace();
}
public function getName()
{
return $this->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);
}
}

View File

@@ -1,32 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelPosition extends AbstractCommonClubsModel
{
protected function getFactory()
{
return new CommonClubsModelFactoryPosition();
}
public function getName()
{
return $this->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();
}
}

View File

@@ -1,221 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelUser extends AbstractCommonClubsModel
{
protected function getFactory()
{
return new CommonClubsModelFactoryUser();
}
public function getName()
{
return $this->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 getPresidentClubs()
{
return $this->fetchAssociatedElements(new CommonClubsModelFactoryClub(), 'president');
}
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;
}
protected function filterDatabaseRawData($values)
{
if(strlen($values['phone']) == 0)
$values['phone'] = null;
if(strlen($values['mobile']) == 0)
$values['mobile'] = null;
return $values;
}
}

View File

@@ -1,119 +0,0 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class CommonClubsModelUserassoc extends AbstractCommonClubsModel
{
protected function getFactory()
{
return new CommonClubsModelFactoryUserassoc();
}
/**
*
* @return CommonClubsModelUser
*/
public function getUser()
{
return $this->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);
}
}

View File

@@ -6,13 +6,28 @@ defined('_JEXEC') or die;
class ClubsControllerClub extends AbstractClubsController
{
protected function getSingleBaseName()
protected function getNameOfElement()
{
return 'club';
}
protected function filterRaw(&$values)
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)
{
if(is_null($values['charitable']))
$values['charitable'] = false;
@@ -26,21 +41,4 @@ 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']);
}
}

View File

@@ -1,91 +0,0 @@
<?php
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Response\JsonResponse;
use Joomla\CMS\Factory;
// No direct access.
defined('_JEXEC') or die;
class ClubsControllerClubposition extends BaseController
{
public function save()
{
$app = Factory::getApplication();
$input = $app->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);
}
}

View File

@@ -6,15 +6,18 @@ defined('_JEXEC') or die;
class ClubsControllerOffer extends AbstractClubsController
{
protected function getSingleBaseName()
protected function getNameOfElement()
{
return 'offer';
}
protected function getFactory()
protected function getDataMapping()
{
return new CommonClubsModelFactoryOffer();
return array(
'name' => array('required'=>true, 'name'=>'Bezeichnung', 'filter'=>'string')
);
}
}

View File

@@ -6,15 +6,16 @@ defined('_JEXEC') or die;
class ClubsControllerPosition extends AbstractClubsController
{
protected function getFactory()
{
return new CommonClubsModelFactoryPosition();
}
protected function getSingleBaseName()
protected function getNameOfElement()
{
return 'position';
}
protected function getDataMapping()
{
return array(
'name'=>array('required'=>true, 'filter'=>'string', 'name'=>'Bezeichung')
);
}
}

View File

@@ -8,99 +8,112 @@ defined('_JEXEC') or die;
class ClubsControllerUser extends AbstractClubsController
{
protected function getSingleBaseName()
private function checkUserName($username, $obj = null)
{
$id = -1;
if(!is_null($obj))
$id = $obj->getId();
return ClubsUser::isUserNameFree($username, $id);
}
protected function getNameOfElement()
{
return 'user';
}
protected function rawDataIsValid($values)
{
if(! parent::rawDataIsValid($values))
return false;
if($this->passwordIsSet($values))
{
if( ! $this->passwordIsValid($values))
return false;
}
return true;
}
private function passwordIsSet($values)
{
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::objectValid()
* @param CommonClubsModelUser $obj
*/
protected function objectValid($obj)
{
if(! $obj->isPasswordSet())
{
Factory::getApplication()->enqueueMessage('Kein Passwort wurde vergeben.', 'error');
return false;
}
return true;
}
protected function filterRaw(&$values)
{
unset($values['password']);
}
protected function additionalData()
protected function getDataMapping()
{
return array(
'pwd' => new CommonClubsControllerMappingString('Passwort'),
'pwdConfirm' => new CommonClubsControllerMappingString('Passwortwiederholung')
'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))
return false;
// TODO Auto-generated method stub
if(isset($values['pwd']) && strlen($values['pwd']) > 0)
{
$pwd = $values['pwd'];
$pwdConfirm = $values['pwdConfirm'];
if(trim($pwd) != trim($pwdConfirm))
{
Factory::getApplication()->enqueueMessage('Die Passwörter stimmen nicht überein.', 'error');
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)
{
parent::filterPrePacking($values);
unset($values['pwd']);
unset($values['pwdConfirm']);
}
/**
* {@inheritDoc}
* @see AbstractClubsController::applyData()
*/
public function applyData($obj, $values)
{
// TODO Auto-generated method stub
$mapping = $this->getDataMapping();
if(strlen($values['pwd']) == 0)
{
unset($values['pwd']);
unset($mapping['pwd']);
}
$this->applyDataToObject($obj, $values, $mapping);
}
}

252
src/admin/mymodels/club.php Normal file
View File

@@ -0,0 +1,252 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class ClubsClub extends AbstractClubsModel
{
protected $id;
protected $name;
protected $address;
protected $city;
protected $homepage;
protected $mail;
protected $iban;
protected $bic;
protected $charitable;
protected $president;
/**
* @return string
*/
public function getAddress()
{
return $this->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;
}
}

View File

@@ -0,0 +1,78 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class ClubsOffer extends AbstractClubsModel
{
protected $name;
/**
* @return string
*/
public function getName()
{
return $this->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;
}
}

View File

@@ -0,0 +1,78 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class ClubsOfferAssociation extends AbstractClubsModel
{
protected $offerid;
protected $clubid;
public function getOffer()
{
return ClubsOffer::loadOffer($this->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;
}
}

View File

@@ -0,0 +1,32 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class ClubsOfferAssociationFactory extends AbstractClubsModelFactory
{
public function __construct()
{
parent::__construct('#__club_offer_assocs', 'ClubsOfferAssociation');
}
protected function getJoins($dbo)
{
$ret = array();
$ret[] = array(
'name' => '#__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;
}
}

View File

@@ -0,0 +1,113 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class ClubsPlace extends AbstractClubsModel
{
protected $name;
protected $address;
protected $area;
protected $clubid;
/**
* @return string
*/
public function getName()
{
return $this->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;
}
}

View File

@@ -0,0 +1,66 @@
<?php
// No direct access.
defined('_JEXEC') or die;
class ClubsPosition extends AbstractClubsModel
{
protected $name;
/**
* @return string
*/
public function getName()
{
return $this->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;
}
}

298
src/admin/mymodels/user.php Normal file
View File

@@ -0,0 +1,298 @@
<?php
use Joomla\CMS\Factory;
// No direct access.
defined('_JEXEC') or die;
class UserInvalidException extends Exception
{}
class PasswordInvalidException extends Exception
{}
class ClubsUser extends AbstractClubsModel
{
protected $user;
protected $password;
protected $name;
protected $address;
protected $city;
protected $mail;
protected $phone;
protected $mobile;
/**
* @return string
*/
public function getMail()
{
return $this->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;
}
}

View File

@@ -1,51 +0,0 @@
#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;
}

View File

@@ -1,102 +0,0 @@
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&ouml;glicherweise sind nicht alle Daten gesichert.";});
$('.form-exit').click(function(){
$(window).off('beforeunload');
});
});

View File

@@ -1,68 +0,0 @@
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`)
);

View File

@@ -1,9 +0,0 @@
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`;

View File

@@ -0,0 +1,18 @@
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');

View File

@@ -7,17 +7,16 @@ defined('_JEXEC') or die;
?>
<form method="post" action="<?php echo $this->address; ?>" id='form-club'>
<form method="post" action="<?php echo $this->address; ?>">
<input type='hidden' name='id' value='<?php echo $this->object->getId(); ?>'>
<h2>Stammdaten</h2>
<table>
<tr>
<td>Clubname</td>
<td>Bezeichnung</td>
<td><input type='text' name='name' value='<?php echo htmlentities($this->object->getName()); ?>'></td>
</tr>
<tr>
<td>Vollst&auml;ndige postalische Adresse</td>
<td>Adresse</td>
<td>
<textarea name='address' rows='5'><?php echo htmlentities($this->object->getAddress()); ?></textarea>
</td>
@@ -67,6 +66,15 @@ defined('_JEXEC') or die;
<?php if(! $this->isNew): ?>
<tr>
<td>Angebote</td>
<td>
<?php foreach($this->offers as $o): ?>
<input type='checkbox' name='offers' value='<?php echo $o['offer']->getId(); ?>' <?php if($o['mark']) echo 'checked="checked"';?>>
<?php echo htmlentities($o['offer']->getName()); ?><br />
<?php endforeach; ?>
</td>
</tr>
<tr>
<td>ID</td>
<td><?php echo $this->object->getId(); ?></td>
@@ -74,64 +82,6 @@ defined('_JEXEC') or die;
<?php endif; ?>
</table>
<?php if(! $this->isNew): ?>
<h2>Angebote</h2>
<?php foreach($this->object->getOffers() as $oconf): ?>
<input type='checkbox' name='offers[]' value='<?php echo $oconf['offer']->getId(); ?>' <?php if($oconf['valid']) echo 'checked="checked"';?>>
<?php echo htmlentities($oconf['offer']->getName()); ?><br />
<?php endforeach; ?>
<h2>Posten</h2>
<?php if(sizeof($this->object->getUsers()) == 0 ): ?>
<p>Dem Verein ist bisher kein Posten zugewiesen.</p>
<?php else: ?>
<table width='100%' class='table table-stiped, table-hover' id='userassocs'>
<tr>
<th width='20%'>Rolle</th>
<th width='25%'>Name</th>
<th width='10%'>Stadt</th>
<th width='5%' style='text-align: center;'>Admin?</th>
<th></th>
<th width='5%'>ID</th>
</tr>
<?php foreach($this->object->getUsers() as $ua): ?>
<?php
$user = $ua->getUser();
if($user == null)
{
$username = '<i>Derzeit vakant</i>';
$usercity = '';
}
else
{
$username = htmlentities($user->getName());
$usercity = htmlentities($user->getCity());
}
?>
<tr id='userassoc-<?php echo $ua->getId(); ?>'>
<td><?php echo htmlentities($ua->getPosition()->getName()); ?></td>
<td><?php echo $username; ?></td>
<td><?php echo $usercity; ?></td>
<td style='text-align: center;'><?php if($ua->isAdmin()) echo "<span class='icon-checkmark'></span>"; ?></td>
<td>
<a href='<?php echo Route::_("index.php?option=com_clubs&view=clubposition&layout=edit&club={$this->object->getId()}&id={$ua->getId()}"); ?>' class='edit-position'><span class='icon-edit'></span></a>
<a href='<?php echo Route::_("index.php?option=com_clubs&task=clubposition.delete&format=json&id={$ua->getId()}"); ?>' class='del-position'><span class='icon-delete'></span></a>
</td>
<td><?php echo $ua->getId(); ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
<p><a href='<?php echo Route::_("index.php?option=com_clubs&view=clubposition&layout=edit&club={$this->object->getId()}&id=new"); ?>' id='new-position'><span class='icon-new'></span> Neuen Posten einf&uuml;gen</a></p>
<?php endif; ?>
<input type='submit' value='Speichern' class='form-exit'> <br /><a href='<?php echo Route::_('index.php?option=com_clubs&view=clubs'); ?>' class='form-exit'>Zur&uuml;ck zur &Uuml;bersicht</a>
<input type='submit' value='Speichern'> <br /><a href='<?php echo Route::_('index.php?option=com_clubs&view=clubs'); ?>'>Zur&uuml;ck zur &Uuml;bersicht</a>
</form>
<div id='dialog-club' class='dialog-hidden'>
<div class='background'></div>
<div class='dialog'>Ein Test</div>
<div id='hidden-id'><?php echo $this->object->getId(); ?></div>
</div>

View File

@@ -1,6 +1,5 @@
<?php
use Joomla\CMS\Factory;
use Joomla\CMS\Toolbar\ToolbarHelper;
// No direct access.
@@ -12,32 +11,34 @@ class ClubsViewClub extends AbstractClubsViewSingle
{
function display($tpl = null)
{
ToolbarHelper::title('Club-Management - Verein', 'cube');
ToolbarHelper::title('Club-Management - Verein');
$this->prepareDisplay();
$userFactory = new CommonClubsModelFactoryUser();
$this->users = $userFactory->loadElements();
$this->users = ClubsUser::loadUsers();
JHtmlJquery::framework();
Factory::getDocument()->addScript('components/com_clubs/res/club/club.js');
Factory::getDocument()->addStyleSheet('components/com_clubs/res/admin-club.css');
// $this->
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);
}
parent::display($tpl);
}
protected function getControllerName()
protected function getViewName()
{
return 'club';
}
protected function getFactory()
protected function getElementController()
{
return new CommonClubsModelFactoryClub();
return new ClubsControllerClub();
}
}

View File

@@ -1,90 +0,0 @@
<?php
use Joomla\CMS\Router\Route;
// No direct access.
defined('_JEXEC') or die;
?>
<form id='clubposition-form' method="post" action="<?php echo Route::_('index.php?option=com_clubs&task=clubposition.save&format=json') ?>">
<input type='hidden' name='id' value='<?php echo $this->id; ?>'>
<input type='hidden' name='clubid' value='<?php echo $this->clubid; ?>'>
<h1>Posten bearbeiten</h1>
<table>
<tr>
<td>Funktion: </td>
<td>
<select name='positionid'>
<?php foreach($this->positions as $p): ?>
<?php
if($this->assoc->getPosition() !== null)
$selected = $this->assoc->getPosition()->getId() == $p->getId();
else
$selected = false;
?>
<option value='<?php echo $p->getId(); ?>' <?php if($selected) echo 'selected'; ?>>
<?php echo $p->getName(); ?>
</option>
<?php endforeach; ?>
</select>
</td>
</tr>
<tr>
<td>Status</td>
<td>
<select name='state' id='clubposition-state'>
<option value='regular' <?php echo $this->assoc->getState() === 'regular' ? 'selected' : ''; ?>>regul&auml;r</option>
<option value='temporary' <?php echo $this->assoc->getState() === 'temporary' ? 'selected' : ''; ?>>kommisarisch</option>
<option value='vacant' <?php echo $this->assoc->getState() === 'vacant' ? 'selected' : ''; ?>>vakant</option>
</select>
</td>
</tr>
<tr id='clubposition-user' <?php if($this->assoc->getState() === 'vacant') echo 'class="dialog-entry-hidden"'; ?>>
<td>Person: </td>
<td>
<select name='userid'>
<?php foreach($this->users as $u): ?>
<?php
$uid = $this->assoc->getUser() === null ? -1 : $this->assoc->getUser()->getId();
$selected = ($u->getId() == $uid);
?>
<option value='<?php echo $u->getId();?>' <?php echo $selected ? 'selected' : ''; ?>>
<?php echo $u->getName(); ?> (<?php echo $u->getCity(); ?>)
</option>
<?php endforeach; ?>
</select>
</td>
</tr>
<tr>
<td>Admin: </td>
<td>
<input type='checkbox' name='admin' value='1' <?php echo $this->assoc->isAdmin() ? 'checked' : ''; ?>>
</td>
</tr>
<tr>
<td>Postalische Adresse (optional): </td>
<td>
<textarea name='address' rows='4'><?php echo $this->assoc->getAddress(); ?></textarea>
</td>
</tr>
<tr>
<td>E-Mail (optional): </td>
<td>
<input type='text' name='mail' value='<?php echo $this->assoc->getMail(); ?>'>
</td>
</tr>
<tr>
<td>Telefon-Nr. (optional): </td>
<td>
<input type='text' name='phone' value='<?php echo $this->assoc->getPhone(); ?>'>
</td>
</tr>
</table>
</form>
<a href='#' id='clubposition-save'>Speichern</a>
<a href='#' id='clubposition-abort'>Abbrechen</a>

View File

@@ -1,17 +0,0 @@
<?php
// No direct access.
use Joomla\CMS\Router\Route;
defined('_JEXEC') or die;
?>
<td><?php echo htmlentities($this->assoc->getPosition()->getName()); ?></td>
<td><?php echo $this->username; ?></td>
<td><?php echo $this->usercity; ?></td>
<td style='text-align: center;'><?php if($this->assoc->isAdmin()) echo "<span class='icon-checkmark'></span>"; ?></td>
<td>
<a href='<?php echo Route::_("index.php?option=com_clubs&view=clubposition&layout=edit&club={$this->clubid}&id={$this->assoc->getId()}"); ?>' class='edit-position'><span class='icon-edit'></span></a>
<a href='<?php echo Route::_("index.php?option=com_clubs&task=clubposition.delete&format=json&id={$this->assoc->getId()}"); ?>' class='del-position'><span class='icon-delete'></span></a>
</td>
<td><?php echo $this->assoc->getId(); ?></td>

View File

@@ -1,62 +0,0 @@
<?php
use Joomla\CMS\MVC\View\HtmlView;
use Joomla\CMS\Factory;
// No direct access.
defined('_JEXEC') or die;
JLoader::register("ClubsControllerPosition", JPATH_ROOT . "/administrator/components/com_clubs/controllers/position.php");
class ClubsViewClubPosition extends HtmlView
{
function display($tpl = null)
{
$input = Factory::getApplication()->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 = '<i>Derzeit vakant.</i>';
$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();
}
}

View File

@@ -1,6 +1,7 @@
<?php
// No direct access.
use Joomla\CMS\Router\Route;
defined('_JEXEC') or die;
@@ -10,25 +11,26 @@ defined('_JEXEC') or die;
<thead>
<tr>
<th width='30%'>Bezeichnung</th>
<th width='20%'>Stadt</th>
<th width='25%'>Stadt</th>
<th width='20%'>Homepage</th>
<th width='20%'>E-Mail</th>
<th width='10%'></th>
<th width='3%'>id</th>
<th width='25%'>E-Mail</th>
<th width='5%'>L&ouml;schen?</th>
<th width='5%'>id</th>
</tr>
</thead>
<?php foreach($this->objects as $club): ?>
<?php foreach($this->clubs as $club): ?>
<?php $link = Route::_('index.php?option=com_clubs&view=club&id=' . $club->getId()); ?>
<?php $url = htmlentities($club->getHomepage()); ?>
<?php $mail = htmlentities($club->getMail()); ?>
<tr>
<td><a href='<?php echo str_replace('__ID__', $club->getId(), $this->changeUrl); ?>'><?php echo htmlentities($club->getName()); ?></a></td>
<td><a href='<?php echo $link; ?>'><?php echo htmlentities($club->getName()); ?></a></td>
<td><?php echo htmlentities($club->getCity()); ?></td>
<td><a href='<?php echo $url; ?>' target='_blank'><?php echo $url; ?></a></td>
<td><a href='mailto:<?php echo $mail; ?>'><?php echo $mail; ?></a></td>
<td><a href='<?php echo str_replace('__ID__', $club->getId(), $this->delUrl); ?>'><span class='icon-delete'></span>L&ouml;schen</a></td>
<td><!--<a href='<?php echo Route::_('index.php?option=com_clubs&task=club.delete&id=' . $club->getId()); ?>'>Del</a> --></td>
<td><?php echo htmlentities($club->getId()); ?></td>
</tr>
<?php endforeach; ?>
</table>
<div><a href='<?php echo $this->addUrl; ?>'><span class='icon-new'></span>Neuen Verein anlegen</a></div>
<div><a href='<?php echo Route::_('index.php?option=com_clubs&view=club&id=new'); ?>'>Neuen Verein anlegen</a></div>

Some files were not shown because too many files have changed in this diff Show More