Kalender, Terminliste, Terminformular und Terminzettel laufen ueber db_abfrage() mit Platzhaltern; das Anlegen einer mehrtaegigen Terminreihe liegt in einer Transaktion. Die Logik steckt jetzt in incs/termin.php, sites/termin*.php rufen sie nur noch auf. Dabei behoben: - SQL-Injektion ueber die Suchbegriffe der Terminliste, ueber die Mehrfachauswahl (Ankreuzfelder del<N>/erl<N> gingen roh in DELETE bzw. UPDATE), ueber die Wiedervorlage-Tage (INTERVAL $folgedays DAY) und ueber ?action=terminshow&id=... in maketerminarray(), maketerminadresse(), maketelnrn() und makegooglestring() - gespeichertes XSS: Beschreibung, Notiz, Termintyp, Ort, Kundenname und Mitarbeiterfarbe im Kalender, in der Terminliste und im Formular - "or $err=error(...)" stand innerhalb des Abfrage-Strings, dadurch wurden die Nebenzeilen einer Terminreihe beim Loeschen nie entfernt - die Abfrage zum Folgetermin las eine Spalte typ_id, die es in termin nicht gibt; Typ und Wiedervorlage fehlten deshalb beim Bearbeiten - ein Folgetermin wurde mit termtime='' und termdauer='' angelegt, ein Termin ohne Folgetermin mit followed_by='' - im strikten Modus Fehler - ein Termin ohne Datum landete auf dem 01.01.1970 und gab dabei "NICHTTERMINIERT!!" mitten in die Seite aus - die Ueberschneidungspruefung verglich ab dem zweiten Tag gegen das Ende des ersten Tages - eine unbekannte Registerkarte der Terminliste ergab ein leeres WHERE und damit einen SQL-Fehler; jetzt gilt die Standardansicht - terminshow.php pruefte den Typ mit = statt == - der Kalender haengt nicht mehr an der Locale de_DE (strftime) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
198 lines
9.1 KiB
Smarty
198 lines
9.1 KiB
Smarty
<p>
|
|
</p>
|
|
<p>
|
|
|
|
</p>
|
|
<p>
|
|
|
|
</p>
|
|
<p>
|
|
|
|
</p>
|
|
<p>
|
|
|
|
</p>
|
|
<br />
|
|
<div id='weekview'>
|
|
<a href='?action=termin&show=list'><span class='cal-list' title="Terminliste anzeigen" style='position: absolute; left: 50%;top: -11em;'></span></a><br />
|
|
<a href='?action=termin&page={$page-1}'><span class='left' title="8 Tage zurück" style='position: absolute; left: 0;top: -8em;'></span></a>
|
|
<a href='?action=termin&page=0'><span class='now' title="heute" style='position: absolute; left: 50%;top: -8em;'></span></a>
|
|
<a href='?action=termin&page={$page+1}'><span class='right' title="8 Tage vor" style='position: absolute; right: 0;top: -8em;'></span></a>
|
|
{foreach $weekdays as $weekday}
|
|
{$dayXpos = 10*$i+3.5}
|
|
{if $i == 1 && $page == 0}
|
|
<div class='nowweekdayhead' style='left: {$dayXpos}em;'>{$weekday.weekday}
|
|
<a href='?action=terminshow&id=1&date={$weekday.date}&type=singlepages'><span class='print' title="Alle Termine von heute drucken" style='position:absolute;top: 0em;right:0em;'></span></a>
|
|
</div>
|
|
{else if {$weekday.weekday|substr:0:7} != "Samstag" && {$weekday.weekday|substr:0:7} != "Sonntag" && {$weekday.feiertag} == ""}
|
|
<div class='weekdayhead' style='left: {$dayXpos}em;'>{$weekday.weekday}<br />
|
|
<a href='?action=terminshow&id=1&date={$weekday.date}&type=singlepages'><span class='print' title="Alle Termine an diesem Tag drucken" style='position:absolute;top: 0em;right:0em;'></span></a>
|
|
</div>
|
|
{*<a href='?action=terminadd&date={$i-1}' title='Neuer Termin'>*}<div class='weekdaybg' style='left: {$dayXpos+0.5}em;'></div>{*</a>*}
|
|
{else if {$weekday.feiertag} == ""}
|
|
<div class='weekdayhead' style='left: {$dayXpos}em;background-color: #FFDDDD;'>{$weekday.weekday}<br />
|
|
<a href='?action=terminshow&id=1&date={$weekday.date}&type=singlepages'><span class='print' title="Alle Termine an diesem Tag drucken" style='position:absolute;top: 0em;right:0em;'></span></a>
|
|
</div>
|
|
{*<a href='?action=terminadd&date={$i-1}' title='Neuer Termin'>*}<div class='weekdaybg' style='left: {$dayXpos+0.5}em;background-color: #FFFFFF;'></div>{*</a>*}
|
|
{else}
|
|
<div class='weekdayhead' style='left: {$dayXpos}em;background-color: #FFFF55;'>{$weekday.weekday} {$weekday.feiertag} <br />
|
|
<a href='?action=terminshow&id=1&date={$weekday.date}&type=singlepages'><span class='print' title="Alle Termine an diesem Tag drucken" style='position:absolute;top: 0em;right:0em;'></span></a>
|
|
</div>
|
|
{*<a href='?action=terminadd&date={$i-1}' title='Neuer Termin'>*}<div class='weekdaybg' style='left: {$dayXpos+0.5}em;background-color: #FFFFFF;'></div>{*</a>*}
|
|
{/if}
|
|
<div class='weekday_line' style='left: {$dayXpos}em;'></div>
|
|
{*FULL DAY TERMINE*}
|
|
{$shift = 0}
|
|
{$terminlength = 960}
|
|
{$terminstart = 390}
|
|
{$height = ($terminlength/15)}
|
|
{$start = 4 + ($terminstart - 420)/15}
|
|
{foreach $weekday.fulldaytermine as $key=>$termin}
|
|
<a href='?action=terminshow&id={$termin.main_id}'>
|
|
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
|
|
style='width: 1em;height: {$height}em;top: {$start}em;left: {$shift + $dayXpos}em;background-color: {$users.{$termin.user}.color|escape};'
|
|
title='{$termin.typ|escape}<br />{$termin.head|escape} - <b>{$termin.uservname|escape} {$termin.usernname|escape}</b><br /> Ganztags<br />{if {$termin.ort}}<b>In {$termin.ort|escape}{if $termin.ortsteil}-{$termin.ortsteil|escape}{/if}</b><br />{/if}{if {$termin.vname} || {$termin.nname} || {$termin.firma}}Bei {$termin.vname|escape} {$termin.nname|escape} {$termin.firma|escape}{/if}'>
|
|
<span class='rotate' style='padding-top: {$shift}em;'>{$termin.typ|substr:0:3|escape}.</span>
|
|
</div>
|
|
</a>
|
|
{$shift = $shift+1.1}
|
|
{/foreach}
|
|
{$lastFullDayterm = $shift}
|
|
|
|
{*TERMINE IN SLOTS SORTIEREN*}
|
|
{$termNr = 0}
|
|
{$currlayer = 0}
|
|
{$usedslots = 0}
|
|
{$layer = 0}
|
|
{foreach $weekday.termine as $key=>$termin}
|
|
{$terminlength = ({$termin.termdauer|date_format:"%H"}*60 + {$termin.termdauer|date_format:"%M"})}
|
|
{$terminstart = ({$termin.termtime|date_format:"%H"}*60 + {$termin.termtime|date_format:"%M"})}
|
|
{if {$terminstart} == 0}
|
|
{$terminlength = {$termin.termdauer}*60}
|
|
{$terminstart = 450+$lastarbtermend+15}
|
|
{$lastarbtermend = $terminstart-450 + $termin.termdauer * 60}
|
|
{/if}
|
|
{for $slot = 0 to 10}
|
|
{if $terminstart > $layer[$slot]}
|
|
{$weekday.termine[$termNr].slot = $slot}
|
|
{$layer[$slot] = $terminstart + $terminlength}
|
|
{if $slot > $usedslots}
|
|
{$usedslots = $usedslots+1}
|
|
{/if}
|
|
{break}
|
|
{/if}
|
|
{/for}
|
|
{$termNr = $termNr + 1}
|
|
{/foreach}
|
|
|
|
{*TERMINE ANZEIGEN*}
|
|
{$lastarbtermend = 0}
|
|
{$width = (10-$lastFullDayterm) / ($usedslots+1)}
|
|
{foreach $weekday.termine as $key=>$termin}
|
|
{$shift = $lastFullDayterm + $width*$termin.slot}
|
|
{$terminlength = ({$termin.termdauer|date_format:"%H"}*60 + {$termin.termdauer|date_format:"%M"})}
|
|
{$terminstart = ({$termin.termtime|date_format:"%H"}*60 + {$termin.termtime|date_format:"%M"})}
|
|
{if {$terminstart} == 0}
|
|
<a href='?action=projectadd&id={$termin.projectid}'>
|
|
{$terminlength = {$termin.termdauer}*60}
|
|
{$terminstart = 450+$lastarbtermend+15}
|
|
{$lastarbtermend = $terminstart-450 + $termin.termdauer * 60}
|
|
{$termin.typ = 'Arbeitsleistung'}
|
|
{else}
|
|
<a href='?action=terminshow&id={$termin.main_id}'>
|
|
{/if}
|
|
{$height = ($terminlength/15)}
|
|
{$start = 4 + ($terminstart - 420)/15}
|
|
|
|
|
|
{if {$termin.typ} != 'Arbeitsleistung'}
|
|
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
|
|
style='width: {$width-0.3}em;height: {$height}em;top: {$start}em;left: {$dayXpos+ 0.1 + $shift}em;background-color: {$users.{$termin.user}.color|escape}'
|
|
title='
|
|
{$termin.typ|escape}<br />{$termin.head|escape} - <b>{$termin.uservname|escape} {$termin.usernname|escape}</b><br />
|
|
Um {$termin.termtime|date_format:'%k:%M'}Uhr<br />Dauer {if {$termin.termdauer|date_format:'%k'} > 0} {$termin.termdauer|date_format:'%k'}h{/if}
|
|
{if {$termin.termdauer|date_format:'%M'} > 0}{$termin.termdauer|date_format:'%M'}min{/if}<br />
|
|
<b>In {$termin.ort|escape}{if $termin.ortsteil}-{$termin.ortsteil|escape}{/if}</b><br />
|
|
Bei {$termin.vname|escape} {$termin.nname|escape} {$termin.firma|escape}'>
|
|
{else}
|
|
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
|
|
style='width: {$width-0.3}em;height: {$height}em;top: {$start}em;left: {$dayXpos+ 0.1 + $shift}em;background-color: {if $termin.done}#CFC{else}{$users.{$termin.user}.color|escape}{/if};'
|
|
title='{$termin.typ|escape} - {$termin.firma|escape} {$termin.vname|escape} {$termin.nname|escape}<br /> <b>{$termin.projectname|escape}</b> <br /> {$termin.head|escape}<br /> <b>Dauer: </b>{$termin.termdauer|string_format:"%.1f"}h'>
|
|
{/if}
|
|
<span class='rotate'>{$termin.typ|substr:0:3|escape}.</span>
|
|
</div>
|
|
</a>
|
|
{/foreach}
|
|
|
|
|
|
{*ANWESENDE MITARBEITER ANZEIGEN*}
|
|
{$ma_nr = 0}
|
|
{foreach $weekday.ma_check as $key=>$mitarb}
|
|
{$ma_nr = $ma_nr + 1.2}
|
|
{$height = 1.2}
|
|
{$width = 9}
|
|
{$start = $ma_nr + 0.5}
|
|
<div class='mabox'
|
|
style='width: {$width}em;height: {$height}em;top: {$start}em;left: {$dayXpos+ 0.5}em;background-color: {$mitarb.color|escape};'
|
|
title='{$mitarb.vname|escape} {$mitarb.nname|escape} - Anwesend {if {$mitarb.complete} == 0} aber noch nicht ausgestempelt{/if}<br />'>
|
|
{if {$mitarb.complete} == 0}<font color='#aa0000'>{else}<font color='#000000'>{/if}{$mitarb.vname|escape} {$mitarb.nname|substr:0:1|escape}.</font>
|
|
</div>
|
|
</a>
|
|
{/foreach}
|
|
{$i=$i+1}
|
|
{/foreach}
|
|
|
|
|
|
|
|
|
|
|
|
{$i = 0}
|
|
{while $i < 16}
|
|
{$i = $i+1}
|
|
<div class='hourline_desc' style='top: {$i*4-0.5}em'>{{$i+6}|str_pad:2:'0':0}:00</div>
|
|
<div class='hourline' style='top: {$i*4}em'></div>
|
|
{/while}
|
|
{$time = {$smarty.now|date_format:"%H"}*60 + {$smarty.now|date_format:"%M"}}
|
|
<div id='timeline' style='top: {4 + ($time - 420)/15}em'></div>
|
|
|
|
{*{if $page == 0}
|
|
{for $i = 1 to 7}
|
|
<div class='weatherinfo' style="left: {3+10*$i}em;background-image: url('{$weather.{$i}.icon}');">
|
|
{$weather.{$i}.low}°C - {$weather.{$i}.high}°C
|
|
</div>
|
|
{/for}
|
|
{/if}*}
|
|
|
|
|
|
|
|
|
|
</div>
|
|
{foreach $users as $user}
|
|
{if $user.openvacation < 0}
|
|
<a href='?action=terminadd&user={$user.id}' style="color: #000;" title='Urlaub eintragen'><span class='legendcolbox' style='background-color: {$user.color|escape}'>{$user.vname|escape} {$user.nname|escape} <font color='#cc0000'><b>({$user.openvacation|escape})</b></font></span></a>
|
|
{else}
|
|
<a href='?action=terminadd&user={$user.id}' style="color: #000;" title='Urlaub eintragen'><span class='legendcolbox' style='background-color: {$user.color|escape}'>{$user.vname|escape} {$user.nname|escape} <b>({$user.openvacation|escape})</b></span></a>
|
|
{/if}
|
|
{/foreach}
|
|
<br />
|
|
<br />
|
|
<script type="text/javascript">
|
|
|
|
|
|
$(".terminbox").tooltip({
|
|
track: true,
|
|
delay: 0,
|
|
showURL: false,
|
|
showBody: " - ",
|
|
|
|
});
|
|
$(".doneterminbox").tooltip({
|
|
track: true,
|
|
delay: 0,
|
|
showURL: false,
|
|
showBody: " - ",
|
|
|
|
});
|
|
|
|
</script>
|