Merge remote-tracking branch 'origin/develop' into feature/465_email2sms

# Conflicts:
#	lam/HISTORY
This commit is contained in:
Roland Gruber 2025-09-17 17:15:41 +02:00
commit 7429b2f6e9
67 changed files with 284 additions and 337 deletions

View file

@ -112,11 +112,6 @@ if [ ! -f /var/lib/%{lam_dir}/config/config.cfg ]; then
cp /var/lib/%{lam_dir}/config/config.cfg.sample /var/lib/%{lam_dir}/config/config.cfg
chmod 600 /var/lib/%{lam_dir}/config/config.cfg
chown %{lam_uid}:%{lam_gid} /var/lib/%{lam_dir}/config/config.cfg
if [ ! -f /var/lib/%{lam_dir}/config/lam.conf ]; then
cp /var/lib/%{lam_dir}/config/unix.sample.conf /var/lib/%{lam_dir}/config/lam.conf
chmod 600 /var/lib/%{lam_dir}/config/lam.conf
chown %{lam_uid}:%{lam_gid} /var/lib/%{lam_dir}/config/lam.conf
fi
fi
for server in apache2 httpd nginx; do
if [ `which systemctl 2< /dev/null` ]; then

View file

@ -30,7 +30,7 @@ function minify {
for file in $files; do
jsFiles="$jsFiles $file"
done
uglifyjs -o $outFile $jsFiles
terser $jsFiles -o $outFile
rm $files
# add final new line to supress Debian warnings
echo "" >> $outFile

View file

@ -1,8 +1,8 @@
ldap-account-manager (9.3.RC1-1) unstable; urgency=medium
ldap-account-manager (9.3-1) unstable; urgency=medium
* new upstream release
-- Roland Gruber <post@rolandgruber.de> Mon, 01 Sep 2025 20:11:26 +0200
-- Roland Gruber <post@rolandgruber.de> Mon, 15 Sep 2025 07:11:26 +0200
ldap-account-manager (9.2-1) unstable; urgency=medium

View file

@ -3,7 +3,7 @@ Maintainer: Roland Gruber <post@rolandgruber.de>
Section: web
Priority: optional
Standards-Version: 4.7.2
Build-Depends: debhelper (>= 12), debhelper-compat (= 12), po-debconf, cleancss (>= 5.2), uglifyjs (>= 3.12)
Build-Depends: debhelper (>= 12), debhelper-compat (= 12), po-debconf, cleancss (>= 5.2), terser (>= 5.0)
Homepage: https://www.ldap-account-manager.org/
Rules-Requires-Root: binary-targets

View file

@ -8,7 +8,7 @@ if [ ! -e $outFile ]; then
for file in $files; do
jsFiles="$jsFiles $file"
done
uglifyjs -o $outFile $jsFiles
terser $jsFiles -o $outFile
rm $files
# add final new line to supress Debian warnings
echo "" >> $outFile

View file

@ -29,7 +29,7 @@
FROM debian:bookworm-slim
LABEL maintainer="Roland Gruber <post@rolandgruber.de>"
ARG LAM_RELEASE=9.3.RC1
ARG LAM_RELEASE=9.3
EXPOSE 80
ENV \

View file

@ -3,7 +3,7 @@ services:
ldap-account-manager:
build:
context: .
image: ldapaccountmanager/lam:9.3.RC1
image: ldapaccountmanager/lam:9.3
restart: unless-stopped
ports:
- "8080:80"

View file

@ -3,7 +3,7 @@ December 2025 9.4
-> SMS sending can be done with email2SMS providers (465)
September 2025 9.3
16.09.2025 9.3
- New translation: Greek
- Tree view: added comparison feature (440)
- Windows: added logon hours (457)

View file

@ -1 +1 @@
9.3.RC1
9.3

View file

@ -465,7 +465,7 @@ function search_domains($server = null, $suffix = null) {
$server = $_SESSION['ldap']->server();
}
$filter = '(objectclass=sambaDomain)';
$units = searchLDAPPaged($server, $suffix, $filter, $attr, false, 0);
$units = searchLDAPPaged($server, $suffix, $filter, $attr, 0, 0);
// extract attributes
for ($i = 0; $i < count($units); $i++) {
$ret[$i] = new samba3domain();
@ -754,9 +754,9 @@ function connectToLDAP($serverURL, $startTLS) {
/**
* This will search the given LDAP suffix for all entries which have the given attribute.
*
* @param string $name attribute name (may be null)
* @param string $value attribute value
* @param string|null $objectClass object class (may be null)
* @param string|null $name attribute name
* @param string|null $value attribute value (may be null if $name is null)
* @param string|null $objectClass object class
* @param array $attributes list of attributes to return
* @param array $scopes account types
* @return array list of found entries
@ -766,7 +766,7 @@ function searchLDAPByAttribute($name, $value, $objectClass, $attributes, $scopes
// build filter
$filter = '';
$filterParts = [];
if ($name != null) {
if ($name !== null) {
$filterParts[] = '(' . $name . '=' . ldap_escape($value, '*', LDAP_ESCAPE_FILTER) . ')';
}
if ($objectClass !== null) {
@ -878,7 +878,7 @@ function getLDAPServerHandle() {
* @param String $dn DN
* @param String $filter filter
* @param array $attributes attribute list
* @param boolean $attrsOnly return only attribute names
* @param int $attrsOnly return only attribute names (1) or also the values (0)
* @param int $limit size limit
* @return array results
*/
@ -1732,7 +1732,7 @@ class moduleCache {
*
* @return int random number
*/
function getRandomNumber() {
function getRandomNumber(): int {
return abs(hexdec(bin2hex(openssl_random_pseudo_bytes(6))));
}
@ -2110,14 +2110,14 @@ function isDeveloperVersion($version): bool {
*/
class LAMException extends Exception {
private $title;
private ?string $title;
private $ldapErrorCode;
/**
* Constructor.
*
* @param string $title title
* @param string|null $title title
* @param string $message message (optional)
* @param Exception|null $cause (optional)
* @param int|null $ldapErrorCode original LDAP error code
@ -2131,16 +2131,16 @@ class LAMException extends Exception {
/**
* Returns the message title.
*
* @return string title
* @return string|null title
*/
public function getTitle() {
public function getTitle(): ?string {
return $this->title;
}
/**
* Returns the original LDAP error code.
*
* @return int error code
* @return int|null error code
*/
public function getLdapErrorCode() {
return $this->ldapErrorCode;

View file

@ -1,5 +1,6 @@
<?php
use LAM\JOB\Job;
use LAM\PDF\PDFEntry;
use LAM\PDF\PDFLabelValue;
use LAM\PDF\PDFTable;
@ -1013,7 +1014,7 @@ abstract class baseModule {
* @param array $rawAccounts the user input data, contains one subarray for each account.
* @param array $ids list of IDs for column position (e.g. "posixAccount_uid" => 5)
* @param array $partialAccounts list of hash arrays (name => value) which are later added to LDAP
* @param String $position current position in CSV
* @param int $position current position in CSV
* @param String $colName column name
* @param String $attrName LDAP attribute name
* @param String|String[] $regex for get_preg() (e.g. 'ascii')
@ -1444,7 +1445,7 @@ abstract class baseModule {
* @param string $attrName attribute name
* @param string|null $label label name
* @param boolean $required this is a required field (default false)
* @param integer $length field length
* @param int|null $length field length
* @param boolean $isTextArea show as text area (default false)
* @param array $autoCompleteValues values for auto-completion
* @param integer $fieldSize field size
@ -1771,7 +1772,7 @@ abstract class baseModule {
$field->setFieldSize(null);
}
elseif ($isTextArea && !in_array($name, $readOnlyFields)) {
$field = new htmlInputTextarea(static::class . '_' . $name, $value, null, null);
$field = new htmlInputTextarea(static::class . '_' . $name, $value, 100, 3);
}
elseif (!$isTextArea) {
$field = new htmlOutputText($value);
@ -1920,7 +1921,7 @@ abstract class baseModule {
* @param array $container return value of checkSelfServiceOptions()
* @param String $name attribute name
* @param array $attributes LDAP attributes
* @param string $fields input fields
* @param string[] $fields input fields
* @param array $readOnlyFields list of read-only fields
* @param String $validationID validation ID for get_preg()
* @param array $validationMessage validation message data (defaults to $this->messages[$name][0])
@ -2322,6 +2323,7 @@ abstract class baseModule {
* Returns a list of jobs that can be run.
*
* @param LAMConfig $config configuration
* @return Job[] jobs
*/
public function getSupportedJobs(&$config) {
return [];

View file

@ -1870,7 +1870,7 @@ class LAMConfig {
* Returns an array of all selected account modules
*
* @param string $scope account type
* @return array user modules
* @return class-string<baseModule>[] user modules
*/
public function get_AccountModules($scope) {
if (isset($this->typeSettings["modules_" . $scope])) {
@ -2322,7 +2322,7 @@ class LAMConfig {
/**
* Returns the port.
*
* @return String port
* @return int|null port
*/
public function getJobsDBPort() {
return $this->jobsDBPort;
@ -2331,7 +2331,7 @@ class LAMConfig {
/**
* Sets the port.
*
* @param int $jobsDBPort port
* @param int|null $jobsDBPort port
*/
public function setJobsDBPort($jobsDBPort) {
$this->jobsDBPort = $jobsDBPort;
@ -3190,7 +3190,7 @@ class LAMCfgMain {
@chmod($fileName, 0600);
}
else {
throw new LAMException(printf(_('Unable to write file %s.'), $fileName));
throw new LAMException(sprintf(_('Unable to write file %s.'), $fileName));
}
}
@ -3268,11 +3268,11 @@ class LAMCfgMain {
}
catch (PDOException $e) {
syslog(LOG_ERR, 'Unable to read main config: ' . $e->getMessage());
throw new LAMException(_('Unable to connect to configuration database.'), null, $e);
throw new LAMException(_('Unable to connect to configuration database.'), '', $e);
}
catch (LAMException $e) {
syslog(LOG_ERR, 'Unable to import main config: ' . $e->getMessage());
throw new LAMException(_('Unable to connect to configuration database.'), null, $e);
throw new LAMException(_('Unable to connect to configuration database.'), '', $e);
}
}

View file

@ -140,10 +140,10 @@ class CronRunner {
$pdo = $cronDatabase->getPdo();
}
catch (PDOException $e) {
throw new LAMException("Unable to connect to database. " . $e->getMessage(), null, $e);
throw new LAMException("Unable to connect to database. " . $e->getMessage(), '', $e);
}
catch (LAMException $e) {
throw new LAMException("Unable to connect to database. " . $e->getTitle(), null, $e);
throw new LAMException("Unable to connect to database. " . $e->getTitle(), '', $e);
}
// get jobs to run
if (empty($cronDatabase->getJobs())) {

View file

@ -84,7 +84,7 @@ abstract class htmlElement {
/**
* Prints the HTML code for this element.
*
* @param string $module Name of account module
* @param string|null $module Name of account module
* @param array $input List of meta-HTML elements
* @param array $values List of values which override the defaults in $input (name => value)
* @param boolean $restricted If true then no buttons will be displayed
@ -1286,7 +1286,7 @@ class htmlSelect extends htmlElement {
if ($selectedElements != null) {
$this->selectedElements = $selectedElements;
}
$this->size = htmlspecialchars($size);
$this->size = htmlspecialchars((string) $size);
}
/**
@ -2374,8 +2374,8 @@ class htmlInputTextarea extends htmlElement {
function __construct($name, $value, $colCount, $rowCount) {
$this->name = htmlspecialchars($name);
$this->value = htmlspecialchars($value);
$this->colCount = htmlspecialchars($colCount);
$this->rowCount = htmlspecialchars($rowCount);
$this->colCount = htmlspecialchars((string) $colCount);
$this->rowCount = htmlspecialchars((string) $rowCount);
}
/**
@ -2840,14 +2840,7 @@ class htmlStatusMessage extends htmlElement {
}
/**
* Prints the HTML code for this element.
*
* @param string $module Name of account module
* @param array $input List of meta-HTML elements
* @param array $values List of values which override the defaults in $input (name => value)
* @param boolean $restricted If true then no buttons will be displayed
* @param string $scope Account type
* @return array List of input field names and their type (name => type)
* {@inheritDoc}
*/
public function generateHTML($module, $input, $values, $restricted, $scope) {
if (!empty($this->cssClasses)) {
@ -4907,7 +4900,7 @@ class htmlProgressbar extends htmlElement {
*/
function __construct(string $id = null, int $progress = 0) {
$this->id = htmlspecialchars($id);
$this->progress = htmlspecialchars($progress);
$this->progress = htmlspecialchars((string) $progress);
}
/**

View file

@ -174,7 +174,7 @@ class ImageManipulatorImagick implements ImageManipulator {
* @see \LAM\ImageUtils\ImageManipulator::crop()
*/
public function crop($x, $y, $width, $height) {
$this->image->cropimage(round($width), round($height), round($x), round($y));
$this->image->cropimage((int) round($width), (int) round($height), (int) round($x), (int) round($y));
}
/**

View file

@ -347,7 +347,7 @@ class Importer {
* Returns a task for LDIF changetype entry.
*
* @param string $dn DN
* @param string $lines lines
* @param string[] $lines lines
* @return ImporterTask task
*/
private function getChangeTypeTask($dn, $lines) {
@ -496,7 +496,7 @@ class RenameEntryTask implements ImporterTask {
*/
public function run() {
$ldap = $_SESSION['ldap']->server();
$success = @ldap_rename($ldap, $this->dn, $this->newRdn, null, $this->deleteOldRdn);
$success = @ldap_rename($ldap, $this->dn, $this->newRdn, '', $this->deleteOldRdn);
if ($success) {
return Importer::formatMessage('INFO', _('Rename successful!'), htmlspecialchars($this->dn));
}

View file

@ -7,7 +7,7 @@ use TCPDF;
/*
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2017 - 2024 Roland Gruber
Copyright (C) 2017 - 2025 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -80,7 +80,7 @@ class LAMTCPDF extends TCPDF {
if (!empty($logoBinary)) {
$imageConverter = ImageManipulationFactory::getImageManipulator($logoBinary);
$imageConverter->convertToJpeg();
$this->Image('@' . $imageConverter->getImageData(), 10, 10, '', 15, 'JPG', '', 'T', false, 300, '', false, false, 0, false, false, false);
$this->Image('@' . $imageConverter->getImageData(), 10, 10, 0, 15, 'JPG', '', 'T');
}
else {
logNewMessage(LOG_ERR, 'Unable to read PDF logo ' . $logoFile);
@ -91,7 +91,7 @@ class LAMTCPDF extends TCPDF {
$this->SetY(10);
}
$this->SetFont($this->fontName, '', 20);
$this->Cell(0, 15, $this->structure->getTitle(), 0, true, 'R', 0, '', 0, false, 'M', 'M');
$this->Cell(0, 15, $this->structure->getTitle(), 0, 1, 'R', false, '', 0, false, 'M');
//set folding marks
if ($this->structure->getFoldingMarks() == PDFStructure::FOLDING_STANDARD) {
$this->SetLineWidth(0.2);
@ -110,7 +110,7 @@ class LAMTCPDF extends TCPDF {
$this->SetY(-15);
$this->SetFont($this->fontName, '', LAMPDF_FONT_SIZE);
$footerText = _("This document was automatically created by LDAP Account Manager") . ' (' . getFormattedTime('Y-m-d H:i:s T') . ')';
$this->Cell(0, 10, $footerText, 0, false, 'C', 0, '', 0, false, 'T', 'M');
$this->Cell(0, 10, $footerText, 0, 0, 'C');
}
}

View file

@ -2,7 +2,7 @@
/*
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2024 Roland Gruber
Copyright (C) 2003 - 2025 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -102,7 +102,7 @@ class Ldap {
if ($errorNumber == 81) {
// connection failed
logNewMessage(LOG_ERR, 'User ' . $user . ' (' . $clientSource . ') failed to log in (LDAP error: ' . getDefaultLDAPErrorString($this->server) . ').');
throw new LAMException(_("Cannot connect to specified LDAP server. Please try again."), null, null, $errorNumber);
throw new LAMException(_("Cannot connect to specified LDAP server. Please try again."), '', null, $errorNumber);
}
elseif ($errorNumber == 49) {
// username/password invalid. Return to login page.

View file

@ -351,7 +351,7 @@ class lamList {
$link->setCSSClasses(['icon']);
$navGroup->addElement($link);
}
$pageCount = ceil($count / $this->maxPageEntries);
$pageCount = (int) ceil($count / $this->maxPageEntries);
for ($i = $this->page - 6; $i < ($this->page + 5); $i++) {
if ($i >= $pageCount) {
break;
@ -362,7 +362,7 @@ class lamList {
if ($i == $this->page - 1) {
$url = "list.php?type=" . $this->type->getId() . "&norefresh=true" .
"&sort=" . $this->sortColumn . "&sortdirection=" . $this->sortDirection . $filter;
$navInput = new htmlInputField('listNavPage', ($i + 1));
$navInput = new htmlInputField('listNavPage', (string) ($i + 1));
$navInput->setMinimumAndMaximumNumber(1, $pageCount);
$navInput->setCSSClasses(['listPageInput']);
$navInput->setOnKeyPress('listPageNumberKeyPress(\'' . $url . '\', event);');
@ -372,7 +372,7 @@ class lamList {
else {
$linkHref = "list.php?type=" . $this->type->getId() . "&norefresh=true&page=" . ($i + 1) .
"&sort=" . $this->sortColumn . "&sortdirection=" . $this->sortDirection . $filter;
$link = new htmlLink(($i + 1), $linkHref);
$link = new htmlLink((string) ($i + 1), $linkHref);
$navGroup->addElement($link);
}
}
@ -1046,7 +1046,7 @@ class lamList {
* Can be used by subclasses to add e.g. additional buttons to the top area.
*
* @param htmlGroup $left left part
* @param htmlGroup $right right part
* @param htmlResponsiveRow $right right part
*/
protected function addExtraInputElementsToTopArea(&$left, &$right) {
// only used by subclasses
@ -1656,7 +1656,7 @@ abstract class lamListOption {
/**
* Returns the option value. The value must not contain "=" and ";".
*
* @return String value
* @return string value
*/
public function getValue() {
return $this->value;
@ -1665,7 +1665,7 @@ abstract class lamListOption {
/**
* Sets the config option value. The value must not contain "=" and ";".
*
* @param String $value
* @param string $value
*/
public function setValue($value) {
if ((strpos($value, '=') > -1) || (strpos($value, ';') > -1)) {
@ -1783,7 +1783,7 @@ class lamSelectListOption extends lamListOption {
$this->setValue($_POST[$this->getID()]);
}
else {
$this->setValue(null);
$this->setValue('');
}
}

View file

@ -682,7 +682,7 @@ function parseHtml($module, $input, $values, $restricted, $scope) {
return [];
}
if ($input instanceof htmlElement) {
return $input->generateHTML($module, $input, $values, $restricted, $scope);
return $input->generateHTML($module, [$input], $values, $restricted, $scope);
}
if ($input !== []) {
$return = [];

View file

@ -323,7 +323,7 @@ class asteriskExtension extends baseModule {
for ($i = 0; $i < count($entries); $i++) {
$this->render_extension($entries[$i], $i, $renderContainer);
$renderContainer->addLabel(new htmlButton("delete_rule_" . $i, _('Delete rule')), false);
$renderContainer->addLabel(new htmlButton("delete_rule_" . $i, _('Delete rule')));
$upDownButtons = new htmlTable();
if ($i > 0) {
@ -333,7 +333,7 @@ class asteriskExtension extends baseModule {
((count($entries) > 1) || ($this->addRuleFlag))) {
$upDownButtons->addElement(new htmlButton('rule_down_button_' . $i, 'down.svg', true));
}
$renderContainer->addField($upDownButtons, true);
$renderContainer->addField($upDownButtons);
$renderContainer->addVerticalSpacer('2rem');
}
@ -342,21 +342,20 @@ class asteriskExtension extends baseModule {
if ($this->addRuleFlag || count($entries) == 0) {
$this->render_extension(null, count($entries), $renderContainer);
$this->render_extension([], count($entries), $renderContainer);
if ($this->addRuleFlag) {
$upDownButtons = new htmlTable();
$renderContainer->addLabel(new htmlButton("delete_rule_" . $i, _('Delete rule')), false);
$renderContainer->addLabel(new htmlButton("delete_rule_" . $i, _('Delete rule')));
$upDownButtons->addElement(new htmlButton('rule_up_button_' . $i, 'up.svg', true));
$renderContainer->addField($upDownButtons, true);
$renderContainer->addField($upDownButtons);
}
$displayEntrNum++;
$this->addRuleFlag = false;
}
// the size of found rows plus 1 for new one
$hidenInput = new htmlHiddenInput("extension_rows", $displayEntrNum);
$renderContainer->add($hidenInput);
// the size of found rows plus 1 for the new one
$renderContainer->add(new htmlHiddenInput("extension_rows", (string) $displayEntrNum));
$renderContainer->add(new htmlButton("add_rule", _('Add another rule')));
}

View file

@ -273,12 +273,12 @@ class courierMailAccount extends baseModule {
$unitIndex = 2;
$value = 0;
if (isset($this->attributes['quota'][0]) && (strlen($this->attributes['quota'][0]) > 0)) {
$unitIndex = floor(log(substr($this->attributes['quota'][0], 0, -1), 1000));
$unitIndex = floor(log((float) substr($this->attributes['quota'][0], 0, -1), 1000));
$value = round((float) (substr($this->attributes['quota'][0], 0, -1)) / (1000 ** $unitIndex), 2);
}
$return->addLabel(new htmlOutputText(_('Mailbox quota')));
$tempTable = new htmlTable();
$boxInput = new htmlInputField('quotaValue', $value);
$boxInput = new htmlInputField('quotaValue', (string) $value);
$boxInput->setFieldSize(5);
$boxInput->setFieldMaxLength(5);
$tempTable->addElement($boxInput);
@ -473,7 +473,7 @@ class courierMailAccount extends baseModule {
$unitIndex = 2;
$value = 0;
if (isset($this->attributes['quota'][0]) && (strlen($this->attributes['quota'][0]) > 0)) {
$unitIndex = floor(log(substr($this->attributes['quota'][0], 0, -1), 1000));
$unitIndex = floor(log((float) substr($this->attributes['quota'][0], 0, -1), 1000));
$value = round((float) (substr($this->attributes['quota'][0], 0, -1)) / (1000 ** $unitIndex), 2);
}
$units = [

View file

@ -256,7 +256,7 @@ By default, the nodes are configured as H-Nodes which fits for small networks. I
$profileContainer->add(new htmlResponsiveInputField(_('Default gateway'), self::ROUTERS, null, 'gateway'));
$profileContainer->add(new htmlResponsiveInputField(_('Netbios name servers'), 'netbios', null, 'netbios'));
$nodeList = array_flip($this->all_netbios_node_types);
$profileNodeSelect = new htmlResponsiveSelect('netbios_node_type', $nodeList, null, _('Netbios node type'), 'netbios_type');
$profileNodeSelect = new htmlResponsiveSelect('netbios_node_type', $nodeList, [], _('Netbios node type'), 'netbios_type');
$profileNodeSelect->setHasDescriptiveElements(true);
$profileContainer->add($profileNodeSelect);
$profileContainer->add(new htmlResponsiveInputField(_('Subnet mask'), 'subnet', null, 'subnetmask'));
@ -580,7 +580,7 @@ By default, the nodes are configured as H-Nodes which fits for small networks. I
$parts = explode('.', $mask);
$bits = '';
for ($i = 0; $i < count($parts); $i++) {
$bits .= decbin($parts[$i]);
$bits .= decbin((int) $parts[$i]);
}
return preg_match('/^1*0*$/', $bits);
}
@ -595,8 +595,8 @@ By default, the nodes are configured as H-Nodes which fits for small networks. I
$ex = explode(".", $subnet);
$num = 0;
foreach ($ex as $mask) {
$binary = decbin($mask);
$num += substr_count($binary, 1);
$binary = decbin((int) $mask);
$num += substr_count($binary, '1');
}
return $num;
}
@ -729,8 +729,8 @@ By default, the nodes are configured as H-Nodes which fits for small networks. I
$ex = explode(".", $profile['subnet'][0]);
$num = 0;
foreach ($ex as $mask) {
$binary = decbin($mask);
$num += substr_count($binary, 1);
$binary = decbin((int) $mask);
$num += substr_count($binary, '1');
}
$this->attributes['dhcpNetMask'][0] = $num;
}

View file

@ -762,10 +762,7 @@ class freeRadius extends baseModule {
}
/**
* Returns a list of jobs that can be run.
*
* @param LAMConfig $config configuration
* @return array list of jobs
* {@inheritDoc}
*/
public function getSupportedJobs(&$config) {
return [
@ -835,15 +832,7 @@ if (interface_exists('\LAM\JOB\Job', false)) {
}
/**
* Checks if a user is expired.
*
* @param integer $jobID job ID
* @param array $options job settings
* @param PDO $pdo PDO
* @param DateTime $now current time
* @param array $policyOptions list of policy options by getPolicyOptions()
* @param array $user user attributes
* @param boolean $isDryRun just do a dry run, nothing is modified
* {@inheritDoc}
*/
protected function checkSingleUser($jobID, $options, &$pdo, $now, $policyOptions, $user, $isDryRun) {
$expireTime = DateTime::createFromFormat('d M Y H:i', $user['radiusexpiration'][0], new DateTimeZone('UTC'));

View file

@ -326,7 +326,7 @@ class imapAccess extends baseModule {
if (isset($quota_values[self::QUOTA_USAGE])) {
$quotaLimit = $quota_values[self::QUOTA_LIMIT];
$container->addLabel(new htmlOutputText(_("Current usage (kB)")));
$container->addField(new htmlOutputText($quota_values[self::QUOTA_USAGE]), true);
$container->addField(new htmlOutputText($quota_values[self::QUOTA_USAGE]));
$quotaLimitInput = new htmlResponsiveInputField(_("Quota limit (kB)"), 'ImapUserQuotaLimit', $quotaLimit, 'ImapUserQuotaLimit');
$container->add($quotaLimitInput);
$container->addVerticalSpacer('0.5rem');

View file

@ -962,7 +962,7 @@ class inetOrgPerson extends baseModule implements passwordService, AccountStatus
private function setExopPassword($settings) {
if (!empty($this->clearTextPassword) && !empty($settings['posixAccount_pwdHash'][0])
&& ($settings['posixAccount_pwdHash'][0] === 'LDAP_EXOP')) {
$success = ldap_exop_passwd($_SESSION['ldap']->server(), $this->getAccountContainer()->finalDN, null, $this->clearTextPassword);
$success = ldap_exop_passwd($_SESSION['ldap']->server(), $this->getAccountContainer()->finalDN, '', $this->clearTextPassword);
if (!$success) {
return [['ERROR', _('Unable to set password'), getExtendedLDAPErrorMessage($_SESSION['ldap']->server())]];
}
@ -1541,7 +1541,7 @@ class inetOrgPerson extends baseModule implements passwordService, AccountStatus
if (isset($this->attributes['userCertificate;binary'])) {
$userCertificateCount = count($this->attributes['userCertificate;binary']);
}
$userCertificateGroup->addElement(new htmlOutputText($userCertificateCount));
$userCertificateGroup->addElement(new htmlOutputText((string) $userCertificateCount));
$userCertificateGroup->addElement(new htmlSpacer('10px', null));
if (!$this->isAdminReadOnly('manager')) {
$userCertificateGroup->addElement(new htmlAccountPageButton(static::class, 'userCertificate', 'manage', _('Manage')));
@ -2409,20 +2409,25 @@ class inetOrgPerson extends baseModule implements passwordService, AccountStatus
// display name
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_displayName', 'displayName');
// description
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_description', 'description', null, null, $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_description',
'description', null, [], $errors, '/;[ ]*/');
// title
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_title', 'title', 'title', $this->messages['title'][1], $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_title',
'title', 'title', $this->messages['title'][1], $errors, '/;[ ]*/');
// employee number
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_employeeNumber', 'employeeNumber');
// employee type
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_type', 'employeeType',
'employeeType', $this->messages['employeeType'][1], $errors);
// business category
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_businessCategory', 'businessCategory', 'businessCategory', $this->messages['businessCategory'][1], $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_businessCategory',
'businessCategory', 'businessCategory', $this->messages['businessCategory'][1], $errors, '/;[ ]*/');
// manager
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_manager', 'manager', 'dn', $this->messages['manager'][0], $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_manager',
'manager', 'dn', $this->messages['manager'][0], $errors, '/;[ ]*/');
// street
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_street', 'street', 'street', $this->messages['street'][1], $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'inetOrgPerson_street',
'street', 'street', $this->messages['street'][1], $errors, '/;[ ]*/');
// post office box
if (isset($ids['inetOrgPerson_postOfficeBox']) && ($rawAccounts[$i][$ids['inetOrgPerson_postOfficeBox']] != "")) {
$partialAccounts[$i]['postOfficeBox'] = preg_split('/;[ ]*/', $rawAccounts[$i][$ids['inetOrgPerson_postOfficeBox']]);
@ -2617,7 +2622,7 @@ class inetOrgPerson extends baseModule implements passwordService, AccountStatus
&& !empty($data[$temp['counter']][$ids['inetOrgPerson_userPassword']])) {
$dn = $accounts[$temp['counter']]['dn'];
$password = $data[$temp['counter']][$ids['inetOrgPerson_userPassword']];
$success = ldap_exop_passwd($_SESSION['ldap']->server(), $dn, null, $password);
$success = ldap_exop_passwd($_SESSION['ldap']->server(), $dn, '', $password);
if (!$success) {
$errors[] = [
"ERROR",
@ -2802,7 +2807,7 @@ class inetOrgPerson extends baseModule implements passwordService, AccountStatus
else {
$filter = '(|(objectClass=organizationalunit)(objectClass=country)(objectClass=organization)(objectClass=krbRealmContainer)(objectClass=container))';
$suffix = $_SESSION['selfServiceProfile']->LDAPSuffix;
$foundOs = searchLDAPPaged($_SESSION['ldapHandle']->getServer(), $suffix, $filter, ['dn'], false, 0);
$foundOs = searchLDAPPaged($_SESSION['ldapHandle']->getServer(), $suffix, $filter, ['dn'], 0, 0);
$oList = [];
foreach ($foundOs as $foundO) {
$oList[] = $foundO['dn'];
@ -2840,7 +2845,7 @@ class inetOrgPerson extends baseModule implements passwordService, AccountStatus
else {
$filter = '(|(objectClass=organizationalunit)(objectClass=country)(objectClass=organization)(objectClass=krbRealmContainer)(objectClass=container))';
$suffix = $_SESSION['selfServiceProfile']->LDAPSuffix;
$foundOus = searchLDAPPaged($_SESSION['ldapHandle']->getServer(), $suffix, $filter, ['dn'], false, 0);
$foundOus = searchLDAPPaged($_SESSION['ldapHandle']->getServer(), $suffix, $filter, ['dn'], 0, 0);
$ouList = [];
foreach ($foundOus as $foundOu) {
$ouList[] = $foundOu['dn'];

View file

@ -180,7 +180,8 @@ class ldapPublicKey extends baseModule {
function display_html_attributes() {
$return = new htmlResponsiveRow();
if (!$this->hasObjectClass() || in_array_ignore_case($this->getObjectClass(), $this->attributes['objectClass'])) {
$this->addMultiValueInputTextField($return, $this->getAttributeName(), _('SSH public key'), false, '16384', false, null, '50');
$this->addMultiValueInputTextField($return, $this->getAttributeName(), _('SSH public key'),
false, 16384, false, null, 50);
// file upload
$return->addVerticalSpacer('2rem');
$return->addLabel(new htmlOutputText(_('Upload a file')));
@ -317,7 +318,8 @@ class ldapPublicKey extends baseModule {
$partialAccounts[$i]['objectClass'][] = $this->getObjectClass();
}
// add keys
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, static::class . '_sshPublicKey', $this->getAttributeName(), null, null, $messages, '/,[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, static::class . '_sshPublicKey',
$this->getAttributeName(), null, [], $messages, '/,[ ]*/');
}
return $messages;
}

View file

@ -224,7 +224,7 @@ class nisMailAlias extends baseModule {
$newGroup->addElement(new htmlAccountPageButton(static::class, 'selectUser', 'recipientNew', 'user.svg', true, _('Select user')));
$newGroup->addElement(new htmlButton('addRec', 'add.svg', true));
$newGroup->addElement(new htmlHelpLink('recipient'));
$newGroup->addElement(new htmlHiddenInput('rec_number', $recipientCount));
$newGroup->addElement(new htmlHiddenInput('rec_number', (string) $recipientCount));
$return->addField($newGroup);
}
return $return;

View file

@ -120,7 +120,7 @@ class nisNetGroupHost extends nisNetGroupUser {
$filterGroup = new htmlGroup();
$filterGroup->addElement(new htmlOutputText(_('Filter') . ' '));
$filter = new htmlInputField('group_filter');
$filter->setFieldSize('5em');
$filter->setFieldSize(5);
$filter->filterSelectBox('group_add');
$filterGroup->addElement($filter);
$return->addElement($filterGroup, true);

View file

@ -204,7 +204,7 @@ class nisNetGroupUser extends baseModule {
$filterGroup = new htmlGroup();
$filterGroup->addElement(new htmlOutputText(_('Filter') . ' '));
$filter = new htmlInputField('group_filter');
$filter->setFieldSize('5em');
$filter->setFieldSize(5);
$filter->filterSelectBox('group_add');
$filterGroup->addElement($filter);
$return->addElement($filterGroup, true);

View file

@ -522,7 +522,8 @@ class nisnetgroup extends baseModule {
}
}
// members
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'nisnetgroup_members', 'nisNetgroupTriple', null, null, $messages, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'nisnetgroup_members',
'nisNetgroupTriple', null, [], $messages, '/;[ ]*/');
}
return $messages;
}

View file

@ -1026,7 +1026,7 @@ class posixAccount extends baseModule implements passwordService, AccountStatusP
private function setExopPassword($settings) {
if (!empty($this->clearTextPassword) && !empty($settings['posixAccount_pwdHash'][0])
&& ($settings['posixAccount_pwdHash'][0] === 'LDAP_EXOP')) {
$success = ldap_exop_passwd($_SESSION['ldap']->server(), $this->getAccountContainer()->finalDN, null, $this->clearTextPassword);
$success = ldap_exop_passwd($_SESSION['ldap']->server(), $this->getAccountContainer()->finalDN, '', $this->clearTextPassword);
if (!$success) {
return [['ERROR', _('Unable to set password'), getExtendedLDAPErrorMessage($_SESSION['ldap']->server())]];
}
@ -2120,7 +2120,7 @@ class posixAccount extends baseModule implements passwordService, AccountStatusP
if ($returnValue === 'ok') {
$return->addLabel(new htmlOutputText($label));
$okGroup = new htmlGroup();
$okGroup->addElement(new htmlImage('../../graphics/pass.svg', 16, 16));
$okGroup->addElement(new htmlImage('../../graphics/pass.svg', '16', '16'));
$okGroup->addElement(new htmlSpacer('5px', null));
$okGroup->addElement(new htmlAccountPageButton(static::class, 'homedir', 'delete_' . $i, _('Delete')));
$return->addField($okGroup);
@ -2128,7 +2128,7 @@ class posixAccount extends baseModule implements passwordService, AccountStatusP
elseif ($returnValue === 'missing') {
$return->addLabel(new htmlOutputText($label));
$failGroup = new htmlGroup();
$failGroup->addElement(new htmlImage('../../graphics/del.svg', 16, 16));
$failGroup->addElement(new htmlImage('../../graphics/del.svg', '16', '16'));
$failGroup->addElement(new htmlSpacer('5px', null));
$failGroup->addElement(new htmlAccountPageButton(static::class, 'homedir', 'create_' . $i, _('Create')));
$return->addField($failGroup);
@ -2507,7 +2507,7 @@ class posixAccount extends baseModule implements passwordService, AccountStatusP
$hiddenOptionsContainerHead = new htmlGroup();
$hiddenOptionsContainerHead->addElement(new htmlOutputText(_('Hidden options')));
$hiddenOptionsContainerHead->addElement(new htmlHelpLink('hiddenOptions'));
$configHostContainer->addLabel($hiddenOptionsContainerHead, 12);
$configHostContainer->addLabel($hiddenOptionsContainerHead);
$configHostContainer->addField(new htmlOutputText(''));
$configHostContainer->addVerticalSpacer('0.5rem');
$configHostContainer->add(new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_hidegecos', false, _('Gecos'), null, false));
@ -3112,7 +3112,7 @@ class posixAccount extends baseModule implements passwordService, AccountStatusP
$temp['counter']++;
return [
'status' => 'inProgress',
'progress' => ($temp['counter'] * 100) / (count($temp['groups'] + count($temp['createHomes']) + count($temp['dn_gon']) + count($temp['exop']))),
'progress' => ($temp['counter'] * 100) / (count($temp['groups']) + count($temp['createHomes']) + count($temp['dn_gon']) + count($temp['exop'])),
'errors' => [['ERROR', _('Unable to find group in LDAP.'), $temp['groups'][$temp['counter']]]]
];
}
@ -3185,7 +3185,7 @@ class posixAccount extends baseModule implements passwordService, AccountStatusP
$data = $temp['exop'][$temp['counter'] - count($temp['groups']) - count($temp['createHomes']) - count($temp['dn_gon'])];
$dn = $data[0];
$password = $data[1];
$success = ldap_exop_passwd($_SESSION['ldap']->server(), $dn, null, $password);
$success = ldap_exop_passwd($_SESSION['ldap']->server(), $dn, '', $password);
$errors = [];
if (!$success) {
$errors[] = [
@ -3535,7 +3535,7 @@ class posixAccount extends baseModule implements passwordService, AccountStatusP
&& ($attributes['INFO.userPasswordModify'][0] === 'exop')) {
$password = $attributes['INFO.userPasswordClearText'][0];
$dn = $attributes['dn'][0];
$success = ldap_exop_passwd($_SESSION['ldapHandle']->getServer(), $dn, null, $password);
$success = ldap_exop_passwd($_SESSION['ldapHandle']->getServer(), $dn, '', $password);
if (!$success) {
StatusMessage('ERROR', _('Unable to set password'), getExtendedLDAPErrorMessage($_SESSION['ldapHandle']->getServer()));
}

View file

@ -127,7 +127,8 @@ class posixGroup extends baseModule implements passwordService {
$partialAccounts[$i]['description'] = $partialAccounts[$i]['cn'];
}
else {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'posixGroup_description', 'description', null, null, $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'posixGroup_description',
'description', null, [], $errors, '/;[ ]*/');
}
}
// group members

View file

@ -2,7 +2,7 @@
/*
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2013 - 2024 Roland Gruber
Copyright (C) 2013 - 2025 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -270,7 +270,7 @@ class pykotaPrinter extends baseModule {
if ($parentPrinters !== []) {
$container->addLabel(new htmlOutputText(_('Printer groups')));
$parentPrinterText = new htmlOutputText(implode(', ', $parentPrinters));
$container->addField($parentPrinterText, true);
$container->addField($parentPrinterText);
}
}
// printer members

View file

@ -565,7 +565,7 @@ class pykotaUser extends baseModule {
$totalPaidGroup->addElement(new htmlOutputText($total));
$totalPaidGroup->addElement(new htmlSpacer('0.5rem', null));
$totalPaidGroup->addElement(new htmlHelpLink('pykotaLifeTimePaid'));
$container->addField($totalPaidGroup, 12);
$container->addField($totalPaidGroup);
// payment/job history
if (!empty($this->attributes['pykotaPayments'][0])) {
$container->add(new htmlSubTitle(_('Payment history')));

View file

@ -221,12 +221,12 @@ class quota extends baseModule {
}
$allQuotas[$i] = substr($allQuotas[$i], strlen(self::$QUOTA_PREFIX));
$singleQuota = explode(",", $allQuotas[$i]);
$singleQuota[1] = $this->formatBlockUsage($singleQuota[1]);
$singleQuota[2] = $this->addBlockUnits($singleQuota[2]);
$singleQuota[3] = $this->addBlockUnits($singleQuota[3]);
$singleQuota[5] = $this->formatInodeUsage($singleQuota[5]);
$singleQuota[6] = $this->addInodeUnits($singleQuota[6]);
$singleQuota[7] = $this->addInodeUnits($singleQuota[7]);
$singleQuota[1] = $this->formatBlockUsage((int) $singleQuota[1]);
$singleQuota[2] = $this->addBlockUnits((int) $singleQuota[2]);
$singleQuota[3] = $this->addBlockUnits((int) $singleQuota[3]);
$singleQuota[5] = $this->formatInodeUsage((int) $singleQuota[5]);
$singleQuota[6] = $this->addInodeUnits((int) $singleQuota[6]);
$singleQuota[7] = $this->addInodeUnits((int) $singleQuota[7]);
$this->quota[$server][$i] = $singleQuota;
if ($this->quota[$server][$i][4] < time()) {
$this->quota[$server][$i][4] = '-';
@ -254,7 +254,7 @@ class quota extends baseModule {
$mebibytes = 1024;
$gibibytes = 1024 * $mebibytes;
$tebibytes = 1024 * $gibibytes;
if (empty($value) || !get_preg($value, 'digit') || ($value < $mebibytes)) {
if (empty($value) || !get_preg((string) $value, 'digit') || ($value < $mebibytes)) {
return (string) $value;
}
if (($value >= $tebibytes) && (($value % $tebibytes) === 0)) {
@ -279,7 +279,7 @@ class quota extends baseModule {
$mebibytes = 1024;
$gibibytes = 1024 * $mebibytes;
$tebibytes = 1024 * $gibibytes;
if (empty($value) || !get_preg($value, 'digit') || ($value < $mebibytes)) {
if (empty($value) || !get_preg((string) $value, 'digit') || ($value < $mebibytes)) {
return (string) $value;
}
if ($value >= $tebibytes) {
@ -302,7 +302,7 @@ class quota extends baseModule {
$million = 1000 * $kilo;
$billion = 1000 * $million;
$trillion = 1000 * $billion;
if (empty($value) || !get_preg($value, 'digit')) {
if (empty($value) || !get_preg((string) $value, 'digit')) {
return (string) $value;
}
if (($value >= $trillion) && (($value % $trillion) === 0)) {
@ -331,7 +331,7 @@ class quota extends baseModule {
$million = 1000 * $kilo;
$billion = 1000 * $million;
$trillion = 1000 * $billion;
if (empty($value) || !get_preg($value, 'digit')) {
if (empty($value) || !get_preg((string) $value, 'digit')) {
return '-';
}
if ($value >= $trillion) {

View file

@ -1392,7 +1392,7 @@ class sambaSamAccount extends baseModule implements passwordService, AccountStat
elseif ($hr >= 24 * 7) {
$hr -= 24 * 7;
}
$checkbox = new htmlInputCheckbox('lh_' . $hr, $hour[$hr]);
$checkbox = new htmlInputCheckbox('lh_' . $hr, (bool) $hour[$hr]);
$boxes[$i % 24][floor($i / 24)] = $checkbox;
}
for ($h = 0; $h < 24; $h++) {
@ -1601,7 +1601,7 @@ class sambaSamAccount extends baseModule implements passwordService, AccountStat
if ($returnValue === 'ok') {
$return->addLabel(new htmlOutputText($label));
$editGroup = new htmlGroup();
$editGroup->addElement(new htmlImage('../../graphics/pass.svg', 16, 16));
$editGroup->addElement(new htmlImage('../../graphics/pass.svg', '16', '16'));
$editGroup->addElement(new htmlSpacer('0.5rem', null));
$editGroup->addElement(new htmlAccountPageButton(static::class, 'homedir', 'delete_' . $i, _('Delete')));
$return->addField($editGroup);
@ -1609,7 +1609,7 @@ class sambaSamAccount extends baseModule implements passwordService, AccountStat
elseif ($returnValue === 'missing') {
$return->addLabel(new htmlOutputText($label));
$editGroup = new htmlGroup();
$editGroup->addElement(new htmlImage('../../graphics/del.svg', 16, 16));
$editGroup->addElement(new htmlImage('../../graphics/del.svg', '16', '16'));
$editGroup->addElement(new htmlSpacer('0.5rem', null));
$editGroup->addElement(new htmlAccountPageButton(static::class, 'homedir', 'create_' . $i, _('Create')));
$return->addField($editGroup);
@ -1749,7 +1749,7 @@ class sambaSamAccount extends baseModule implements passwordService, AccountStat
$expireContainer->add(new htmlSelect('sambaSamAccount_expire_mon', $mon, ['1']), 2, 2, 2, 'padding-left-right05');
$expireContainer->add(new htmlSelect('sambaSamAccount_expire_yea', $year, ['2030']), 6, 6, 6, 'padding-left-right05');
$expireContainer->add(new htmlHelpLink('expireDate'), 2, 2, 2, 'padding-left-right05');
$return->addField($expireContainer, 12);
$return->addField($expireContainer);
if (!$this->isBooleanConfigOptionSet('sambaSamAccount_hideHomeDrive')) {
// letter of home drive
$drives = ['-'];
@ -1780,7 +1780,7 @@ class sambaSamAccount extends baseModule implements passwordService, AccountStat
for ($i = 0; $i < count($sambaDomains); $i++) {
$sambaDomainNames[] = $sambaDomains[$i]->name;
}
$return->add(new htmlResponsiveSelect('sambaSamAccount_sambaDomainName', $sambaDomainNames, null, _('Domain'), 'domain'));
$return->add(new htmlResponsiveSelect('sambaSamAccount_sambaDomainName', $sambaDomainNames, [], _('Domain'), 'domain'));
// Windows group
$groups = [];
foreach ($this->groupRids as $key => $value) {
@ -1802,7 +1802,7 @@ class sambaSamAccount extends baseModule implements passwordService, AccountStat
for ($i = 0; $i < count($sambaDomains); $i++) {
$sambaDomainNames[] = $sambaDomains[$i]->name;
}
$return->add(new htmlResponsiveSelect('sambaSamAccount_sambaDomainName', $sambaDomainNames, null, _('Domain'), 'domain'));
$return->add(new htmlResponsiveSelect('sambaSamAccount_sambaDomainName', $sambaDomainNames, [], _('Domain'), 'domain'));
}
return $return;
}
@ -2747,9 +2747,9 @@ class sambaSamAccount extends baseModule implements passwordService, AccountStat
* Sets the expiration date of this account.
* If all parameters are null the expiration date will be removed.
*
* @param String $year year (e.g. 2040)
* @param String $month month (e.g. 8)
* @param String $day day (e.g. 27)
* @param int|null $year year (e.g. 2040)
* @param int|null $month month (e.g. 8)
* @param int|null $day day (e.g. 27)
*/
public function setExpirationDate($year, $month, $day) {
if (($year == null) && ($month == null) && ($day == null)) {

View file

@ -750,11 +750,11 @@ class shadowAccount extends baseModule implements passwordService, AccountStatus
/**
* Sets the expiration date of this account.
* If all parameters are null the expiration date will be removed.
* If all parameters are null, the expiration date will be removed.
*
* @param String $year year (e.g. 2040)
* @param String $month month (e.g. 8)
* @param String $day day (e.g. 27)
* @param int|null $year year (e.g. 2040)
* @param int|null $month month (e.g. 8)
* @param int|null $day day (e.g. 27)
*/
public function setExpirationDate($year, $month, $day) {
if (($year == null) && ($month == null) && ($day == null)) {
@ -824,10 +824,7 @@ class shadowAccount extends baseModule implements passwordService, AccountStatus
}
/**
* Returns a list of jobs that can be run.
*
* @param LAMConfig $config configuration
* @return array list of jobs
* {@inheritDoc}
*/
public function getSupportedJobs(&$config) {
return [
@ -1110,15 +1107,7 @@ if (interface_exists('\LAM\JOB\Job', false)) {
}
/**
* Checks if a user needs to change his password.
*
* @param integer $jobID job ID
* @param array $options job settings
* @param PDO $pdo PDO
* @param DateTime $now current time
* @param array $policyOptions list of max age values (policy DN => maxAge)
* @param array $user user attributes
* @param boolean $isDryRun just do a dry run, nothing is modified
* {@inheritDoc}
*/
protected function checkSingleUser($jobID, $options, &$pdo, $now, $policyOptions, $user, $isDryRun) {
// skip if user is locked
@ -1220,15 +1209,7 @@ if (interface_exists('\LAM\JOB\Job', false)) {
}
/**
* Checks if a user needs to change his password.
*
* @param integer $jobID job ID
* @param array $options job settings
* @param PDO $pdo PDO
* @param DateTime $now current time
* @param array $policyOptions list of max age values (policy DN => maxAge)
* @param array $user user attributes
* @param boolean $isDryRun just do a dry run, nothing is modified
* {@inheritDoc}
*/
protected function checkSingleUser($jobID, $options, &$pdo, $now, $policyOptions, $user, $isDryRun) {
$dn = $user['dn'];
@ -1313,15 +1294,7 @@ if (interface_exists('\LAM\JOB\Job', false)) {
}
/**
* Checks if a user is expired.
*
* @param integer $jobID job ID
* @param array $options job settings
* @param PDO $pdo PDO
* @param DateTime $now current time
* @param array $policyOptions list of policy options by getPolicyOptions()
* @param array $user user attributes
* @param boolean $isDryRun just do a dry run, nothing is modified
* {@inheritDoc}
*/
protected function checkSingleUser($jobID, $options, &$pdo, $now, $policyOptions, $user, $isDryRun) {
$expireTimeUnix = $user['shadowexpire'][0] * 3600 * 24;

View file

@ -7,7 +7,7 @@ use \LAM\PDF\PDFTableRow;
/*
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2011 - 2024 Roland Gruber
Copyright (C) 2011 - 2025 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -157,16 +157,16 @@ class systemQuotas extends baseModule {
// new entry
$container->addElement(new htmlInputField('path', null, 20));
$container->addElement($spacer);
$newSoftBlockInput = new htmlInputField('softBlock', 0, 10);
$newSoftBlockInput = new htmlInputField('softBlock', '0', 10);
$container->addElement($newSoftBlockInput);
$container->addElement($spacer);
$newHardBlockInput = new htmlInputField('hardBlock', 0, 10);
$newHardBlockInput = new htmlInputField('hardBlock', '0', 10);
$container->addElement($newHardBlockInput);
$container->addElement($spacer);
$newSoftInodeInput = new htmlInputField('softInode', 0, 10);
$newSoftInodeInput = new htmlInputField('softInode', '0', 10);
$container->addElement($newSoftInodeInput);
$container->addElement($spacer);
$newHardInodeInput = new htmlInputField('hardInode', 0, 10);
$newHardInodeInput = new htmlInputField('hardInode', '0', 10);
$container->addElement($newHardInodeInput);
$container->addElement(new htmlButton('add', 'add.svg', true));
return $container;
@ -242,12 +242,12 @@ class systemQuotas extends baseModule {
/**
* Checks if the quota parameters are valid.
*
* @param String $path mountpoint
* @param int $softBlock soft block limit
* @param int $hardBlock hard block limit
* @param int $softInode soft inode limit
* @param int $hardInode hard inode limit
* @param boolean $uploadIndex position is upload table
* @param string $path mountpoint
* @param string $softBlock soft block limit
* @param string $hardBlock hard block limit
* @param string $softInode soft inode limit
* @param string $hardInode hard inode limit
* @param int $uploadIndex position in upload table
* @return array array where error messages are returned
*/
private function checkQuota($path, $softBlock, $hardBlock, $softInode, $hardInode, $uploadIndex = null) {

View file

@ -200,12 +200,15 @@ class takUser extends baseModule {
if (!in_array('takUser', $partialAccounts[$i]['objectClass'])) {
$partialAccounts[$i]['objectClass'][] = 'takUser';
}
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'takuser_takcallsign', 'takcallsign', 'username', $this->messages['takcallsign'][3], $errors);
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'takuser_takrole', 'takrole', null, null, $errors);
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'takuser_takcallsign',
'takcallsign', 'username', $this->messages['takcallsign'][3], $errors);
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'takuser_takrole',
'takrole', null, [], $errors);
if (!in_array($partialAccounts[$i]['takrole'][0], self::ROLE_TYPES)) {
$errors[] = array_merge($this->messages['takrole'][0], [[$i]]);
}
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'takuser_takcolor', 'takcolor', null, null, $errors);
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'takuser_takcolor',
'takcolor', null, [], $errors);
if (!in_array($partialAccounts[$i]['takcolor'][0], self::COLOR_TYPES)) {
$errors[] = array_merge($this->messages['takcolor'][0], [[$i]]);
}

View file

@ -539,7 +539,7 @@ class windowsGroup extends baseModule {
}
$this->addDoubleSelectionArea($return, _("Selected groups"), _("Available groups"), $selectedGroups,
null, $availableGroups, null, 'memberof', false, true);
[], $availableGroups, [], 'memberof', false, true);
$return->addVerticalSpacer('2rem');
$backButton = new htmlAccountPageButton(static::class, 'attributes', 'back', _('Back'));
@ -642,7 +642,6 @@ class windowsGroup extends baseModule {
$filterGroup = new htmlGroup();
$filterGroup->addElement(new htmlOutputText(_('Filter') . ' '));
$filter = new htmlInputField('windows_filter');
$filter->setFieldSize('5em');
$filter->filterSelectBox('members');
$filterGroup->addElement($filter);
$return->add($filterGroup);

View file

@ -372,8 +372,8 @@ class windowsHost extends baseModule {
/**
* Formats a value in file time (100 ns since 1601-01-01).
*
* @param integer $value time value
* @return String formatted value
* @param string $value time value
* @return string formatted value
*/
private function formatFileTime($value) {
if (empty($value) || ($value == '-1')) {

View file

@ -1407,7 +1407,7 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
$userPrincipalNameLabel->setMarkAsRequired(true);
$containerLeft->addLabel($userPrincipalNameLabel);
$userPrincipalNameGroup = new htmlGroup();
$userPrincipalNameGroup->addElement(new htmlInputField('userPrincipalName', $userPrincipalName, '15'));
$userPrincipalNameGroup->addElement(new htmlInputField('userPrincipalName', $userPrincipalName, 15));
$userPrincipalNameGroup->addElement(new htmlSelect('userPrincipalNameDomain', $domains, [$userPrincipalNameDomain]));
$userPrincipalNameGroup->addElement(new htmlHelpLink('userPrincipalName'));
$containerLeft->addField($userPrincipalNameGroup);
@ -2192,9 +2192,9 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
// determine action
if (str_contains($buttonName, '_change')) {
$date = DateTime::createFromFormat('Y-m-d', $_POST['accountexpires'], new DateTimeZone('UTC'));
$year = $date->format('Y');
$month = $date->format('m');
$day = $date->format('d');
$year = (int) $date->format('Y');
$month = (int) $date->format('m');
$day = (int) $date->format('d');
// set new time
$this->setExpirationDate($year, $month, $day);
// sync other modules
@ -2291,7 +2291,7 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
}
$this->addDoubleSelectionArea($return, _("Selected groups"), _("Available groups"),
$selectedGroups, null, $availableGroups, null, 'groups', $groupDisplayContainsDn, true);
$selectedGroups, [], $availableGroups, [], 'groups', $groupDisplayContainsDn, true);
// sync options
$typeManager = new TypeManager();
@ -2902,13 +2902,13 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
elseif ($hr >= 24 * 7) {
$hr -= 24 * 7;
}
$checkbox = new htmlInputCheckbox('lh_' . $hr, $hour[$hr]);
$checkbox = new htmlInputCheckbox('lh_' . $hr, ($hour[$hr] === '1'));
$boxes[$i % 24][floor($i / 24)] = $checkbox;
}
for ($h = 0; $h < 24; $h++) {
$hour = str_pad($h, 2, '0', STR_PAD_LEFT);
$hour = str_pad((string) $h, 2, '0', STR_PAD_LEFT);
$row = [];
$row[] = new htmlOutputText("$hour:00 - " . str_pad($h + 1, 2, '0', STR_PAD_LEFT) . ":00");
$row[] = new htmlOutputText("$hour:00 - " . str_pad((string) ($h + 1), 2, '0', STR_PAD_LEFT) . ":00");
for ($d = 1; $d < 7; $d++) {
$row[] = $boxes[$h][$d];
}
@ -3028,7 +3028,7 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
*/
public function build_uploadAccounts($rawAccounts, $ids, &$partialAccounts, $selectedModules, &$type) {
$errors = [];
// get list of existing groups
// get the list of existing groups
$groupList = $this->findGroups();
$groupMap = [];
foreach ($groupList as $dn) {
@ -3238,7 +3238,8 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
}
// other telephone
if (!$this->isBooleanConfigOptionSet('windowsUser_hideotherTelephone')) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_otherTelephone', 'otherTelephone', 'telephone', $this->messages['otherTelephone'][1], $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_otherTelephone',
'otherTelephone', 'telephone', $this->messages['otherTelephone'][1], $errors, '/;[ ]*/');
}
// fax number
if (!$this->isBooleanConfigOptionSet('windowsUser_hidefacsimileTelephoneNumber')) {
@ -3251,7 +3252,8 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
}
// other websites
if (!$this->isBooleanConfigOptionSet('windowsUser_hideurl')) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_otherWebSites', 'url', null, null, $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_otherWebSites',
'url', null, [], $errors, '/;[ ]*/');
}
// user account control
$userAccountControlAttr['useraccountcontrol'][0] = self::DEFAULT_ACCOUNT_CONTROL;
@ -3277,7 +3279,7 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
if (!empty($rawAccounts[$i][$ids['windowsUser_accountExpires']])) {
if (get_preg($rawAccounts[$i][$ids['windowsUser_accountExpires']], 'date')) {
$dateParts = explode('-', $rawAccounts[$i][$ids['windowsUser_accountExpires']]);
$partialAccounts[$i]['accountexpires'] = $this->buildExpirationDate($dateParts[2], $dateParts[1], $dateParts[0]);
$partialAccounts[$i]['accountexpires'] = $this->buildExpirationDate((int) $dateParts[2], (int) $dateParts[1], (int) $dateParts[0]);
}
else {
$errMsg = $this->messages['accountexpires'][1];
@ -3374,12 +3376,13 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
}
// title
if (!$this->isBooleanConfigOptionSet('windowsUser_hidetitle', true)) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_title', 'title', 'title', $this->messages['title'][1], $errors);
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_title',
'title', 'title', $this->messages['title'][1], $errors);
}
// room number
if (!$this->isBooleanConfigOptionSet('windowsUser_hideroomnumber', true)) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_roomNumber',
'roomnumber', null, null, $errors, '/;[ ]*/');
'roomnumber', null, [], $errors, '/;[ ]*/');
}
// carLicense
if (!$this->isBooleanConfigOptionSet('windowsUser_hidecarLicense', true)) {
@ -3391,28 +3394,33 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
}
// employee type
if (!$this->isBooleanConfigOptionSet('windowsUser_hideemployeeType', true)) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_employeeType', 'employeeType',
'employeeType', $this->messages['employeeType'][1], $errors);
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_employeeType',
'employeeType', 'employeeType', $this->messages['employeeType'][1], $errors);
}
// business category
if (!$this->isBooleanConfigOptionSet('windowsUser_hidebusinessCategory', true)) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_businessCategory', 'businessCategory', 'businessCategory', $this->messages['businessCategory'][1], $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_businessCategory',
'businessCategory', 'businessCategory', $this->messages['businessCategory'][1], $errors, '/;[ ]*/');
}
// departments
if (!$this->isBooleanConfigOptionSet('windowsUser_hidedepartment', true)) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_department', 'department', null, null, $errors);
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_department',
'department', null, [], $errors);
}
// department numbers
if (!$this->isBooleanConfigOptionSet('windowsUser_hidedepartmentNumber', true)) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_departmentNumber', 'departmentNumber', null, null, $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_departmentNumber',
'departmentNumber', null, [], $errors, '/;[ ]*/');
}
// organisational unit
if (!$this->isBooleanConfigOptionSet('windowsUser_hideou', true)) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_ou', 'ou', null, null, $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_ou',
'ou', null, [], $errors, '/;[ ]*/');
}
// organisation
if (!$this->isBooleanConfigOptionSet('windowsUser_hideo', true)) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_o', 'o', null, null, $errors, '/;[ ]*/');
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_o',
'o', null, [], $errors, '/;[ ]*/');
}
// manager
if (!$this->isBooleanConfigOptionSet('windowsUser_hidemanager', true)) {
@ -3445,7 +3453,7 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
// Proxy-Addresses
if (!$this->isBooleanConfigOptionSet('windowsUser_hideproxyAddresses', true)) {
$this->mapSimpleUploadField($rawAccounts, $ids, $partialAccounts, $i, 'windowsUser_proxyAddresses', 'proxyAddresses',
null, null, $errors, '/;[ ]*/');
null, [], $errors, '/;[ ]*/');
}
}
return $errors;
@ -3722,7 +3730,7 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
$date = new DateTime('now', getTimeZone());
$toAdd = new DateInterval('P' . $numDays . 'D');
$dateTarget = $date->add($toAdd);
$this->setExpirationDate($dateTarget->format('Y'), $dateTarget->format('m'), $dateTarget->format('d'));
$this->setExpirationDate((int) $dateTarget->format('Y'), (int) $dateTarget->format('m'), (int) $dateTarget->format('d'));
}
// departments
if (!$this->isBooleanConfigOptionSet('windowsUser_hidedepartment')
@ -4058,7 +4066,7 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
$lockoutDurationSeconds = substr($lockoutDuration, 0, -7);
$lockoutTime = self::getFileTime($attrs['lockouttime'][0]);
$unlockTime = clone $lockoutTime;
$unlockTime->add(new DateInterval('PT' . abs($lockoutDurationSeconds) . 'S'));
$unlockTime->add(new DateInterval('PT' . abs((int) $lockoutDurationSeconds) . 'S'));
$now = new DateTime('now', getTimeZone());
if ($unlockTime > $now) {
$unlockTime->setTimezone(getTimeZone());
@ -4347,7 +4355,7 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
* Returns the formatted value for the password expiration date.
*
* @param array $attributes user attributes ($this->attributes if null)
* @return String date or -
* @return string date or -
*/
private function formatPasswordExpires($attributes = null) {
if ($attributes == null) {
@ -4363,8 +4371,8 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
/**
* Formats a value in file time (100 ns since 1601-01-01).
*
* @param integer $value time value
* @return String formatted value
* @param string $value time value
* @return string formatted value
*/
private function formatFileTime($value) {
if (empty($value) || ($value == '-1')) {
@ -4380,7 +4388,7 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
/**
* Returns a value in file time (100 ns since 1601-01-01).
*
* @param integer $value time value as int
* @param string $value time value as int
* @return DateTime|null time value
*/
public static function getFileTime($value): ?DateTime {
@ -4396,11 +4404,11 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
/**
* Sets the expiration date of this account.
* If all parameters are null the expiration date will be removed.
* If all parameters are null, the expiration date will be removed.
*
* @param String $year year (e.g. 2040)
* @param String $month month (e.g. 8)
* @param String $day day (e.g. 27)
* @param int|null $year year (e.g. 2040)
* @param int|null $month month (e.g. 8)
* @param int|null $day day (e.g. 27)
*/
public function setExpirationDate($year, $month, $day) {
if (($year == null) && ($month == null) && ($day == null)) {
@ -4619,10 +4627,7 @@ class windowsUser extends baseModule implements passwordService, AccountStatusPr
}
/**
* Returns a list of jobs that can be run.
*
* @param LAMConfig $config configuration
* @return array list of jobs
* {@inheritDoc}
*/
public function getSupportedJobs(&$config) {
return [
@ -5017,31 +5022,23 @@ if (interface_exists('\LAM\JOB\Job', false)) {
}
/**
* Checks if a user needs to change his password.
*
* @param integer $jobID job ID
* @param array $options job settings
* @param PDO $pdo PDO
* @param DateTime $now current time
* @param array $policyOptions not used
* @param array $user user attributes
* @param boolean $isDryRun just do a dry run, nothing is modified
* {@inheritDoc}
*/
protected function checkSingleUser($jobID, $options, &$pdo, $now, $policyOptions, $user, $isDryRun) {
$dn = $user['dn'];
// skip if password does not expire at all
// skip if the password does not expire at all
if (windowsUser::isNeverExpiring($user)) {
$this->jobResultLog->logDebug($dn . ' does not expire.');
return;
}
// skip if password does not expire
// skip if the password does not expire
if (empty($user['msds-userpasswordexpirytimecomputed'][0])
|| ($user['msds-userpasswordexpirytimecomputed'][0] == windowsUser::ACCOUNT_DOES_NOT_EXPIRE)
|| ($user['msds-userpasswordexpirytimecomputed'][0] == '0')) {
$this->jobResultLog->logDebug($dn . ': password does not expire.');
return;
}
// skip if account itself is expired
// skip if the account itself is expired
if (!empty($user['accountexpires'][0])) {
$accountExpiration = windowsUser::getFileTime($user['accountexpires'][0]);
if ($accountExpiration <= $now) {
@ -5049,7 +5046,7 @@ if (interface_exists('\LAM\JOB\Job', false)) {
return;
}
}
// skip if account is deactivated
// skip if the account is deactivated
if (windowsUser::isDeactivated($user)) {
$this->jobResultLog->logDebug($dn . ' is deactivated.');
return;
@ -5277,8 +5274,8 @@ if (interface_exists('\LAM\JOB\Job', false)) {
/**
* Returns if the job should run.
*
* @param $pdo PDO
* @param $jobId job id
* @param PDO $pdo PDO
* @param string $jobId job id
* @param DateTime $baseDate base date
* @param int $monthInterval month interval
* @return bool should run
@ -5512,15 +5509,7 @@ if (interface_exists('\LAM\JOB\Job', false)) {
}
/**
* Checks if a user is expired.
*
* @param integer $jobID job ID
* @param array $options job settings
* @param PDO $pdo PDO
* @param DateTime $now current time
* @param array $policyOptions list of policy options by getPolicyOptions()
* @param array $user user attributes
* @param boolean $isDryRun just do a dry run, nothing is modified
* {@inheritDoc}
*/
protected function checkSingleUser($jobID, $options, &$pdo, $now, $policyOptions, $user, $isDryRun) {
$seconds = substr($user['accountexpires'][0], 0, -7);

View file

@ -160,7 +160,7 @@ class yubiKeyUser extends baseModule {
}
if (empty($objectClass) || in_array($objectClass, $this->attributes['objectClass'])) {
$htmlIds = [];
$this->addMultiValueInputTextField($return, $attributeName, _('YubiKey ids'), false, '12', false, null, null, $htmlIds, 'lam-prevent-enter');
$this->addMultiValueInputTextField($return, $attributeName, _('YubiKey ids'), false, 12, false, null, null, $htmlIds, 'lam-prevent-enter');
if (!empty($objectClass)) {
$return->addVerticalSpacer('2rem');
$remButton = new htmlButton('remObjectClass', _('Remove YubiKey extension'));

View file

@ -120,7 +120,7 @@ function createPdf($structure, $accounts, $pdfKeys, $account_type, $font, $retur
$info_string = str_replace("\r", "", $section->getText());
$info_string = explode("\n", $info_string);
foreach ($info_string as $text) {
$pdf->MultiCell(0, LAMPDF_LINEHEIGHT, trim($text), 0, "L", 0);
$pdf->MultiCell(0, LAMPDF_LINEHEIGHT, trim($text), 0, "L");
$pdf->Ln(0);
}
$pdf->Ln(LAMPDF_LINEHEIGHT * 2);
@ -156,7 +156,7 @@ function createPdf($structure, $accounts, $pdfKeys, $account_type, $font, $retur
printTable($pdf, $valueEntry, $font);
}
elseif ($valueEntry instanceof PDFImage) {
printImage($pdf, $valueEntry, $font);
printImage($pdf, $valueEntry);
}
}
}
@ -204,9 +204,12 @@ function getSectionHeadline($entry) {
*/
function printLabelValue(&$pdf, $valueEntry, $fontName) {
$pdf->SetFont($fontName, 'B', LAMPDF_FONT_SIZE);
$pdf->MultiCell(LAMPDF_LABELWIDTH, LAMPDF_LINEHEIGHT, replaceSpecialCharacters($valueEntry->getLabel()) . ':', 0, 'R', false, 0, '', '', true, 0, false, true, 0, 'T');
$pdf->MultiCell(LAMPDF_LABELWIDTH, LAMPDF_LINEHEIGHT, replaceSpecialCharacters($valueEntry->getLabel()) . ':',
0, 'R', false, 0);
$pdf->SetFont($fontName, '', LAMPDF_FONT_SIZE);
$pdf->MultiCell(0, LAMPDF_LINEHEIGHT, replaceSpecialCharacters($valueEntry->getValue()), 0, 'L', false, 1, '', '', true, 0, false, true, 0, 'M');
$pdf->MultiCell(0, LAMPDF_LINEHEIGHT, replaceSpecialCharacters($valueEntry->getValue()),
0, 'L', false, 1, null, null, true, 0, false,
true, 0, 'M');
$pdf->Ln(0);
}
@ -221,7 +224,8 @@ function printTable(&$pdf, $table, $fontName) {
$headline = $table->getHeadline();
if (!empty($headline)) {
$pdf->SetFont($fontName, 'B', LAMPDF_FONT_SIZE);
$pdf->Cell(LAMPDF_LABELWIDTH, LAMPDF_LINEHEIGHT, replaceSpecialCharacters($headline) . ':', 0, 0, 'L', 0);
$pdf->Cell(LAMPDF_LABELWIDTH, LAMPDF_LINEHEIGHT, replaceSpecialCharacters($headline) . ':',
0, 0, 'L');
$pdf->SetFont($fontName, '', LAMPDF_FONT_SIZE);
$pdf->Ln(LAMPDF_LINEHEIGHT);
}
@ -234,7 +238,8 @@ function printTable(&$pdf, $table, $fontName) {
if ($cell->bold) {
$pdf->SetFont($fontName, 'B', LAMPDF_FONT_SIZE);
}
$pdf->Cell($width, LAMPDF_LINEHEIGHT, replaceSpecialCharacters($cell->content), 0, 0, $cell->align, 0, '', 1);
$pdf->Cell($width, LAMPDF_LINEHEIGHT, replaceSpecialCharacters($cell->content), 0,
0, $cell->align, false, '', 1);
if ($cell->bold) {
$pdf->SetFont($fontName, '', LAMPDF_FONT_SIZE);
}
@ -249,16 +254,15 @@ function printTable(&$pdf, $table, $fontName) {
*
* @param LAMTCPDF $pdf PDF
* @param PDFImage $imageEntry entry
* @param string $fontName font name
*/
function printImage(&$pdf, $imageEntry, $fontName) {
function printImage(&$pdf, $imageEntry) {
include_once __DIR__ . '/imageutils.inc';
$imageManipulator = ImageManipulationFactory::getImageManipulator($imageEntry->getImageData());
$height = $imageManipulator->getHeight() / 2.9;
if ($height > 40) {
$height = 40;
}
$pdf->Image('@' . $imageManipulator->getImageData(), null, null, null, $height,
$pdf->Image('@' . $imageManipulator->getImageData(), null, null, 0, $height,
'JPG', null, 'T', true, 300, 'R',
false, false, 0, false, false, false);
$pdf->Ln($height);

View file

@ -1441,7 +1441,7 @@ class PDFStructure {
$this->sections[] = new PDFTextSection($section['data']);
}
else {
$entrySection = new PDFEntrySection(null);
$entrySection = new PDFEntrySection('');
$entrySection->import($section['data']);
$this->sections[] = $entrySection;
}

View file

@ -342,7 +342,7 @@ class ConfigDataImporter {
$steps[] = new ImporterStep(_('General settings'), 'mainConfig', $value);
break;
case 'certificates':
$steps[] = new ImporterStep(_('SSL certificates'), 'certificates', $value);
$steps[] = new ImporterStep(_('SSL certificates'), 'certificates', [$value]);
break;
case 'serverProfiles':
$mainStep = new ImporterStep(_('Server profiles'), 'serverProfiles', $value);
@ -424,7 +424,7 @@ class ConfigDataImporter {
* Runs the actual import.
*
* @param ImporterStep[] $steps import steps
* @throws LAMException if error occurred
* @throws LAMException if an error occurred
*/
public function runImport($steps) {
foreach ($steps as $step) {
@ -434,7 +434,7 @@ class ConfigDataImporter {
$key = $step->getKey();
match ($key) {
'mainConfig' => $this->importMainConfig($step->getValue()),
'certificates' => $this->importCertificates($step->getValue()),
'certificates' => $this->importCertificates($step->getValue()[0]),
'serverProfiles' => $this->importServerProfiles($step),
'accountProfiles' => $this->importAccountProfiles($step),
'accountProfileTemplates' => $this->importAccountProfileTemplates($step),

View file

@ -83,7 +83,7 @@ class Remote {
$this->serverConfig = $server;
$serverNameParts = explode(",", $this->serverConfig->getServer());
if (count($serverNameParts) > 1) {
$handle = @new SSH2($serverNameParts[0], $serverNameParts[1]);
$handle = @new SSH2($serverNameParts[0], (int) $serverNameParts[1]);
}
else {
$handle = @new SSH2($serverNameParts[0]);
@ -165,7 +165,7 @@ class Remote {
}
catch (NoKeyLoadedException $e) {
logNewMessage(LOG_ERR, sprintf('Unable to load key %s: %s', $keyPath, $e->getMessage()));
throw new LAMException(sprintf(_("Unable to load key %s."), htmlspecialchars($keyPath)), null, $e);
throw new LAMException(sprintf(_("Unable to load key %s."), htmlspecialchars($keyPath)), '', $e);
}
}

View file

@ -272,7 +272,7 @@ function logNewMessage($level, $message): void {
LOG_WARNING => 'WARNING',
LOG_ERR => 'ERROR'];
if (!in_array($level, array_keys($possibleLevels))) {
StatusMessage('ERROR', 'Invalid log level!', $level);
StatusMessage('ERROR', 'Invalid log level!', htmlspecialchars((string) $level));
return;
}
if (isset($_SESSION['cfgMain'])) {

View file

@ -267,7 +267,7 @@ class SelfServicePersistence {
}
catch (PDOException $e) {
logNewMessage(LOG_ERR, _('Unable to connect to configuration database.') . ' ' . $e->getMessage());
throw new LAMException(_('Unable to connect to configuration database.'), null, $e);
throw new LAMException(_('Unable to connect to configuration database.'), '', $e);
}
}
else {

View file

@ -525,7 +525,7 @@ class TreeView {
$cutButton->setCSSClasses($buttonClasses);
$buttonGroup->addElement($cutButton);
$pasteButton = new htmlImage('../../graphics/paste.svg', $buttonSize, $buttonSize, _('Paste'), _('Paste'));
$pasteButton = new htmlImage('../../graphics/paste.svg', $buttonSize, $buttonSize, _('Paste as new child entry'), _('Paste as new child entry'));
$pasteButton->setOnClick('window.lam.treeview.pasteNode(\'' . getSecurityTokenName() . '\', '
. '\'' . getSecurityTokenValue() . '\', \'' . base64_encode($dn) . '\');');
$pasteButton->setCSSClasses($buttonClasses);
@ -903,7 +903,7 @@ class TreeView {
$image->enableLightbox();
$image->setCSSClasses(['thumbnail', 'image-input', 'attribute-field']);
$image->addDataAttribute('attr-name', $attributeName);
$image->addDataAttribute('index', $index);
$image->addDataAttribute('index', (string) $index);
return $image;
}

View file

@ -22,6 +22,7 @@ namespace LAM\TYPES;
*/
use baseModule;
use baseType;
use LAMConfig;
@ -280,7 +281,7 @@ class ConfiguredType {
/**
* Returns the names of the active modules for this type.
*
* @return string[] module names
* @return class-string<baseModule>[] module names
*/
public function getModules(): array {
$typeSettings = $this->typeManager->getConfig()->get_typeSettings();

View file

@ -123,10 +123,9 @@ class lamAsteriskExtList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
function __construct($type) {
public function __construct($type) {
parent::__construct($type);
$this->labels = [
'nav' => _("Extension count: %s"),

View file

@ -3,7 +3,7 @@
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2008 Thomas Manninger
2009 - 2024 Roland Gruber
2009 - 2025 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -150,8 +150,7 @@ class lamDHCPList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
public function __construct($type) {
parent::__construct($type);
@ -220,10 +219,7 @@ class lamDHCPList extends lamList {
}
/**
* Add DCP main settings button.
*
* @param htmlGroup $left left part
* @param htmlGroup $right right part
* {@inheritDoc}
*/
protected function addExtraInputElementsToTopArea(&$left, &$right) {
if (checkIfWriteAccessIsAllowed($this->type->getId())) {

View file

@ -213,10 +213,9 @@ class lamGroupList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
function __construct($type) {
public function __construct($type) {
parent::__construct($type);
$this->labels = [
'nav' => _("Group count: %s"),

View file

@ -173,10 +173,9 @@ class lamHostList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
function __construct($type) {
public function __construct($type) {
parent::__construct($type);
$this->labels = [
'nav' => _("Host count: %s"),

View file

@ -122,10 +122,9 @@ class kolabSharedFolderTypeList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
function __construct($type) {
public function __construct($type) {
parent::__construct($type);
$this->labels = [
'nav' => _("Shared folder count: %s"),

View file

@ -129,10 +129,9 @@ class lamMailAliasList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
function __construct($type) {
public function __construct($type) {
parent::__construct($type);
$this->labels = [
'nav' => _("Alias count: %s"),

View file

@ -149,10 +149,9 @@ class lamNetgroupList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
function __construct($type) {
public function __construct($type) {
parent::__construct($type);
$this->labels = [
'nav' => _("Group count: %s"),

View file

@ -147,10 +147,9 @@ class lamPykotaBillingCodeTypeList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
function __construct($type) {
public function __construct($type) {
parent::__construct($type);
$this->labels = [
'nav' => _("Billing code count: %s"),

View file

@ -147,10 +147,9 @@ class lamPykotaPrinterTypeList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
function __construct($type) {
public function __construct($type) {
parent::__construct($type);
$this->labels = [
'nav' => _("Printer count: %s"),

View file

@ -149,10 +149,9 @@ class lamSmbDomainList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
function __construct($type) {
public function __construct($type) {
parent::__construct($type);
$this->labels = [
'nav' => _("Domain count: %s"),

View file

@ -100,59 +100,58 @@ class user extends baseType {
public function getTitleBarTitle($container) {
$title = '';
// get attributes
$personalAttributes = null;
$personalAttributes = [];
if ($container->getAccountModule('inetOrgPerson') != null) {
$personalAttributes = $container->getAccountModule('inetOrgPerson')->getAttributes();
}
elseif ($container->getAccountModule('windowsUser') != null) {
$personalAttributes = $container->getAccountModule('windowsUser')->getAttributes();
}
$accountAttributes = null;
$accountAttributes = [];
if ($container->getAccountModule('account') != null) {
$accountAttributes = $container->getAccountModule('account')->getAttributes();
}
$sambaAttributes = null;
$sambaAttributes = [];
if ($container->getAccountModule('sambaSamAccount') != null) {
$sambaAttributes = $container->getAccountModule('sambaSamAccount')->getAttributes();
}
$unixAttributes = null;
$unixAttributes = [];
if ($container->getAccountModule('posixAccount') != null) {
$unixAttributes = $container->getAccountModule('posixAccount')->getAttributes();
}
$mitKerberosAttributes = null;
$mitKerberosAttributes = [];
if ($container->getAccountModule('mitKerberosStructural') != null) {
$mitKerberosAttributes = $container->getAccountModule('mitKerberosStructural')->getAttributes();
}
elseif ($container->getAccountModule('mitKerberos') != null) {
$mitKerberosAttributes = $container->getAccountModule('mitKerberos')->getAttributes();
}
// check if first and last name can be shown
if (($personalAttributes != null) && isset($personalAttributes['sn'][0]) && !empty($personalAttributes['sn'][0])
&& isset($personalAttributes['givenName'][0]) && !empty($personalAttributes['givenName'][0])) {
// check if the first and last name can be shown
if (!empty($personalAttributes['sn'][0]) && !empty($personalAttributes['givenName'][0])) {
return $title . htmlspecialchars($personalAttributes['givenName'][0] . ' ' . $personalAttributes['sn'][0]);
}
// check if a display name is set
if (($sambaAttributes != null) && isset($sambaAttributes['displayName'][0]) && !empty($sambaAttributes['displayName'][0])) {
if (!empty($sambaAttributes['displayName'][0])) {
return $title . htmlspecialchars($sambaAttributes['displayName'][0]);
}
// check if a common name is set
if (($personalAttributes != null) && isset($personalAttributes['cn'][0]) && !empty($personalAttributes['cn'][0])) {
if (!empty($personalAttributes['cn'][0])) {
return $title . htmlspecialchars($personalAttributes['cn'][0]);
}
if (($unixAttributes != null) && isset($unixAttributes['cn'][0]) && !empty($unixAttributes['cn'][0])) {
if (!empty($unixAttributes['cn'][0])) {
return $title . htmlspecialchars($unixAttributes['cn'][0]);
}
// check if a username is set
if (($unixAttributes != null) && isset($unixAttributes['uid'][0]) && !empty($unixAttributes['uid'][0])) {
if (!empty($unixAttributes['uid'][0])) {
return $title . htmlspecialchars($unixAttributes['uid'][0]);
}
if (($personalAttributes != null) && isset($personalAttributes['uid'][0]) && !empty($personalAttributes['uid'][0])) {
if (!empty($personalAttributes['uid'][0])) {
return $title . htmlspecialchars($personalAttributes['uid'][0]);
}
if (($accountAttributes != null) && isset($accountAttributes['uid'][0]) && !empty($accountAttributes['uid'][0])) {
if (!empty($accountAttributes['uid'][0])) {
return $title . htmlspecialchars($accountAttributes['uid'][0]);
}
if (($mitKerberosAttributes != null) && isset($mitKerberosAttributes['krbPrincipalName'][0]) && !empty($mitKerberosAttributes['krbPrincipalName'][0])) {
if (!empty($mitKerberosAttributes['krbPrincipalName'][0])) {
return $title . htmlspecialchars($mitKerberosAttributes['krbPrincipalName'][0]);
}
if ($container->isNewAccount) {
@ -216,8 +215,7 @@ class lamUserList extends lamList {
/**
* Constructor
*
* @param string $type account type
* @return lamList list object
* @param ConfiguredType $type account type
*/
public function __construct($type) {
parent::__construct($type);

View file

@ -483,16 +483,18 @@ function dryRun(): array {
* @param string $errstr error message
* @param string $errfile error file
* @param int $errline error line
* @return bool stop internal error handler
*/
function multiEditLdapErrorHandler($errno, $errstr, $errfile, $errline): void {
if ($errno === E_USER_ERROR) {
function multiEditLdapErrorHandler($errno, $errstr, $errfile, $errline): bool {
if (($errno === E_USER_ERROR) || ($errno === E_ERROR)) {
logNewMessage(LOG_ERR, 'Error occurred: ' . $errstr . " ($errfile: $errline)");
$_REQUEST['multiEdit_error'] = true;
}
elseif ($errno === E_USER_WARNING) {
elseif (($errno === E_USER_WARNING) || ($errno === E_WARNING)) {
logNewMessage(LOG_WARNING, 'Error occurred: ' . $errstr . " ($errfile: $errline)");
$_REQUEST['multiEdit_error'] = true;
}
return true;
}
/**

View file

@ -343,7 +343,7 @@ elseif (isset($monitorEntries['cn=monitor']['opsinitiated'])) {
$container->addLabel(new htmlOutputText('<b>' . _("Bind") . '</b>', false));
$binds = $monitorEntries['cn=snmp,cn=monitor']['anonymousbinds'][0] + $monitorEntries['cn=snmp,cn=monitor']['unauthbinds'][0]
+ $monitorEntries['cn=snmp,cn=monitor']['simpleauthbinds'][0] + $monitorEntries['cn=snmp,cn=monitor']['strongauthbinds'][0];
$container->addField(new htmlOutputText($binds));
$container->addField(new htmlOutputText((string) $binds));
$container->addLabel(new htmlOutputText('<b>' . _("Search") . '</b>', false));
$searches = $monitorEntries['cn=snmp,cn=monitor']['searchops'][0];
$container->addField(new htmlOutputText($searches));

View file

@ -1,5 +1,5 @@
parameters:
level: 4
level: 5
scanDirectories:
- lam/lib
- lam/templates
@ -56,7 +56,9 @@ parameters:
- '#Call to .*method .* on an unknown class LAM\\DB\\CronDatabase.*#'
- '#.* has invalid type LAM\\ENV\\.*#'
- '#.* has invalid type LAM\\DB\\.*#'
- '#.* has invalid return type LAM\\JOB\\.*#'
- '#Call to an undefined method baseModule::getBackupEmail\(\).#'
- '#Call to an undefined method baseModule::getMembers\(\).#'
- '#Call to an undefined method baseModule::getNextGIDs\(\).#'
- '#Call to an undefined method baseModule::setExpirationDate\(\).#'
- '#.*accountContainer::getAccountModule\(\) expects class-string\<baseModule\>, string given.*#'

View file

@ -6,6 +6,7 @@ use Rector\CodeQuality\Rector\Empty_\SimplifyEmptyCheckOnEmptyArrayRector;
use Rector\CodeQuality\Rector\For_\ForRepeatedCountToOwnVariableRector;
use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector;
use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\If_\RemoveAlwaysTrueIfConditionRector;
use Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector;
use Rector\Php70\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector;
use Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector;
@ -45,7 +46,8 @@ return RectorConfig::configure()
InlineArrayReturnAssignRector::class,
// TODO unreliable, recheck with newer rector version
ExplicitReturnNullRector::class,
RemoveParentCallWithoutParentRector::class
RemoveParentCallWithoutParentRector::class,
RemoveAlwaysTrueIfConditionRector::class,
])
->withFileExtensions([
'php',