Compare commits

..
Author SHA1 Message Date
Harald Bamberger 5d024b3a71 Merge branch 'feature-77978/Renew_52546_and_53902' 2026-07-23 08:01:44 +02:00
Harald Bamberger 507b47e9ea add name to Udf component 2026-07-23 07:59:02 +02:00
Paolo a83fe561b9 Added the new property "readonly" to the UDF component to switch between edit and readonly mode for all the UDfs 2026-07-22 09:18:23 +02:00
Harald Bamberger c84146fcbd Merge branch 'bug-77989/StudVW_Datepicker_check_modeltype' 2026-07-17 10:36:23 +02:00
ma0068 35decf476c make fields deletable with keyboard: Konto Buchungsdatum, Prüfung Datum, Abschlussprüfung Datum und Sponsion, Mobilität von und bis 2026-07-17 09:12:02 +02:00
Harald Bamberger 6cfc4b0973 Merge branch 'master' into bug-77989/StudVW_Datepicker_check_modeltype 2026-07-16 16:01:25 +02:00
Harald Bamberger 6296b87ea5 Merge branch 'bug-77989/StudVW_Datepicker_check_modeltype' 2026-07-16 15:54:18 +02:00
Harald Bamberger 576a44838f datetime format bewerbung_abgeschickt_am 2026-07-16 15:53:32 +02:00
Harald Bamberger c00e7a182c Merge branch 'master' into bug-77989/StudVW_Datepicker_check_modeltype 2026-07-16 15:00:45 +02:00
ma0068andHarald Bamberger fd1b5daf9c enable deletion of zgv and zgv master date with null and empty string 2026-07-16 14:51:38 +02:00
Harald Bamberger c0b5f2f748 add permission to DetailHeader function for use in pv21 2026-07-16 12:58:00 +02:00
ma0068 b217681ee5 use model-type for interessenten anlegen, listNew 2026-07-14 15:23:06 +02:00
ma0068 7841a73fc0 prepare field bewerbung_abgeschicktamum for showing in frontend (datestamp in database) and add also model-type to datepicker 2026-07-14 15:05:54 +02:00
ma0068 2064008f9e add model-type to fields Betriebsmittel/ausgegebenam, Betriebsmittel/retouram, Funktionen/datumvon und Funktionen/datumbis 2026-07-14 14:31:13 +02:00
ma0068 19b9906c86 Aufnahmetermine: use model-type isodate for field anmeldedatum 2026-07-14 14:23:37 +02:00
ma0068 2c3913a763 Mobility: use model-type isodate for fields von and bis 2026-07-14 14:19:25 +02:00
ma0068 9111edf442 Dokumente: use model-type isodate for field nachgereicht_am 2026-07-14 14:06:59 +02:00
ma0068 b1c47da3c3 use model-type isodate for fields in StatusModal datum and bestaetigtam 2026-07-14 14:01:12 +02:00
ma0068 67eb238876 use model-type isodate for field Details Gebdatum 2026-07-14 13:37:19 +02:00
Harald Bamberger a139cc8d2e initialize with luxon date iso format 2026-07-14 13:24:04 +02:00
Harald Bamberger 35ecbdefa8 studvw prestudent ZGV date fields and konto date fields use iso date as model-type 2026-07-14 13:17:27 +02:00
Harald Bamberger 5f0b1ace51 Merge branch 'epic/LV-Evaluierung_STG-KF-Datenaggregation' 2026-07-14 07:33:24 +02:00
Harald Bamberger b891d8baa5 Merge branch 'master' into epic/LV-Evaluierung_STG-KF-Datenaggregation 2026-07-13 18:01:35 +02:00
Cristina 5dbcf9ce70 Added sancho_header_lvevaluierung_rollout.jpg and sancho_footer_lvevaluierung_rollout.jpg 2026-07-13 17:31:34 +02:00
adisposkofh c26db6cc40 minor fix to tabulator localized columns parsing 2026-07-09 11:44:04 +02:00
Cristina 8548b93ddc Added method getPreviousSameSemesterFrom in Studiensemester_model.php
Method returns the current study semester and the previous semesters of the same type (SS/WS).
2026-07-08 18:57:31 +02:00
Cristina bdc4782e9d Merge branch 'master' into epic/LV-Evaluierung_STG-KF-Datenaggregation 2026-07-08 18:54:02 +02:00
Cristina 0583990870 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-07-08 18:53:37 +02:00
Cristina 335753be8c Adapted Lvevaluierung Mail texte "Evaluierungszeitfenster" instead of "Evaluationszeitraum" 2026-07-06 12:19:28 +02:00
Cristina 8862f050e8 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-06-09 10:37:53 +02:00
Cristina 29f9b226ab Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-05-12 17:08:53 +02:00
34 changed files with 380 additions and 402 deletions
+17 -15
View File
@@ -4,31 +4,34 @@ if (!defined('BASEPATH')) exit('No direct script access allowed');
// Define configuration parameters // Define configuration parameters
$config['email_number_to_sent'] = 1000; // Number of emails to sent each time sendAll is called $config['email_number_to_sent'] = 1000; // Number of emails to sent each time sendAll is called
$config['email_number_per_time_range'] = 882; // Number of emails to sent before pause $config['email_number_per_time_range'] = 1; // Number of emails to sent before pause
$config['email_time_range'] = 1; // Length of the pause in seconds $config['email_time_range'] = 1; // Length of the pause in seconds
$config['email_from_system'] = '[email protected]'; $config['email_from_system'] = '[email protected]';
$config['alias_from_system'] = 'No Reply'; $config['alias_from_system'] = 'No Reply';
// Smtp: if the CI email library has to connect to a smtp server
// Mail: if the system is setup to send emails with the standard php mail function
// Sendmail: if the system is setup to send email via Sendmail (or similar)
$config['protocol'] = ''; // mail, sendmail, or smtp
// If protocol is set to sendmail
$config['mailpath'] = ''; // SThe server path to Sendmail (or similar)
// If protocol is set to smtp // If protocol is set to smtp
$config['smtp_host'] = 'localhost'; // SMTP Server Address $config['smtp_host'] = 'localhost'; // SMTP Server Address
$config['smtp_port'] = 25; $config['smtp_port'] = 25;
$config['smtp_timeout'] = 1; // in seconds $config['smtp_timeout'] = 5; // in seconds
$config['smtp_keepalive'] = false; // Enable persistent SMTP connections $config['smtp_keepalive'] = false; // Enable persistent SMTP connections
$config['smtp_auth'] = false;
$config['smtp_user'] = ''; $config['smtp_user'] = '';
$config['smtp_pass'] = ''; $config['smtp_pass'] = '';
$config['smtp_encryption'] = ''; // '', 'tls' or 'ssl' $config['wordwrap'] = true; // {unwrap}http://example.com/a_long_link_that_should_not_be_wrapped.html{/unwrap}
$config['wordwrap'] = 76; $config['wrapchars'] = 76; // Character count to wrap at.
$config['is_html'] = true; // html or text $config['mailtype'] = 'html'; // html or text
$config['priority'] = 3; // 1 = High, 3 = Normal, 5 = low. When null, the header is not set at all. $config['priority'] = 3; // Email Priority. 1 = highest. 5 = lowest. 3 = normal
$config['validate'] = false; // If true then the email address will be validated
// If enabled will be logged info about emails // If enabled will be logged info about emails in Codeigniter error logs
// 0: Disable debugging (you can also leave this out completely, 0 is the default). $config['enable_debug'] = false;
// 1: Output messages sent by the client.
// 2: as 1, plus responses received from the server (this is the most useful setting).
// 3: as 2, plus more information about the initial connection - this level can help diagnose STARTTLS failures.
// 4: as 3, plus even lower-level information, very verbose, don't use for debugging SMTP, only low-level problems.
$config['enable_debug'] = 0;
// default sender // default sender
$config['sancho_mail_default_sender'] = defined('SANCHO_MAIL_DEFAULT_SENDER') ? SANCHO_MAIL_DEFAULT_SENDER : ''; $config['sancho_mail_default_sender'] = defined('SANCHO_MAIL_DEFAULT_SENDER') ? SANCHO_MAIL_DEFAULT_SENDER : '';
@@ -44,4 +47,3 @@ $config['sancho_mail_header_img'] = defined('SANCHO_MAIL_HEADER_IMG') ? SANCHO_M
// footer image for custom mails // footer image for custom mails
$config['sancho_mail_footer_img'] = defined('SANCHO_MAIL_FOOTER_IMG') ? SANCHO_MAIL_FOOTER_IMG : ''; $config['sancho_mail_footer_img'] = defined('SANCHO_MAIL_FOOTER_IMG') ? SANCHO_MAIL_FOOTER_IMG : '';
@@ -259,7 +259,7 @@ class BetriebsmittelP extends FHCAPI_Controller
$kaution = $this->input->post('kaution'); $kaution = $this->input->post('kaution');
if($kaution) $kaution = str_replace(',', '.', $kaution); if($kaution) $kaution = str_replace(',', '.', $kaution);
$ausgegebenam = $this->input->post('ausgegebenam'); $ausgegebenam = $this->input->post('ausgegebenam');
$retouram = $this->input->post('retouram'); $retouram = $this->input->post('retouram') == "" ? null : $this->input->post('retouram');
// NOTE(chris): transform_kartennummer // NOTE(chris): transform_kartennummer
if ($betriebsmitteltyp == 'Zutrittskarte' && $nummer) if ($betriebsmitteltyp == 'Zutrittskarte' && $nummer)
@@ -9,9 +9,9 @@ class Detailheader extends FHCAPI_Controller
public function __construct() public function __construct()
{ {
parent::__construct([ parent::__construct([
'getHeader' => ['vertrag/mitarbeiter:r'], 'getHeader' => ['vertrag/mitarbeiter:r', 'basis/mitarbeiter:r'],
'getPersonAbteilung' => ['vertrag/mitarbeiter:r'], 'getPersonAbteilung' => ['vertrag/mitarbeiter:r', 'basis/mitarbeiter:r'],
'getLeitungOrg' => ['vertrag/mitarbeiter:r'], 'getLeitungOrg' => ['vertrag/mitarbeiter:r', 'basis/mitarbeiter:r'],
]); ]);
} }
@@ -294,6 +294,10 @@ class Funktionen extends FHCAPI_Controller
{ {
$this->terminateWithValidationErrors($this->form_validation->error_array()); $this->terminateWithValidationErrors($this->form_validation->error_array());
} }
if($datum_von == '')
$datum_von = null;
if($datum_bis == '')
$datum_bis = null;
$result = $this->BenutzerfunktionModel->update( $result = $this->BenutzerfunktionModel->update(
[ [
@@ -371,6 +371,9 @@ class Abschlusspruefung extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array()); $this->terminateWithValidationErrors($this->form_validation->error_array());
} }
$datum = $formData['datum'] == '' ? null : $formData['datum'];
$sponsion = $formData['sponsion'] == '' ? null : $formData['sponsion'];
$result = $this->AbschlusspruefungModel->update( $result = $this->AbschlusspruefungModel->update(
[ [
'abschlusspruefung_id' => $abschlusspruefung_id 'abschlusspruefung_id' => $abschlusspruefung_id
@@ -382,8 +385,8 @@ class Abschlusspruefung extends FHCAPI_Controller
'vorsitz' => $vorsitz, 'vorsitz' => $vorsitz,
'pruefungsantritt_kurzbz' => $formData['pruefungsantritt_kurzbz'], 'pruefungsantritt_kurzbz' => $formData['pruefungsantritt_kurzbz'],
'abschlussbeurteilung_kurzbz' => $formData['abschlussbeurteilung_kurzbz'], 'abschlussbeurteilung_kurzbz' => $formData['abschlussbeurteilung_kurzbz'],
'datum' => $formData['datum'], 'datum' => $datum,
'sponsion' => $formData['sponsion'], 'sponsion' => $sponsion,
'pruefer1' => $pruefer1, 'pruefer1' => $pruefer1,
'pruefer2' => $pruefer2, 'pruefer2' => $pruefer2,
'pruefer3' => $pruefer3, 'pruefer3' => $pruefer3,
@@ -170,6 +170,8 @@ class Dokumente extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array()); $this->terminateWithValidationErrors($this->form_validation->error_array());
} }
$nachgereicht_am = $this->input->post('nachgereicht_am') == '' ? null : $this->input->post('nachgereicht_am');
$uid = getAuthUID(); $uid = getAuthUID();
$result = $this->AkteModel->update( $result = $this->AkteModel->update(
@@ -180,7 +182,7 @@ class Dokumente extends FHCAPI_Controller
'dokument_kurzbz' => $this->input->post('dokument_kurzbz'), 'dokument_kurzbz' => $this->input->post('dokument_kurzbz'),
'anmerkung_intern' => $this->input->post('anmerkung_intern'), 'anmerkung_intern' => $this->input->post('anmerkung_intern'),
'titel_intern' => $this->input->post('titel_intern'), 'titel_intern' => $this->input->post('titel_intern'),
'nachgereicht_am' => $this->input->post('nachgereicht_am'), 'nachgereicht_am' => $nachgereicht_am,
'updateamum' => date('c'), 'updateamum' => date('c'),
'updatevon' => $uid, 'updatevon' => $uid,
] ]
@@ -429,9 +429,12 @@ class Konto extends FHCAPI_Controller
'updateamum' => date('c'), 'updateamum' => date('c'),
'updatevon' => getAuthUID() 'updatevon' => getAuthUID()
]; ];
foreach ($allowed as $field) foreach ($allowed as $field)
if ($this->input->post($field) !== null) if ($this->input->post($field) !== null)
$data[$field] = $this->input->post($field); $data[$field] = $this->input->post($field);
if($data['buchungsdatum'] == '')
$data['buchungsdatum'] = null;
$result = $this->KontoModel->update($id, $data); $result = $this->KontoModel->update($id, $data);
@@ -237,8 +237,8 @@ class Mobility extends FHCAPI_Controller
} }
$formData = $this->input->post('formData'); $formData = $this->input->post('formData');
$von = $formData['von'] ?? null; $von = ($formData['von'] ?? '') ?: null;
$bis = $formData['bis'] ?? null; $bis = ($formData['bis'] ?? '') ?: null;
$nation_code = $formData['nation_code'] ?? null; $nation_code = $formData['nation_code'] ?? null;
$mobilitaetsprogramm_code = $formData['mobilitaetsprogramm_code'] ?? null; $mobilitaetsprogramm_code = $formData['mobilitaetsprogramm_code'] ?? null;
$herkunftsland_code = $formData['herkunftsland_code'] ?? null; $herkunftsland_code = $formData['herkunftsland_code'] ?? null;
@@ -193,7 +193,7 @@ class Prestudent extends FHCAPI_Controller
} }
elseif ( elseif (
$val === '' $val === ''
&& in_array($prop, ['zgvnation', 'zgvmanation', 'zgvdoktornation', 'berufstaetigkeit_code', 'ausbildungcode']) && in_array($prop, ['zgvnation', 'zgvmanation', 'zgvdoktornation', 'berufstaetigkeit_code', 'ausbildungcode', 'zgvdatum', 'zgvmadatum'])
) )
{ {
$val = null; $val = null;
@@ -448,8 +448,10 @@ class Pruefung extends FHCAPI_Controller
} }
} }
$datum = $this->input->post('datum') == '' ? null : $this->input->post('datum');
if(intval($pruefung_id) > 0) if(intval($pruefung_id) > 0)
{ {
$result = $this->PruefungModel->update( $result = $this->PruefungModel->update(
[ [
'pruefung_id' => $pruefung_id 'pruefung_id' => $pruefung_id
@@ -459,7 +461,7 @@ class Pruefung extends FHCAPI_Controller
'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'), 'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'),
'note' => $this->input->post('note'), 'note' => $this->input->post('note'),
'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'), 'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'),
'datum' => $this->input->post('datum'), 'datum' => $datum,
'anmerkung' => $this->input->post('anmerkung'), 'anmerkung' => $this->input->post('anmerkung'),
'updatevon' => $authUID, 'updatevon' => $authUID,
'updateamum' => date('c'), 'updateamum' => date('c'),
@@ -472,7 +474,7 @@ class Pruefung extends FHCAPI_Controller
'lehreinheit_id' => $this->input->post('lehreinheit_id'), 'lehreinheit_id' => $this->input->post('lehreinheit_id'),
'student_uid' => $this->input->post('student_uid'), 'student_uid' => $this->input->post('student_uid'),
'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'), 'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'),
'datum' => $this->input->post('datum'), 'datum' => $datum,
'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'), 'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'),
'note' => $this->input->post('note'), 'note' => $this->input->post('note'),
'anmerkung' => $this->input->post('anmerkung'), 'anmerkung' => $this->input->post('anmerkung'),
@@ -520,7 +522,7 @@ class Pruefung extends FHCAPI_Controller
'studiensemester_kurzbz' => $studiensemester_kurzbz, 'studiensemester_kurzbz' => $studiensemester_kurzbz,
'note' => $this->input->post('note'), 'note' => $this->input->post('note'),
'uebernahmedatum' => date('c'), 'uebernahmedatum' => date('c'),
'benotungsdatum' => $this->input->post('datum'), 'benotungsdatum' => $datum,
'insertamum' => date('c'), 'insertamum' => date('c'),
'insertvon' => $authUID, 'insertvon' => $authUID,
'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null 'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null
@@ -555,7 +557,7 @@ class Pruefung extends FHCAPI_Controller
], [ ], [
'note' => $this->input->post('note'), 'note' => $this->input->post('note'),
'uebernahmedatum' => date('c'), 'uebernahmedatum' => date('c'),
'benotungsdatum' => $this->input->post('datum'), 'benotungsdatum' => $datum,
'updateamum' => date('c'), 'updateamum' => date('c'),
'updatevon' => $authUID, 'updatevon' => $authUID,
'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null 'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null
@@ -296,6 +296,10 @@ class Student extends FHCAPI_Controller
$fotoval = ($val == '') ? null : str_replace('data:image/jpeg;base64,', '', $val); $fotoval = ($val == '') ? null : str_replace('data:image/jpeg;base64,', '', $val);
$update_person[$prop] = $fotoval; $update_person[$prop] = $fotoval;
} }
else if ($prop == 'gebdatum')
{
$update_person[$prop] = ($val == '') ? null : $val;
}
else else
{ {
$update_person[$prop] = $val; $update_person[$prop] = $val;
+41 -20
View File
@@ -35,20 +35,41 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
* @param string $bcc Sets BCC of mail. * @param string $bcc Sets BCC of mail.
* @return void * @return void
*/ */
function sendSanchoMail($vorlage_kurzbz, $vorlage_data, $to, $subject, $headerImg = '', $footerImg = '', $from = null, $cc = null, $bcc = null) function sendSanchoMail(
$vorlage_kurzbz,
$vorlage_data,
$to,
$subject,
$headerImg = '',
$footerImg = '',
$from = null,
$cc = null,
$bcc = null
)
{ {
$ci =& get_instance(); $ci =& get_instance();
$ci->load->library('email');
$ci->load->library('MailLib'); $ci->load->library('MailLib');
$embeddedImages = array();
$_from = 'noreply@' . DOMAIN;
$sancho_mail_config = $ci->config->item('mail'); $sancho_mail_config = $ci->config->item('mail');
if ($from == null && isset($sancho_mail_config['sancho_mail_default_sender']) && $sancho_mail_config['sancho_mail_default_sender'])
if ($from == '')
{ {
$_from = $sancho_mail_config['sancho_mail_default_sender'] . '@' . DOMAIN; $from = ((isset($sancho_mail_config['sancho_mail_default_sender'])
&& $sancho_mail_config['sancho_mail_default_sender'])
? $sancho_mail_config['sancho_mail_default_sender']
: 'noreply')
. '@' . DOMAIN;
} }
// Embed sancho header and footer image
// reset important to ensure embedding of images when called in a loop
$ci->email->clear(true); // clear vars and attachments
$cid_header = '';
$cid_footer = '';
if (isset($sancho_mail_config['sancho_mail_use_images']) && $sancho_mail_config['sancho_mail_use_images']) if (isset($sancho_mail_config['sancho_mail_use_images']) && $sancho_mail_config['sancho_mail_use_images'])
{ {
$sanchoHeader_img = ''; $sanchoHeader_img = '';
@@ -90,27 +111,29 @@ function sendSanchoMail($vorlage_kurzbz, $vorlage_data, $to, $subject, $headerIm
} }
} }
// Attach header and footer // attach header and footer
$embeddedImages[] = array('file_name' => $sanchoHeader_img, 'cid' => 'sancho_header'); $ci->email->attach($sanchoHeader_img, 'inline');
$embeddedImages[] = array('file_name' => $sanchoFooter_img, 'cid' => 'sancho_footer'); $ci->email->attach($sanchoFooter_img, 'inline');
$cid_header = $ci->email->attachment_cid($sanchoHeader_img); // sets unique content id for embedding
$cid_footer = $ci->email->attachment_cid($sanchoFooter_img); // sets unique content id for embedding
} }
// Set specific mail content into specific content template // Set specific mail content into specific content template
$content = _parseMailContent($vorlage_kurzbz, $vorlage_data); $content = _parseMailContent($vorlage_kurzbz, $vorlage_data);
// Set overall main content into the sancho mail template // overall main content data array
$body = _parseMailContent( $layout = array(
'Sancho_Mail_Template', 'CID_header' => $cid_header,
array( 'CID_footer' => $cid_footer,
'CID_header' => 'sancho_header', 'content' => $content
'CID_footer' => 'sancho_footer',
'content' => $content
)
); );
// Set overall main content into the sancho mail template
$body = _parseMailContent('Sancho_Mail_Template', $layout);
// Send mail // Send mail
return $ci->maillib->send( return $ci->maillib->send(
$_from, $from,
$to, $to,
$subject, $subject,
$body, $body,
@@ -119,8 +142,7 @@ function sendSanchoMail($vorlage_kurzbz, $vorlage_data, $to, $subject, $headerIm
$bcc, $bcc,
'', // altMessage '', // altMessage
true, // bulk true, // bulk
true, // autogenerated true // autogenerated
$embeddedImages
); );
} }
@@ -149,4 +171,3 @@ function _parseMailContent($vorlage_kurzbz, $vorlage_data)
} }
} }
} }
+87 -130
View File
@@ -2,10 +2,6 @@
if (! defined('BASEPATH')) exit('No direct script access allowed'); if (! defined('BASEPATH')) exit('No direct script access allowed');
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
/** /**
* Library to manage the sending of the email * Library to manage the sending of the email
*/ */
@@ -13,7 +9,7 @@ class MailLib
{ {
const ENABLE_DEBUG = 'enable_debug'; const ENABLE_DEBUG = 'enable_debug';
private $_sended; // Sended email counter private $sended; // Sended email counter
// Properties for storing the configuration // Properties for storing the configuration
private $email_number_to_sent; private $email_number_to_sent;
@@ -22,7 +18,6 @@ class MailLib
private $email_from_system; private $email_from_system;
private $_ci; // Codeigniter instance private $_ci; // Codeigniter instance
private $_mail; // PHPMailer instance
/** /**
* Class constructor * Class constructor
@@ -30,7 +25,7 @@ class MailLib
public function __construct() public function __construct()
{ {
// Set the counter to 0 // Set the counter to 0
$this->_sended = 0; $this->sended = 0;
// Get CI instance // Get CI instance
$this->_ci =& get_instance(); $this->_ci =& get_instance();
@@ -38,135 +33,97 @@ class MailLib
// The second parameter is used to avoiding name collisions in the config array // The second parameter is used to avoiding name collisions in the config array
$this->_ci->config->load('mail', true); $this->_ci->config->load('mail', true);
try // CI Email library
{ $this->_ci->load->library('email');
// PHPMailer configuration
$this->_mail = new PHPMailer(true);
$this->_mail->isSMTP(); // Send using SMTP
$this->_mail->Host = $this->_getEmailCfgItem('smtp_host'); // Set the SMTP server to send through
$this->_mail->Port = $this->_getEmailCfgItem('smtp_port'); // TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
$this->_mail->SMTPAuth = $this->_getEmailCfgItem('smtp_auth'); // Enable SMTP authentication
$this->_mail->Username = $this->_getEmailCfgItem('smtp_user'); // SMTP username
$this->_mail->Password = $this->_getEmailCfgItem('smtp_pass'); // SMTP password
$this->_mail->SMTPSecure = $this->_getEmailCfgItem('smtp_encryption'); // Enable implicit TLS encryption
$this->_mail->Timeout = $this->_getEmailCfgItem('smtp_timeout'); // set the timeout (seconds)
$this->_mail->SMTPKeepAlive = $this->_getEmailCfgItem('smtp_keepalive'); // Persistent SMTP connection
$this->_mail->Priority = $this->_getEmailCfgItem('priority'); // 1 = High, 3 = Normal, 5 = low. When null, the header is not set at all.
$this->_mail->WordWrap = $this->_getEmailCfgItem('wordwrap');
$this->_mail->isHTML($this->_getEmailCfgItem('is_html')); // html or text
$this->_mail->SMTPDebug = $this->_getEmailCfgItem('enable_debug');
$this->_mail->CharSet = 'UTF-8';
// Set the configuration properties with the standard configuration values // Initializing email library with the loaded configurations
$this->email_number_to_sent = $this->_getEmailCfgItem('email_number_to_sent'); $this->_ci->email->initialize($this->_ci->config->config['mail']);
$this->email_number_per_time_range = $this->_getEmailCfgItem('email_number_per_time_range');
$this->email_time_range = $this->_getEmailCfgItem('email_time_range'); // Set the configuration properties with the standard configuration values
$this->email_from_system = $this->_getEmailCfgItem('email_from_system'); $this->email_number_to_sent = $this->getEmailCfgItem('email_number_to_sent');
$this->alias_from_system = $this->_getEmailCfgItem('alias_from_system'); $this->email_number_per_time_range = $this->getEmailCfgItem('email_number_per_time_range');
} $this->email_time_range = $this->getEmailCfgItem('email_time_range');
catch(Exception $e) $this->email_from_system = $this->getEmailCfgItem('email_from_system');
{ $this->alias_from_system = $this->getEmailCfgItem('alias_from_system');
error_log($e->errorMessage());
}
} }
/** /**
* Sends a single email * Sends a single email
*/ */
public function send($from, $to, $subject, $message, $alias = '', $cc = null, $bcc = null, $altMessage = '', $bulk = false, $autogenerated = false, $embeddedImages = array()) public function send($from, $to, $subject, $message, $alias = '', $cc = null, $bcc = null, $altMessage = '', $bulk = false, $autogenerated = false)
{ {
$result = false; // If it is configured then log mail info into the CI error logs
if ($this->getEmailCfgItem(self::ENABLE_DEBUG) === true)
try
{ {
// If it is configured then log mail info into the CI error logs $this->_ci->load->library('LogLib'); // Loads logging library
if ($this->_getEmailCfgItem(self::ENABLE_DEBUG) === true)
{
$this->_ci->load->library('LogLib'); // Loads logging library
// Log them all! // Log them all!
$this->_ci->loglib->logError('From: '.$from); $this->_ci->loglib->logError('From: '.$from);
$this->_ci->loglib->logError('To: '.$to); $this->_ci->loglib->logError('To: '.$to);
$this->_ci->loglib->logError('Subject: '.$subject); $this->_ci->loglib->logError('Subject: '.$subject);
$this->_ci->loglib->logError('Message: '.$message); $this->_ci->loglib->logError('Message: '.$message);
$this->_ci->loglib->logError('Alias: '.$alias); $this->_ci->loglib->logError('Alias: '.$alias);
$this->_ci->loglib->logError('CC: '.$cc); $this->_ci->loglib->logError('CC: '.$cc);
$this->_ci->loglib->logError('BCC: '.$bcc); $this->_ci->loglib->logError('BCC: '.$bcc);
$this->_ci->loglib->logError('Alternative message: '.$altMessage); $this->_ci->loglib->logError('Alternative message: '.$altMessage);
}
// If from is not specified then use the standard one
if (is_null($from) || $from == '')
{
$from = $this->email_from_system;
// If alias is not specified then use the standard one
if (is_null($alias) || $alias == '')
{
$alias = $this->alias_from_system;
}
}
if (defined('MAIL_FROM') && MAIL_FROM != '')
{
$from = MAIL_FROM;
if (is_null($alias) || $alias == '')
{
$alias = $this->alias_from_system;
}
}
$this->_mail->setFrom($from, $alias);
// Check if the email address of the debug recipient is a valid one
$recipient = $to;
$recipientCC = $cc;
$recipientBCC = $bcc;
// If we the an email for debugging has been set
if (defined('MAIL_DEBUG') && MAIL_DEBUG != '')
{
// if is it valid use it!!!
$recipient = MAIL_DEBUG;
if ($recipientCC != '') $recipientCC = MAIL_DEBUG;
if ($recipientBCC != '') $recipientBCC = MAIL_DEBUG;
}
// Recipients
$this->_mail->addAddress($recipient);
if (!is_null($recipientCC)) $this->_mail->addCC($recipientCC);
if (!is_null($recipientBCC)) $this->_mail->addBCC($recipientBCC);
// Subject & body & alternative body
$this->_mail->Subject = $subject;
$this->_mail->Body = $message;
if (!isEmptyString($altMessage)) $this->_mail->AltBody = $altMessage;
// Custom headers
if ($bulk) $this->_mail->addCustomHeader('Precedence', 'bulk');
if ($autogenerated) $this->_mail->addCustomHeader('Auto-Submitted', 'auto-generated');
// Embedded images
foreach ($embeddedImages as $embeddedImage)
{
if (!$this->_mail->addEmbeddedImage($embeddedImage['file_name'], $embeddedImage['cid'])) return false;
}
$result = $this->_mail->send();
// If the email was succesfully sended then increment the counter and checks if it has to _wait until the sending of the next
if ($result != false)
{
$this->_sended++;
$this->_wait();
}
// Clear the properties for the next message
$this->_mail->clearAddresses();
$this->_mail->clearAllRecipients();
$this->_mail->clearAttachments();
} }
catch (Exception $e)
// If from is not specified then use the standard one
if (is_null($from) || $from == '')
{ {
error_log($e->errorMessage()); $from = $this->email_from_system;
// If alias is not specified then use the standard one
if (is_null($alias) || $alias == '')
{
$alias = $this->alias_from_system;
}
}
if (defined('MAIL_FROM') && MAIL_FROM != '')
{
$from = MAIL_FROM;
if (is_null($alias) || $alias == '')
{
$alias = $this->alias_from_system;
}
}
$this->_ci->email->from($from, $alias);
// Check if the email address of the debug recipient is a valid one
$recipient = $to;
$recipientCC = $cc;
$recipientBCC = $bcc;
if (defined('MAIL_DEBUG') && MAIL_DEBUG != '')
{
// if is it valid use it!!!
$recipient = MAIL_DEBUG;
if ($recipientCC != '')
$recipientCC = MAIL_DEBUG;
if ($recipientBCC != '')
$recipientBCC = MAIL_DEBUG;
}
$this->_ci->email->to($recipient);
if (!is_null($recipientCC)) $this->_ci->email->cc($recipientCC);
if (!is_null($recipientBCC)) $this->_ci->email->bcc($recipientBCC);
$this->_ci->email->subject($subject);
$this->_ci->email->message($message);
if (!isEmptyString($altMessage)) $this->_ci->email->set_alt_message($altMessage);
if($bulk)
$this->_ci->email->set_header('Precedence', 'bulk');
if($autogenerated)
$this->_ci->email->set_header('Auto-Submitted', 'auto-generated');
// Avoid printing on standard output ugly error messages
$result = @$this->_ci->email->send();
// If the email was succesfully sended then increment the counter
// and checks if it has to wait until the sending of the next
if ($result)
{
$this->sended++;
$this->wait();
} }
return $result; return $result;
@@ -219,13 +176,13 @@ class MailLib
} }
/** /**
* Checks if it has to _wait until the sending of the next * Checks if it has to wait until the sending of the next
*/ */
private function _wait() private function wait()
{ {
if ($this->_sended == $this->email_number_per_time_range) if ($this->sended == $this->email_number_per_time_range)
{ {
$this->_sended = 0; $this->sended = 0;
sleep($this->email_time_range); // Wait!!! sleep($this->email_time_range); // Wait!!!
} }
} }
@@ -233,7 +190,7 @@ class MailLib
/** /**
* Gets an item from the email configuration array * Gets an item from the email configuration array
*/ */
private function _getEmailCfgItem($itemName) private function getEmailCfgItem($itemName)
{ {
return $this->_ci->config->item($itemName, EMAIL_CONFIG_INDEX); return $this->_ci->config->item($itemName, EMAIL_CONFIG_INDEX);
} }
@@ -122,6 +122,47 @@ class Studiensemester_model extends DB_Model
return $this->execQuery($query, array($studiensemester_kurzbz, $limit)); return $this->execQuery($query, array($studiensemester_kurzbz, $limit));
} }
/**
* Returns the current study semester and the previous semesters of the same type (SS/WS).
*
* Example:
* - SS2026, limit 3: SS2026, SS2025, SS2024
* - WS2025, limit 2: WS2025, WS2024
*
* @param $studiensemester_kurzbz
* @param $limit
*/
public function getPreviousSameSemesterFrom($studiensemester_kurzbz, $limit = 1)
{
$qry = '
SELECT
studiensemester_kurzbz,
start,
ende
FROM
public.tbl_studiensemester
WHERE
SUBSTRING(studiensemester_kurzbz FROM 1 FOR 2) = SUBSTRING(? FROM 1 FOR 2)
AND start <= (
SELECT start
FROM public.tbl_studiensemester
WHERE studiensemester_kurzbz = ?
)
ORDER BY
start DESC
LIMIT ?
';
return $this->execQuery($qry,
[
$studiensemester_kurzbz,
$studiensemester_kurzbz,
$limit
]
);
}
/** /**
* getNearest * getNearest
*/ */
@@ -260,7 +260,6 @@ class Benutzerfunktion_model extends DB_Model
return $this->execQuery($query, $parameters_array); return $this->execQuery($query, $parameters_array);
} }
/** /**
* Get active Kompetenzfeldleitung bei UID. * Get active Kompetenzfeldleitung bei UID.
* *
@@ -296,7 +295,6 @@ class Benutzerfunktion_model extends DB_Model
return $this->execQuery($query, $parameters_array); return $this->execQuery($query, $parameters_array);
} }
public function insertBenutzerfunktion($Json) public function insertBenutzerfunktion($Json)
{ {
unset($Json['benutzerfunktion_id']); unset($Json['benutzerfunktion_id']);
+1 -2
View File
@@ -519,8 +519,7 @@
"vuejs/vuedatepicker_js": "7.2.0", "vuejs/vuedatepicker_js": "7.2.0",
"vuejs/vuedatepicker_css": "7.2.0", "vuejs/vuedatepicker_css": "7.2.0",
"vuejs/vuedatepicker_js11": "11.0.1", "vuejs/vuedatepicker_js11": "11.0.1",
"vuejs/vuedatepicker_css11": "11.0.1", "vuejs/vuedatepicker_css11": "11.0.1"
"phpmailer/phpmailer": "^7.0"
}, },
"config": { "config": {
Generated
+32 -137
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "3ec44005c1f5f810f304ad049a2c5c6b", "content-hash": "869cbc35bd1ba90ab90934fcb41b0f51",
"packages": [ "packages": [
{ {
"name": "afarkas/html5shiv", "name": "afarkas/html5shiv",
@@ -897,12 +897,12 @@
"version": "v6.0.0", "version": "v6.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/googleapis/php-jwt.git", "url": "https://github.com/firebase/php-jwt.git",
"reference": "0541cba75ab108ef901985e68055a92646c73534" "reference": "0541cba75ab108ef901985e68055a92646c73534"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/googleapis/php-jwt/zipball/0541cba75ab108ef901985e68055a92646c73534", "url": "https://api.github.com/repos/firebase/php-jwt/zipball/0541cba75ab108ef901985e68055a92646c73534",
"reference": "0541cba75ab108ef901985e68055a92646c73534", "reference": "0541cba75ab108ef901985e68055a92646c73534",
"shasum": "" "shasum": ""
}, },
@@ -944,8 +944,8 @@
"php" "php"
], ],
"support": { "support": {
"issues": "https://github.com/googleapis/php-jwt/issues", "issues": "https://github.com/firebase/php-jwt/issues",
"source": "https://github.com/googleapis/php-jwt/tree/v6.0.0" "source": "https://github.com/firebase/php-jwt/tree/v6.0.0"
}, },
"time": "2022-01-24T15:18:34+00:00" "time": "2022-01-24T15:18:34+00:00"
}, },
@@ -1614,100 +1614,18 @@
}, },
"type": "library" "type": "library"
}, },
{
"name": "phpmailer/phpmailer",
"version": "v7.1.1",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "1bc1716a507a65e039d4ac9d9adebbbd0d346e15"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/1bc1716a507a65e039d4ac9d9adebbbd0d346e15",
"reference": "1bc1716a507a65e039d4ac9d9adebbbd0d346e15",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-filter": "*",
"ext-hash": "*",
"php": ">=5.5.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^10.0.0@dev",
"squizlabs/php_codesniffer": "^3.13.5",
"yoast/phpunit-polyfills": "^1.0.4"
},
"suggest": {
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
"directorytree/imapengine": "For uploading sent messages via IMAP, see gmail example",
"ext-imap": "Needed to support advanced email address parsing according to RFC822",
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
},
"type": "library",
"autoload": {
"psr-4": {
"PHPMailer\\PHPMailer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1-only"
],
"authors": [
{
"name": "Marcus Bointon",
"email": "[email protected]"
},
{
"name": "Jim Jagielski",
"email": "[email protected]"
},
{
"name": "Andy Prevost",
"email": "[email protected]"
},
{
"name": "Brent R. Matzelle"
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v7.1.1"
},
"funding": [
{
"url": "https://github.com/Synchro",
"type": "github"
}
],
"time": "2026-05-18T08:06:14+00:00"
},
{ {
"name": "phpseclib/phpseclib", "name": "phpseclib/phpseclib",
"version": "2.0.55", "version": "2.0.48",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpseclib/phpseclib.git", "url": "https://github.com/phpseclib/phpseclib.git",
"reference": "d73c9e019a895be83b18a2ccccfa7e2b0a648743" "reference": "eaa7be704b8b93a6913b69eb7f645a59d7731b61"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d73c9e019a895be83b18a2ccccfa7e2b0a648743", "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/eaa7be704b8b93a6913b69eb7f645a59d7731b61",
"reference": "d73c9e019a895be83b18a2ccccfa7e2b0a648743", "reference": "eaa7be704b8b93a6913b69eb7f645a59d7731b61",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1715,7 +1633,7 @@
}, },
"require-dev": { "require-dev": {
"phing/phing": "~2.7", "phing/phing": "~2.7",
"phpunit/phpunit": "^4.8.35|^5.7|^6.0|^8.5|^9.4", "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4",
"squizlabs/php_codesniffer": "~2.0" "squizlabs/php_codesniffer": "~2.0"
}, },
"suggest": { "suggest": {
@@ -1788,7 +1706,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/phpseclib/phpseclib/issues", "issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/2.0.55" "source": "https://github.com/phpseclib/phpseclib/tree/2.0.48"
}, },
"funding": [ "funding": [
{ {
@@ -1804,7 +1722,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-06-14T19:53:12+00:00" "time": "2024-12-14T21:03:54+00:00"
}, },
{ {
"name": "rmariuzzo/jquery-checkboxes", "name": "rmariuzzo/jquery-checkboxes",
@@ -2013,18 +1931,8 @@
], ],
"support": { "support": {
"issues": "https://github.com/twigphp/Twig/issues", "issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v1.42.5" "source": "https://github.com/twigphp/Twig/tree/1.x"
}, },
"funding": [
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
"type": "tidelift"
}
],
"time": "2020-02-11T05:59:23+00:00" "time": "2020-02-11T05:59:23+00:00"
}, },
{ {
@@ -2818,29 +2726,33 @@
}, },
{ {
"name": "phpmetrics/phpmetrics", "name": "phpmetrics/phpmetrics",
"version": "v2.9.1", "version": "v2.8.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpmetrics/PhpMetrics.git", "url": "https://github.com/phpmetrics/PhpMetrics.git",
"reference": "e2e68ddd1543bc3f44402c383f7bccb62de1ece3" "reference": "4b77140a11452e63c7a9b98e0648320bf6710090"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpmetrics/PhpMetrics/zipball/e2e68ddd1543bc3f44402c383f7bccb62de1ece3", "url": "https://api.github.com/repos/phpmetrics/PhpMetrics/zipball/4b77140a11452e63c7a9b98e0648320bf6710090",
"reference": "e2e68ddd1543bc3f44402c383f7bccb62de1ece3", "reference": "4b77140a11452e63c7a9b98e0648320bf6710090",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-dom": "*", "ext-dom": "*",
"ext-tokenizer": "*", "ext-tokenizer": "*",
"nikic/php-parser": "^3|^4|^5" "nikic/php-parser": "^3|^4",
"php": ">=5.5"
}, },
"replace": { "replace": {
"halleck45/php-metrics": "*", "halleck45/php-metrics": "*",
"halleck45/phpmetrics": "*" "halleck45/phpmetrics": "*"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "*" "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14",
"sebastian/comparator": ">=1.2.3",
"squizlabs/php_codesniffer": "^3.5",
"symfony/dom-crawler": "^3.0 || ^4.0 || ^5.0"
}, },
"bin": [ "bin": [
"bin/phpmetrics" "bin/phpmetrics"
@@ -2876,15 +2788,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/PhpMetrics/PhpMetrics/issues", "issues": "https://github.com/PhpMetrics/PhpMetrics/issues",
"source": "https://github.com/phpmetrics/PhpMetrics/tree/v2.9.1" "source": "https://github.com/phpmetrics/PhpMetrics/tree/v2.8.2"
}, },
"funding": [ "time": "2023-03-08T15:03:36+00:00"
{
"url": "https://github.com/Halleck45",
"type": "github"
}
],
"time": "2025-09-25T05:21:02+00:00"
}, },
{ {
"name": "phpspec/prophecy", "name": "phpspec/prophecy",
@@ -3221,6 +3127,7 @@
"issues": "https://github.com/sebastianbergmann/php-token-stream/issues", "issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
"source": "https://github.com/sebastianbergmann/php-token-stream/tree/master" "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
}, },
"abandoned": true,
"time": "2017-11-27T05:48:46+00:00" "time": "2017-11-27T05:48:46+00:00"
}, },
{ {
@@ -4056,16 +3963,16 @@
}, },
{ {
"name": "sebastian/recursion-context", "name": "sebastian/recursion-context",
"version": "3.0.3", "version": "3.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git", "url": "https://github.com/sebastianbergmann/recursion-context.git",
"reference": "8fe7e75986a9d24b4cceae847314035df7703a5a" "reference": "9bfd3c6f1f08c026f542032dfb42813544f7d64c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/8fe7e75986a9d24b4cceae847314035df7703a5a", "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/9bfd3c6f1f08c026f542032dfb42813544f7d64c",
"reference": "8fe7e75986a9d24b4cceae847314035df7703a5a", "reference": "9bfd3c6f1f08c026f542032dfb42813544f7d64c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4107,27 +4014,15 @@
"homepage": "http://www.github.com/sebastianbergmann/recursion-context", "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/recursion-context/issues", "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
"source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.3" "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.2"
}, },
"funding": [ "funding": [
{ {
"url": "https://github.com/sebastianbergmann", "url": "https://github.com/sebastianbergmann",
"type": "github" "type": "github"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
"type": "tidelift"
} }
], ],
"time": "2025-08-10T05:25:53+00:00" "time": "2024-03-01T14:07:30+00:00"
}, },
{ {
"name": "sebastian/resource-operations", "name": "sebastian/resource-operations",
+72 -66
View File
@@ -16,9 +16,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
* *
* Authors: Christian Paminger <[email protected]>, * Authors: Christian Paminger <[email protected]>,
* Andreas Oesterreicher <[email protected]>, * Andreas Oesterreicher <[email protected]>,
* Rudolf Hangl <[email protected]> and * Rudolf Hangl <[email protected]> and
* Gerald Simane-Sequens <[email protected]> * Gerald Simane-Sequens <[email protected]>
*/ */
/** /**
* Klasse Mail * Klasse Mail
@@ -28,12 +28,6 @@
* Replyto und Attachments * Replyto und Attachments
*/ */
include_once DOC_ROOT . 'vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
class mail class mail
{ {
public $to; public $to;
@@ -47,8 +41,6 @@ class mail
public $attachments; public $attachments;
public $errormsg; public $errormsg;
private $_mail; // PHPMailer instance
/** /**
* MAIL - Konstruktor * MAIL - Konstruktor
* $to Empfaenger * $to Empfaenger
@@ -73,30 +65,6 @@ class mail
*/ */
public function send() public function send()
{ {
// PHPMailer configuration
try
{
$this->_mail = new PHPMailer(true);
$this->_mail->isSMTP(); // Send using SMTP
$this->_mail->Host = 'localhost'; // Set the SMTP server to send through
$this->_mail->Port = 25; // TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
$this->_mail->SMTPAuth = false; // Enable SMTP authentication
$this->_mail->Username = ''; // SMTP username
$this->_mail->Password = ''; // SMTP password
$this->_mail->SMTPSecure = ''; // Enable implicit TLS encryption
$this->_mail->Timeout = 1; // set the timeout (seconds)
$this->_mail->SMTPKeepAlive = false; // Persistent SMTP connection
$this->_mail->Priority = 3; // 1 = High, 3 = Normal, 5 = low. When null, the header is not set at all.
$this->_mail->WordWrap = 76;
$this->_mail->isHTML(true); // html or text
$this->_mail->SMTPDebug = 0; // Disable debugging
$this->_mail->CharSet = 'UTF-8';
}
catch(Exception $e)
{
return false;
}
//wenn MAIL_DEBUG gesetzt ist dann alles an diese Adresse schicken //wenn MAIL_DEBUG gesetzt ist dann alles an diese Adresse schicken
if(MAIL_DEBUG!='') if(MAIL_DEBUG!='')
{ {
@@ -114,38 +82,68 @@ class mail
$this->sender = MAIL_FROM; $this->sender = MAIL_FROM;
// Header // Header
$this->_mail->setFrom($this->sender); $header = '';
$header .= "From: {$this->sender}".$eol;
if (!empty($this->CC_recievers)) if (!empty($this->CC_recievers))
$this->_mail->addCC($this->CC_recievers); $header .= "CC: {$this->CC_recievers}".$eol;
if (!empty($this->BCC_recievers)) if (!empty($this->BCC_recievers))
$this->_mail->addBCC($this->BCC_recievers); $header .= "BCC: {$this->BCC_recievers}".$eol;
if (!empty($this->replyTo)) if (!empty($this->replyTo))
$header .= "Reply-To: {$this->replyTo}".$eol;
if (!empty($this->replyTo))
$header .= "Return-Path: {$this->replyTo}".$eol;
$header .= 'X-Mailer: FHComplete V1'.$eol;
$header .= 'Mime-Version: 1.0'.$eol;
$header .= 'Precedence: bulk'.$eol;
$header .= 'Auto-Submitted: auto-generated'.$eol;
$header .= "Content-Type: multipart/related; boundary=\"$mime_boundary_mixed\"".$eol;
$header .= "Content-Transfer-Encoding: 8bit".$eol;
// Body
$mailbody = "";
$mailbody .= $eol;
$mailbody .= "--$mime_boundary_mixed".$eol;
$mailbody .= "Content-Type: multipart/alternative; boundary=\"$mime_boundary_alternative\"".$eol;
$mailbody .= $eol;
$mailbody .= "--$mime_boundary_alternative".$eol;
$mailbody .= "Content-Type: text/plain; charset={$this->textContent[1]}".$eol;
$mailbody .= "Content-Transfer-Encoding: {$this->textContent[2]}".$eol;
$mailbody .= $eol;
$mailbody .= $this->textContent[0];
$mailbody .= $eol;
$mailbody .= $eol;
if (!empty($this->htmlContent[0]))
{ {
$this->_mail->addReplyTo($this->replyTo); $mailbody .= "--$mime_boundary_alternative".$eol;
$this->_mail->addCustomHeader('Return-Path', $this->replyTo); $mailbody .= "Content-Type: text/html; charset={$this->htmlContent[1]}".$eol;
$mailbody .= "Content-Transfer-Encoding: {$this->htmlContent[2]}".$eol;
$mailbody .= $eol;
$mailbody .= $this->htmlContent[0];
$mailbody .= $eol;
$mailbody .= $eol;
} }
$mailbody .= "--{$mime_boundary_alternative}--".$eol;
$this->_mail->addCustomHeader('X-Mailer', 'FHComplete V1'); $mailbody .= $eol;
$this->_mail->addCustomHeader('Mime-Version', '1.0'); $mailbody .= "--$mime_boundary_mixed";
$this->_mail->addCustomHeader('Precedence', 'bulk');
$this->_mail->addCustomHeader('Auto-Submitted', 'auto-generated');
$this->_mail->Body = $this->htmlContent[0];
$this->_mail->AltBody = $this->textContent[0];
// Attachments Plain // Attachments Plain
if (is_array($this->attachmentsplain) && (count($this->attachmentsplain) > 0)) if (is_array($this->attachmentsplain) && (count($this->attachmentsplain) > 0))
{ {
foreach ($this->attachmentsplain as $attachment) foreach ($this->attachmentsplain as $attachment)
{ {
$this->_mail->addStringAttachment( $dispo = 'attachment';
$attachment[0], // File content $mailbody .= $eol;
$attachment[2], // Name $mailbody .= "Content-Disposition: $dispo; filename={$attachment[2]}".$eol;
$attachment[3], // Encoding $mailbody .= "Content-Type: {$attachment[1]}; name={$attachment[2]}".$eol;
$attachment[1], // Type
'attachment' // Disposition $mailbody .= 'Content-Transfer-Encoding: '.$attachment[3].$eol;
); $mailbody .= $eol;
$mailbody .= $attachment[0];
$mailbody .= $eol;
$mailbody .= "--$mime_boundary_mixed";
} }
} }
@@ -154,23 +152,31 @@ class mail
{ {
foreach ($this->attachments as $attachment) foreach ($this->attachments as $attachment)
{ {
$this->_mail->addStringEmbeddedImage( $dispo = empty($attachment[3]) ? 'attachment' : 'inline';
$attachment[0], // File content $mailbody .= $eol;
$attachment[3], // Content ID $mailbody .= "Content-Disposition: $dispo; filename={$attachment[2]}".$eol;
$attachment[2], // Content name $mailbody .= "Content-Type: {$attachment[1]}; name={$attachment[2]}".$eol;
PHPMailer::ENCODING_BASE64, // Encoding if (!empty($attachment[3]))
$attachment[1], // Type {
empty($attachment[3]) ? 'attachment' : 'inline' // Disposition $mailbody .= "Content-ID: <{$attachment[3]}>".$eol;
); }
$mailbody .= 'Content-Transfer-Encoding: base64'.$eol;
$mailbody .= $eol;
$mailbody .= $attachment[0];
$mailbody .= $eol;
$mailbody .= "--$mime_boundary_mixed";
} }
} }
$mailbody .= "--".$eol;
// Subject Encoding setzen // Subject Encoding setzen
$this->_mail->Subject = $this->subject; $subject = "=?UTF-8?B?".base64_encode($this->subject)."?=";
$this->_mail->addAddress($this->to);
// Senden // Senden
return $this->_mail->send(); if(mail($this->to, $subject, $mailbody, $header))
return true;
else
return false;
} }
/** /**
@@ -433,6 +433,7 @@ export default {
:label="$p.t('wawi/ausgegebenam')" :label="$p.t('wawi/ausgegebenam')"
name="ausgegebenam" name="ausgegebenam"
v-model="formData.ausgegebenam" v-model="formData.ausgegebenam"
model-type="yyyy-MM-dd"
auto-apply auto-apply
:enable-time-picker="false" :enable-time-picker="false"
text-input text-input
@@ -449,6 +450,7 @@ export default {
:label="$p.t('wawi/retouram')" :label="$p.t('wawi/retouram')"
name="retouram" name="retouram"
v-model="formData.retouram" v-model="formData.retouram"
model-type="yyyy-MM-dd"
auto-apply auto-apply
:enable-time-picker="false" :enable-time-picker="false"
text-input text-input
@@ -551,6 +551,7 @@ export default {
container-class="mb-3 col-3" container-class="mb-3 col-3"
type="DatePicker" type="DatePicker"
v-model="formData.datum_von" v-model="formData.datum_von"
model-type="yyyy-MM-dd"
name="datum_von" name="datum_von"
:label="$p.t('ui/from') + ' *'" :label="$p.t('ui/from') + ' *'"
auto-apply auto-apply
@@ -566,6 +567,7 @@ export default {
container-class="mb-3 col-3" container-class="mb-3 col-3"
type="DatePicker" type="DatePicker"
v-model="formData.datum_bis" v-model="formData.datum_bis"
model-type="yyyy-MM-dd"
name="datum_bis" name="datum_bis"
:label="$p.t('global/bis')" :label="$p.t('global/bis')"
auto-apply auto-apply
@@ -470,6 +470,7 @@ export default {
:label="$p.t('admission', 'anmeldundRtAm')" :label="$p.t('admission', 'anmeldundRtAm')"
type="DatePicker" type="DatePicker"
v-model="formData.anmeldedatum" v-model="formData.anmeldedatum"
model-type="yyyy-MM-dd"
auto-apply auto-apply
:enable-time-picker="false" :enable-time-picker="false"
text-input text-input
@@ -293,6 +293,7 @@ export default {
:label="$p.t('person', 'geburtsdatum')" :label="$p.t('person', 'geburtsdatum')"
type="DatePicker" type="DatePicker"
v-model="data.gebdatum" v-model="data.gebdatum"
model-type="yyyy-MM-dd"
name="gebdatum" name="gebdatum"
:clearable="false" :clearable="false"
no-today no-today
@@ -103,6 +103,7 @@ export default {
<form-input <form-input
type="DatePicker" type="DatePicker"
v-model="formData.nachgereicht_am" v-model="formData.nachgereicht_am"
model-type="yyyy-MM-dd"
name="nachgereicht_am" name="nachgereicht_am"
:label="$p.t('dokumente/nachreichungAm')" :label="$p.t('dokumente/nachreichungAm')"
auto-apply auto-apply
@@ -27,7 +27,7 @@ export default {
return { return {
filter: false, filter: false,
studiengang_kz: false, studiengang_kz: false,
counterdate: new Date() counterdate: luxon.DateTime.now().setZone(FHC_JS_DATA_STORAGE_OBJECT.timezone).toISODate()
}; };
}, },
computed: { computed: {
@@ -259,6 +259,7 @@ export default {
<form-input <form-input
type="DatePicker" type="DatePicker"
v-model="counterdate" v-model="counterdate"
model-type="yyyy-MM-dd"
input-group input-group
:enable-time-picker="false" :enable-time-picker="false"
text-input text-input
@@ -79,6 +79,7 @@ export default {
<form-input <form-input
type="DatePicker" type="DatePicker"
v-model="data.buchungsdatum" v-model="data.buchungsdatum"
model-type="yyyy-MM-dd"
name="buchungsdatum" name="buchungsdatum"
:label="$p.t('konto/buchungsdatum')" :label="$p.t('konto/buchungsdatum')"
:enable-time-picker="false" :enable-time-picker="false"
@@ -88,7 +88,7 @@ export default {
this.data = { this.data = {
buchungstyp_kurzbz: '', buchungstyp_kurzbz: '',
betrag: '-0.00', betrag: '-0.00',
buchungsdatum: new Date(), buchungsdatum: luxon.DateTime.now().setZone(FHC_JS_DATA_STORAGE_OBJECT.timezone).toISODate(),
buchungstext: '', buchungstext: '',
mahnspanne: 30, mahnspanne: 30,
studiensemester_kurzbz: this.currentSemester, studiensemester_kurzbz: this.currentSemester,
@@ -154,6 +154,7 @@ export default {
<form-input <form-input
type="DatePicker" type="DatePicker"
v-model="data.buchungsdatum" v-model="data.buchungsdatum"
model-type="yyyy-MM-dd"
name="buchungsdatum" name="buchungsdatum"
:label="$p.t('konto/buchungsdatum')" :label="$p.t('konto/buchungsdatum')"
:enable-time-picker="false" :enable-time-picker="false"
@@ -467,6 +467,7 @@ export default {
:label="$p.t('ui', 'von')" :label="$p.t('ui', 'von')"
type="DatePicker" type="DatePicker"
v-model="formData.von" v-model="formData.von"
model-type="yyyy-MM-dd"
auto-apply auto-apply
:enable-time-picker="false" :enable-time-picker="false"
text-input text-input
@@ -501,6 +502,7 @@ export default {
:label="$p.t('global', 'bis')" :label="$p.t('global', 'bis')"
type="DatePicker" type="DatePicker"
v-model="formData.bis" v-model="formData.bis"
model-type="yyyy-MM-dd"
auto-apply auto-apply
:enable-time-picker="false" :enable-time-picker="false"
text-input text-input
@@ -325,6 +325,7 @@ export default {
:label="$p.t('infocenter', 'zgvDatum')" :label="$p.t('infocenter', 'zgvDatum')"
type="DatePicker" type="DatePicker"
v-model="data.zgvdatum" v-model="data.zgvdatum"
model-type="yyyy-MM-dd"
name="zgvdatum" name="zgvdatum"
no-today no-today
auto-apply auto-apply
@@ -389,6 +390,7 @@ export default {
:label="$p.t('lehre', 'zgvMasterDatum')" :label="$p.t('lehre', 'zgvMasterDatum')"
type="DatePicker" type="DatePicker"
v-model="data.zgvmadatum" v-model="data.zgvmadatum"
model-type="yyyy-MM-dd"
name="zgvmadatum" name="zgvmadatum"
no-today no-today
auto-apply auto-apply
@@ -454,6 +456,7 @@ export default {
:label="$p.t('lehre', 'zgvDoktorDatum')" :label="$p.t('lehre', 'zgvDoktorDatum')"
type="DatePicker" type="DatePicker"
v-model="data.zgvdoktordatum" v-model="data.zgvdoktordatum"
model-type="yyyy-MM-dd"
name="zgvdoktordatum" name="zgvdoktordatum"
no-today no-today
auto-apply auto-apply
@@ -276,6 +276,7 @@ export default{
container-class="mb-3" container-class="mb-3"
type="DatePicker" type="DatePicker"
v-model="formData.datum" v-model="formData.datum"
model-type="yyyy-MM-dd"
name="datum" name="datum"
:label="$p.t('global/datum')" :label="$p.t('global/datum')"
auto-apply auto-apply
@@ -291,6 +292,7 @@ export default{
container-class="mb-3" container-class="mb-3"
type="DatePicker" type="DatePicker"
v-model="formData.bestaetigtam" v-model="formData.bestaetigtam"
model-type="yyyy-MM-dd"
name="bestaetigtam" name="bestaetigtam"
:label="$p.t('lehre/bestaetigt_am')" :label="$p.t('lehre/bestaetigt_am')"
auto-apply auto-apply
@@ -306,13 +308,14 @@ export default{
container-class="mb-3" container-class="mb-3"
type="DatePicker" type="DatePicker"
v-model="formData.bewerbung_abgeschicktamum" v-model="formData.bewerbung_abgeschicktamum"
model-type="yyyy-MM-dd HH:mm:ss"
name="bewerbung_abgeschicktamum" name="bewerbung_abgeschicktamum"
:label="$p.t('lehre/bewerbung_abgeschickt_am')" :label="$p.t('lehre/bewerbung_abgeschickt_am')"
auto-apply auto-apply
:enable-time-picker="false" :enable-time-picker="true"
format="dd.MM.yyyy" format="dd.MM.yyyy HH:mm:ss"
text-input text-input
preview-format="dd.MM.yyyy" preview-format="dd.MM.yyyy HH:mm:ss"
:teleport="true" :teleport="true"
:disabled="bisLocked || !hasPrestudentstatusPermission" :disabled="bisLocked || !hasPrestudentstatusPermission"
> >
@@ -285,6 +285,7 @@ export default {
uid="stv-list-new-gebdatum" uid="stv-list-new-gebdatum"
name="gebdatum" name="gebdatum"
v-model="formDataPerson['gebdatum']" v-model="formDataPerson['gebdatum']"
model-type="yyyy-MM-dd"
:disabled="!!person" :disabled="!!person"
@update:model-value="loadSuggestions" @update:model-value="loadSuggestions"
text-input text-input
+17 -3
View File
@@ -4,6 +4,7 @@ import FormInput from '../Form/Input.js';
import ApiUdf from '../../api/udf.js'; import ApiUdf from '../../api/udf.js';
export default { export default {
name: 'CoreUdfCmpt',
components: { components: {
CoreFetchCmpt, CoreFetchCmpt,
FormInput FormInput
@@ -26,7 +27,8 @@ export default {
// The values as associative array // The values as associative array
modelValue: Object, modelValue: Object,
// Show only fields with a name that exists in the filter // Show only fields with a name that exists in the filter
filter: [String, Array] filter: [String, Array],
readonly: true
}, },
data() { data() {
return { return {
@@ -35,6 +37,13 @@ export default {
}; };
}, },
computed: { computed: {
isPkValid() {
// If the provided pk is _not_ valid
return !Object.keys(this.pk).every(key => !this.pk[key]);
},
getReadonly() {
return this.readonly;
},
filterArray() { filterArray() {
if (!this.filter || Array.isArray(this.filter)) if (!this.filter || Array.isArray(this.filter))
return this.filter; return this.filter;
@@ -61,6 +70,10 @@ export default {
}, },
watch: { watch: {
pk(n, o) { pk(n, o) {
// If the provided pk is _not_ valid
if (Object.keys(n).every(key => !n[key])) return;
if (!this.$refs.fetch) if (!this.$refs.fetch)
return; // NOTE(chris): no initial load yet return; // NOTE(chris): no initial load yet
@@ -124,6 +137,7 @@ export default {
template: ` template: `
<div class="core-udf row"> <div class="core-udf row">
<core-fetch-cmpt <core-fetch-cmpt
v-if="isPkValid"
ref="fetch" ref="fetch"
:api-function="loadF" :api-function="loadF"
:api-function-parameters="{ ciModel, pk }" :api-function-parameters="{ ciModel, pk }"
@@ -138,7 +152,7 @@ export default {
:type="field.type" :type="field.type"
:multiple="field.multiple" :multiple="field.multiple"
:title="field.description" :title="field.description"
:disabled="field.disabled" :disabled="field.disabled || getReadonly"
:clearable="field.clearable" :clearable="field.clearable"
:auto-apply="field.autoApply" :auto-apply="field.autoApply"
:enable-time-picker="field.enableTimePicker" :enable-time-picker="field.enableTimePicker"
@@ -152,4 +166,4 @@ export default {
</template> </template>
</core-fetch-cmpt> </core-fetch-cmpt>
</div>` </div>`
} }
+16 -8
View File
@@ -218,15 +218,23 @@ export const CoreFilterCmpt = {
}, },
columnsForFilter() { columnsForFilter() {
if (!this.filteredColumns || !this.datasetMetadata) return []; if (!this.filteredColumns || !this.datasetMetadata) return [];
const localizedColumnTitles = this.tabulator.getLang().columns;
const isTabulatorLocalized = !!this.$props.tabulatorOptions.locale; const isTabulatorLocalized = !!this.$props.tabulatorOptions.locale;
const filterTitles = this.filteredColumns.reduce((a, c) => {
a[c.field] = let filterTitles;
isTabulatorLocalized && localizedColumnTitles[c.field] if (isTabulatorLocalized) {
? localizedColumnTitles[c.field] const localizedColumnTitles = this.tabulator.getLang().columns;
: c.title; filterTitles = this.filteredColumns.reduce((a, c) => {
return a; a[c.field] = localizedColumnTitles[c.field];
}, {}); return a;
}, {});
} else {
filterTitles = this.filteredColumns.reduce((a, c) => {
a[c.field] = c.title;
return a;
}, {});
}
return this.datasetMetadata.map((el) => ({ return this.datasetMetadata.map((el) => ({
...el, ...el,
...{ title: filterTitles[el.name] }, ...{ title: filterTitles[el.name] },
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB