diff options
Diffstat (limited to 'Zotlabs/Module/Admin')
-rw-r--r-- | Zotlabs/Module/Admin/Accounts.php | 218 | ||||
-rw-r--r-- | Zotlabs/Module/Admin/Site.php | 418 |
2 files changed, 572 insertions, 64 deletions
diff --git a/Zotlabs/Module/Admin/Accounts.php b/Zotlabs/Module/Admin/Accounts.php index 0c7e089be..32029eb00 100644 --- a/Zotlabs/Module/Admin/Accounts.php +++ b/Zotlabs/Module/Admin/Accounts.php @@ -5,7 +5,7 @@ namespace Zotlabs\Module\Admin; class Accounts { - + /** * @brief Handle POST actions on accounts admin page. * @@ -15,14 +15,105 @@ class Accounts { * */ + const MYP = 'ZAR'; // ZAR2x + const VERSION = '2.0.0'; + function post() { $pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() ); $users = ( x($_POST, 'user') ? $_POST['user'] : array() ); $blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() ); - + check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts'); - + + $isajax = is_ajax(); + $rc = 0; + + If (!is_site_admin()) { + if ($isajax) { + killme(); + exit; + } + goaway(z_root() . '/'); + } + + if ($isajax) { + //$debug = print_r($_SESSION[self::MYP],true); + $zarop = (x($_POST['zardo']) && preg_match('/^[ad]{1,1}$/', $_POST['zardo']) ) + ? $_POST['zardo'] : ''; + // zarat arrives with leading underscore _n + $zarat = (x($_POST['zarat']) && preg_match('/^_{1,1}[0-9]{1,6}$/', $_POST['zarat']) ) + ? substr($_POST['zarat'],1) : ''; + $zarse = (x($_POST['zarse']) && preg_match('/^[0-9a-f]{8,8}$/', $_POST['zarse']) ) + ? hex2bin($_POST['zarse']) : ''; + + if ($zarop && $zarat >= 0 && $zarse && $zarse == $_SESSION[self::MYP]['h'][$zarat]) { + + // + if ($zarop == 'd') { + $rd = q("UPDATE register SET reg_vital = 0 WHERE reg_id = %d AND SUBSTR(reg_hash,1,4) = '%s' ", + intval($_SESSION[self::MYP]['i'][$zarat]), + dbesc($_SESSION[self::MYP]['h'][$zarat]) + ); + $rc = '×'; + } + elseif ($zarop == 'a') { + // approval, REGISTER_DENIED by user 0x0040, REGISTER_AGREED by user 0x0020 @Regate + $rd = q("UPDATE register SET reg_flags = (reg_flags & ~ 16), " + . " reg_vital = (CASE (reg_flags & ~ 48) WHEN 0 THEN 0 ELSE 1 END) " + . " WHERE reg_vital = 1 AND reg_id = %d AND SUBSTR(reg_hash,1,4) = '%s' ", + intval($_SESSION[self::MYP]['i'][$zarat]), + dbesc($_SESSION[self::MYP]['h'][$zarat]) + ); + $rc = 0; + $rs = q("SELECT * from register WHERE reg_id = %d ", + intval($_SESSION[self::MYP]['i'][$zarat]) + ); + if ($rs && ($rs[0]['reg_flags'] & ~ 48) == 0) { + // create account + $rc = 'ok'.$rs[0]['reg_id']; + $ac = create_account_from_register($rs[0]); + if ( $ac['success'] ) { + $rc .= '✔'; + + $auto_create = get_config('system','auto_channel_create',1); + + if($auto_create) { + $reonar = json_decode($rs[0]['reg_stuff'], true); + // prepare channel creation + if($reonar['chan.name']) + set_aconfig($ac['account']['account_id'], 'register', 'channel_name', $reonar['chan.name']); + + if($reonar['chan.did1']) + set_aconfig($ac['account']['account_id'], 'register', 'channel_address', $reonar['chan.did1']); + + $permissions_role = get_config('system','default_permissions_role'); + if($permissions_role) + set_aconfig($ac['account']['account_id'], 'register', 'permissions_role', $permissions_role); + + // create channel + $new_channel = auto_channel_create($ac['account']['account_id']); + + if($new_channel['success']) { + $rc .= ' c,ok' . $new_channel['channel']['channel_id'] . '✔'; + } + else { + $rc .= ' c ×'; + } + } + + + } + } else { + $rc='oh ×'; + } + } + echo json_encode(array('re' => $zarop, 'at' => '_' . $zarat, 'rc' => $rc)); + } + killme(); + exit; + } + // change to switch structure? // account block/unblock button was submitted if (x($_POST, 'page_accounts_block')) { @@ -55,7 +146,7 @@ class Accounts { account_deny($hash); } } - + goaway(z_root() . '/admin/accounts' ); } @@ -75,19 +166,21 @@ class Accounts { $account = q("SELECT * FROM account WHERE account_id = %d", intval($uid) ); - + if (! $account) { notice( t('Account not found') . EOL); goaway(z_root() . '/admin/accounts' ); } - + check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't'); - + + $debug = ''; + switch (argv(2)){ case 'delete': // delete user account_remove($uid,true,false); - + notice( sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL); break; case 'block': @@ -95,7 +188,7 @@ class Accounts { intval(ACCOUNT_BLOCKED), intval($uid) ); - + notice( sprintf( t("Account '%s' blocked") , $account[0]['account_email']) . EOL); break; case 'unblock': @@ -103,27 +196,61 @@ class Accounts { intval(ACCOUNT_BLOCKED), intval($uid) ); - + notice( sprintf( t("Account '%s' unblocked"), $account[0]['account_email']) . EOL); break; } - + goaway(z_root() . '/admin/accounts' ); } - - /* get pending */ - $pending = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d )>0 ", - intval(ACCOUNT_PENDING) - ); - + + $tao = 'tao.zar.zarax = ' . "'" . '<img src="' . z_root() . '/images/zapax16.gif">' . "';\n"; + + $pending = get_pending_accounts(); + + unset($_SESSION[self::MYP]); + if ($pending) { + // collect and group all ip + $atips = q("SELECT reg_atip AS atip, COUNT(reg_atip) AS atips FROM register " + ." WHERE reg_vital = 1 GROUP BY reg_atip "); + $atips ? $atipn = array_column($atips, 'atips', 'atip') : $atipn = array('' => 0); + + $tao .= 'tao.zar.zarar = {'; + foreach ($pending as $n => $v) { + + $stuff = json_decode($v['reg_stuff'], true); + + if(isset($stuff['msg'])) { + $pending[$n]['msg'] = $stuff['msg']; + } + + if (array_key_exists($v['reg_atip'], $atipn)) { + $pending[$n]['reg_atip'] = $v['reg_atip']; + $pending[$n]['reg_atip_n'] = $atipn[$v['reg_atip']]; + } + + // timezone adjust date_time for display + $pending[$n]['reg_created'] = datetime_convert('UTC', date_default_timezone_get(), $pending[$n]['reg_created']); + $pending[$n]['reg_startup'] = datetime_convert('UTC', date_default_timezone_get(), $pending[$n]['reg_startup']); + $pending[$n]['reg_expires'] = datetime_convert('UTC', date_default_timezone_get(), $pending[$n]['reg_expires']); + + // better secure + $tao .= $n . ": '" . substr(bin2hex($v['reg_hash']),0,8) . "',"; + $_SESSION[self::MYP]['h'][] = substr($v['reg_hash'],0,4); + $_SESSION[self::MYP]['i'][] = $v['reg_id']; + } + $tao = rtrim($tao,',') . '};' . "\n"; + } + // <- hilmar] + /* get accounts */ - + $total = q("SELECT count(*) as total FROM account"); if (count($total)) { \App::set_pager_total($total[0]['total']); \App::set_pager_itemspage(100); } - + $serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : ''); $key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id'); @@ -134,8 +261,8 @@ class Accounts { $base = z_root() . '/admin/accounts?f='; $odir = (($dir === 'asc') ? '0' : '1'); - $users = q("SELECT account_id , account_email, account_lastlog, account_created, account_expires, account_service_class, ( account_flags & %d ) > 0 as blocked, - (SELECT %s FROM channel as ch WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as channels FROM account as ac + $users = q("SELECT account_id , account_email, account_lastlog, account_created, account_expires, account_service_class, ( account_flags & %d ) > 0 as blocked, + (SELECT %s FROM channel as ch WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as channels FROM account as ac where true $serviceclass and account_flags != %d order by $key $dir limit %d offset %d ", intval(ACCOUNT_BLOCKED), db_concat('ch.channel_address', ' '), @@ -143,15 +270,15 @@ class Accounts { intval(\App::$pager['itemspage']), intval(\App::$pager['start']) ); - + // function _setup_users($e){ // $accounts = Array( - // t('Normal Account'), + // t('Normal Account'), // t('Soapbox Account'), // t('Community/Celebrity Account'), // t('Automatic Friend Account') // ); - + // $e['page_flags'] = $accounts[$e['page-flags']]; // $e['register_date'] = relative_date($e['register_date']); // $e['login_date'] = relative_date($e['login_date']); @@ -159,49 +286,56 @@ class Accounts { // return $e; // } // $users = array_map("_setup_users", $users); - + $t = get_markup_template('admin_accounts.tpl'); $o = replace_macros($t, array( // strings // + '$debug' => $debug, '$title' => t('Administration'), '$page' => t('Accounts'), '$submit' => t('Submit'), '$select_all' => t('select all'), - '$h_pending' => t('Registrations waiting for confirm'), - '$th_pending' => array( t('Request date'), t('Email') ), - '$no_pending' => t('No registrations.'), + '$sel_tall' => t('Select toggle'), + '$sel_deny' => t('Deny selected'), + '$sel_aprv' => t('Approve selected'), + '$h_pending' => t('Verified registrations waiting for approval'), + '$th_pending' => array(t('Request date'), 'dId2', t('Email'), 'IP', t('Requests')), + '$no_pending' => t('No verified registrations.'), '$approve' => t('Approve'), '$deny' => t('Deny'), '$delete' => t('Delete'), '$block' => t('Block'), '$unblock' => t('Unblock'), + '$verified' => t('Verified'), + '$not_verified' => t('Not yet verified'), '$odir' => $odir, '$base' => $base, '$h_users' => t('Accounts'), - '$th_users' => array( + '$th_users' => array( [ t('ID'), 'account_id' ], [ t('Email'), 'account_email' ], - [ t('All Channels'), 'channels' ], + [ t('All channels'), 'channels' ], [ t('Register date'), 'account_created' ], [ t('Last login'), 'account_lastlog' ], [ t('Expires'), 'account_expires' ], - [ t('Service Class'), 'account_service_class'] ), - - '$confirm_delete_multi' => t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?'), - '$confirm_delete' => t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?'), - + [ t('Service class'), 'account_service_class'] ), + + '$confirm_delete_multi' => p2j(t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?')), + '$confirm_delete' => p2j(t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?')), + '$form_security_token' => get_form_security_token("admin_accounts"), - + // values // - '$baseurl' => z_root(), - - '$pending' => $pending, - '$users' => $users, + '$baseurl' => z_root(), + '$tao' => $tao, + '$pending' => $pending, + '$users' => $users, + '$msg' => t('Message') )); $o .= paginate($a); - + return $o; } - } + diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php index 011bf3ce4..8a7bb1180 100644 --- a/Zotlabs/Module/Admin/Site.php +++ b/Zotlabs/Module/Admin/Site.php @@ -5,14 +5,28 @@ namespace Zotlabs\Module\Admin; class Site { + // system cfgs + const ivo = 'invitation_only'; + const iva = 'invitation_also'; + /** * @brief POST handler for Admin Site Page. * */ function post(){ + // [hilmar-> + $this->isajax = is_ajax(); + $this->eol = $this->isajax ? "\n" : EOL; + // ] if (!x($_POST, 'page_site')) { - return; + // [ + if (!$this->isajax) + // ] + return; } + // [ + $this->msgbg = ''; + // <-hilmar] check_form_security_token_redirectOnErr('/admin/site', 'admin_site'); @@ -24,14 +38,17 @@ class Site { $siteinfo = ((x($_POST,'siteinfo')) ? trim($_POST['siteinfo']) : ''); $language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : ''); $theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : ''); -// $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : ''); -// $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : ''); + // $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : ''); + // $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : ''); $maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0); $register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0); + $register_wo_email = ((x($_POST,'register_wo_email')) ? intval(trim($_POST['register_wo_email'])) : 0); $minimum_age = ((x($_POST,'minimum_age')) ? intval(trim($_POST['minimum_age'])) : 13); $access_policy = ((x($_POST,'access_policy')) ? intval(trim($_POST['access_policy'])) : 0); - $invite_only = ((x($_POST,'invite_only')) ? True : False); + $reg_autochannel = ((x($_POST,'auto_channel_create')) ? True : False); + $invitation_only = ((x($_POST,'invitation_only')) ? True : False); + $invitation_also = ((x($_POST,'invitation_also')) ? True : False); $abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0); $register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : ''); @@ -75,6 +92,16 @@ class Site { $maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50); $feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0); $verify_email = ((x($_POST,'verify_email')) ? 1 : 0); + $register_perday = ((x($_POST,'register_perday')) ? intval(trim($_POST['register_perday'])) : 50); + $register_sameip = ((x($_POST,'register_sameip')) ? intval(trim($_POST['register_sameip'])) : 3); + + $regdelayn = ((x($_POST,'zardelayn')) ? intval(trim($_POST['zardelayn'])) : 0); + $regdelayu = ((x($_POST,'zardelay')) ? notags(trim($_POST['zardelay'])) : ''); + $reg_delay = (preg_match('/^[a-z]{1,1}$/', $regdelayu) ? $regdelayn . $regdelayu : ''); + $regexpiren = ((x($_POST,'zarexpiren')) ? intval(trim($_POST['zarexpiren'])) : 0); + $regexpireu = ((x($_POST,'zarexpire')) ? notags(trim($_POST['zarexpire'])) : ''); + $reg_expire = (preg_match('/^[a-z]{1,1}$/', $regexpireu) ? $regexpiren . $regexpireu : ''); + $imagick_path = ((x($_POST,'imagick_path')) ? trim($_POST['imagick_path']) : ''); $force_queue = ((intval($_POST['force_queue']) > 0) ? intval($_POST['force_queue']) : 3000); $pub_incl = escape_tags(trim($_POST['pub_incl'])); @@ -82,6 +109,35 @@ class Site { $permissions_role = escape_tags(trim($_POST['permissions_role'])); + // [hilmar-> + $this->register_duty = ((x($_POST,'register_duty')) ? notags(trim($_POST['register_duty'])) : ''); + if (! preg_match('/^[0-9 .,:\-]{0,191}$/', $this->register_duty)) { + $this->msgbg .= 'ZAR0131E,' . t('Invalid input') . $this->eol; + $this->error++; + } else { + + $this->duty(); + + if ($this->isajax) { + echo json_encode(array('msgbg' => $this->msgbg, 'me' => 'zar')); + // that mission is complete + killme(); + exit; + + } else { + + //logger( print_r( $this->msgbg, true) ); + //logger( print_r( $this->joo, true) ); + if ($this->error === 0) { + set_config('system', 'register_duty', $this->register_duty); + set_config('system', 'register_duty_jso', $this->joo); + } else { + notice('ZAR0130E,'.t('Errors') . ': ' . $this->error) . EOL . $this->msgfg; + } + } + } + // <-hilmar] + set_config('system', 'feed_contacts', $feed_contacts); set_config('system', 'delivery_interval', $delivery_interval); set_config('system', 'delivery_batch_count', $delivery_batch_count); @@ -96,6 +152,10 @@ class Site { set_config('system', 'login_on_homepage', $login_on_homepage); set_config('system', 'enable_context_help', $enable_context_help); set_config('system', 'verify_email', $verify_email); + set_config('system', 'max_daily_registrations', $register_perday); + set_config('system', 'register_sameip', $register_sameip); + set_config('system', 'register_delay', $reg_delay); + set_config('system', 'register_expire', $reg_expire); set_config('system', 'default_expire_days', $default_expire_days); set_config('system', 'active_expire_days', $active_expire_days); set_config('system', 'reply_address', $reply_address); @@ -126,17 +186,20 @@ class Site { set_config('system','siteinfo',$siteinfo); set_config('system', 'language', $language); set_config('system', 'theme', $theme); -// if ( $theme_mobile === '---' ) { -// del_config('system', 'mobile_theme'); -// } else { -// set_config('system', 'mobile_theme', $theme_mobile); -// } - // set_config('system','site_channel', $site_channel); + // if ( $theme_mobile === '---' ) { + // del_config('system', 'mobile_theme'); + // } else { + // set_config('system', 'mobile_theme', $theme_mobile); + // } + // set_config('system','site_channel', $site_channel); set_config('system','maximagesize', $maximagesize); set_config('system','register_policy', $register_policy); + set_config('system','register_wo_email', $register_wo_email); set_config('system','minimum_age', $minimum_age); - set_config('system','invitation_only', $invite_only); + set_config('system','auto_channel_create', $reg_autochannel); + set_config('system',self::ivo, $invitation_only); + set_config('system',self::iva, $invitation_also); set_config('system','access_policy', $access_policy); set_config('system','account_abandon_days', $abandon_days); set_config('system','register_text', $register_text); @@ -260,6 +323,9 @@ class Site { REGISTER_APPROVE => t("Yes - with approval"), REGISTER_OPEN => t("Yes") ); + $this->register_duty ? get_config('system', 'register_duty') : ''; + $register_perday = get_config('system','max_daily_registrations'); + $register_perday ? '' : $register_perday = 50; /* Acess policy */ $access_choices = Array( @@ -286,9 +352,70 @@ class Site { $homelogin = get_config('system','login_on_homepage'); $enable_context_help = get_config('system','enable_context_help'); + // for reuse reg_delay and reg_expire + $reg_rabots = array( + 'i' => t('Minute(s)'), + 'h' => t('Hour(s)') , + 'd' => t('Day(s)') , + 'w' => t('Week(s)') , + 'm' => t('Month(s)') , + 'y' => t('Year(s)') + ); + $regdelay_n = $regdelay_u = false; + $regdelay = get_config('system','register_delay'); + if ($regdelay) + list($regdelay_n, $regdelay_u) = array(substr($regdelay,0,-1),substr($regdelay,-1)); + $reg_delay = replace_macros(get_markup_template('field_duration.qmc.tpl'), + array( + 'label' => t('Account registration delay'), + 'qmc' => 'zar', + 'qmcid' => 'ZAR0860C', + 'help' => t('How long a registration request has to wait before validation can perform.' + . ' No delay if zero or no value.'), + 'field' => array( + 'name' => 'delay', + 'title' => t('duration up from now'), + 'value' => ($regdelay_n === false ? 0 : $regdelay_n), + 'min' => '0', + 'max' => '99', + 'size' => '2', + 'default' => ($regdelay_u === false ? 'i' : $regdelay_u) + ), + 'rabot' => $reg_rabots + ) + ); + $regexpire_n = $regexpire_u = false; + $regexpire = get_config('system','register_expire'); + if ($regexpire) + list($regexpire_n, $regexpire_u) = array(substr($regexpire,0,-1),substr($regexpire,-1)); + $reg_expire = replace_macros(get_markup_template('field_duration.qmc.tpl'), + array( + 'label' => t('Account registration expiration'), + 'qmc' => 'zar', + 'qmcid' => 'ZAR0862C', + 'help' => t('How long a registration to confirm remains valid.' + . ' Not expire if zero or no value.'), + 'field' => array( + 'name' => 'expire', + 'title' => t('duration up from now'), + 'value' => ($regexpire_n === false ? 99 : $regexpire_n), + 'min' => '0', + 'max' => '99', + 'size' => '2', + 'default' => ($regexpire_u === false ? 'y' : $regexpire_u) + ), + 'rabot' => $reg_rabots + ) + ); + $invitation_only = get_config('system',self::ivo); + $invitation_also = get_config('system',self::iva); + + $tao = ''; $t = get_markup_template("admin_site.tpl"); return replace_macros($t, array( '$title' => t('Administration'), + // interfacing js vars + '$tao' => $tao, '$page' => t('Site'), '$submit' => t('Submit'), '$registration' => t('Registration'), @@ -305,21 +432,96 @@ class Site { '$siteinfo' => array('siteinfo', t('Site Information'), get_config('system','siteinfo'), t("Publicly visible description of this site. Displayed on siteinfo page. BBCode can be used here")), '$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices), '$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices), -// '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile), -// '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")), + // '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile), + // '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")), '$feed_contacts' => array('feed_contacts', t('Allow Feeds as Connections'),get_config('system','feed_contacts'),t('(Heavy system resource usage)')), '$maximagesize' => array('maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")), - '$register_policy' => array('register_policy', t("Does this site allow new member registration?"), get_config('system','register_policy'), "", $register_choices), - '$invite_only' => array('invite_only', t("Invitation only"), get_config('system','invitation_only'), t("Only allow new member registrations with an invitation code. Above register policy must be set to Yes.")), '$minimum_age' => array('minimum_age', t("Minimum age"), (x(get_config('system','minimum_age'))?get_config('system','minimum_age'):13), t("Minimum age (in years) for who may register on this site.")), '$access_policy' => array('access_policy', t("Which best describes the types of account offered by this hub?"), get_config('system','access_policy'), t("This is displayed on the public server site list."), $access_choices), - '$register_text' => array('register_text', t("Register text"), htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")), + + // Register + // [hilmar-> + '$register_text' => array('register_text', + t("Register text"), + htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'), + t("Will be displayed prominently on the registration page.") . ' ' + . t('If you operate with register duties (see ZAR0830C), best practise is to tell cleartext about here'), + 'ZAR0810C'), + '$register_policy' => array('register_policy', + t("Does this site allow new member registration?"), + get_config('system','register_policy'), + "", + $register_choices, + 'ZAR0820C'), + '$register_wo_email' => array('register_wo_email', + t("Registration is also possible without having to enter an email address."), + get_config('system','register_wo_email'), + t("Registration is also supported without requiring an email address from the applicant. Instead of the email address an artificial identification is generated, which has to be confirmed in a separate dialog. The default value is (Off) and corresponds to the registration procedure up to version 5.4.x."), + "", "", 'ZAR0824C'), + + '$register_duty' => array('register_duty', + t('Registration office on duty'), + $this->register_duty = get_config('system', 'register_duty'), + t('The weekdays and hours the register office is open for registrations') . '. ' + . t('Split weekdays and hours per `:`') . '. ' + . t('Separate weekday(s):hour(s) pairs with blank(s)') . '. ' + . t('Several values or ranges are to split by comma') . '. ' + . t('From-To ranges are joined with `-`') . '. ' + . t('ie') . ' `1-5:0900-1200,1300-1700 6:900-1230` ' . t('or') .' `1-2,4-5:800-1800` ' + . EOL . ' <a id="zar083a" class="zuia btn">' . t('Parse and test your input') . '</a>'. EOL + . t('If left empty, defaults to 24h open everyday the week (-:-).') . ' ' + . t('Note, ranges are specified as open-close pairs and in case of') + . ' 0900-1200 ' + . t('results to: opens 9h and closes 12h. If meant open 9h to 12h exactly, say `0900-1201`'), + 'ZAR0830C'), + '$register_perday' => array('register_perday', + t('Account registrations max per day'), + (x(get_config('system', 'max_daily_registrations'))) + ? get_config('system', 'max_daily_registrations') : 50, + t('How many registration requests the site accepts during one day. Unlimited if zero or no value. Default 50'), + 'ZAR0840C'), + '$register_sameip' => array('register_sameip', + t('Account registrations from same ip'), + (x(get_config('system', 'register_sameip'))) + ? get_config('system', 'register_sameip') : 3, + t('How many pending registration requests the site accepts from a same ip address.'), + 'ZAR0850C'), + '$reg_delay'=>$reg_delay, + '$reg_expire'=>$reg_expire, + '$reg_autochannel' => array('auto_channel_create', + t("Auto channel create"), + get_config('system','auto_channel_create', 1), + t("Auto create a channel when register a new account. When On, the register form will show additional fields for the channel-name and the nickname."), + "", "", 'ZAR0870C'), + + '$invitation_only' => array(self::ivo, + ($invitation_only === false ? '✗' : '✓') . ' ' . t("Invitation only"), + $invitation_only, + t("Only allow new member registrations with an invitation code. Above register policy must be set to Yes."), + "", "", 'ZAR0880C'), + + '$invitation_also' => array(self::iva, + ($invitation_also === false ? '✗' : '✓') . ' ' . t("Invitation also"), + $invitation_also, + t("Also allow new member registrations with an invitation code. Above register policy must be set to Yes."), + "", "", 'ZAR0881C'), + + '$verify_email' => array('verify_email', + t("Verify Email Addresses"), + get_config('system','verify_email'), + t("Check to verify email addresses used in account registration (recommended)."), + "", "", 'ZAR0890C'), + '$abandon_days' => array('abandon_days', + t('Accounts abandoned after x days'), + get_config('system','account_abandon_days'), + t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.') + ), + // <-hilmar] + '$role' => $role, '$frontpage' => array('frontpage', t("Site homepage to show visitors (default: login box)"), get_config('system','frontpage'), t("example: 'pubstream' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file.")), '$mirror_frontpage' => array('mirror_frontpage', t("Preserve site homepage URL"), get_config('system','mirror_frontpage'), t('Present the site homepage in a frame at the original location instead of redirecting')), - '$abandon_days' => array('abandon_days', t('Accounts abandoned after x days'), get_config('system','account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')), '$allowed_sites' => array('allowed_sites', t("Allowed friend domains"), get_config('system','allowed_sites'), t("Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains")), - '$verify_email' => array('verify_email', t("Verify Email Addresses"), get_config('system','verify_email'), t("Check to verify email addresses used in account registration (recommended).")), '$force_publish' => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")), '$disable_discover_tab' => array('disable_discover_tab', t('Import Public Streams'), $discover_tab, t('Import and allow access to public content pulled from other sites. Warning: this content is unmoderated.')), '$site_firehose' => array('site_firehose', t('Site only Public Streams'), get_config('system','site_firehose'), t('Allow access to public content originating only from this site if Imported Public Streams are disabled.')), @@ -350,15 +552,187 @@ class Site { '$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")), '$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')), '$active_expire_days' => array('active_expire_days', t('Do not expire any posts which have comments less than this many days ago'), intval(get_config('system','active_expire_days',7)), ''), - '$sellpage' => array('site_sellpage', t('Public servers: Optional landing (marketing) webpage for new registrants'), get_config('system','sellpage',''), sprintf( t('Create this page first. Default is %s/register'),z_root())), '$first_page' => array('first_page', t('Page to display after creating a new channel'), get_config('system','workflow_channel_next','profiles'), t('Default: profiles')), - '$location' => array('site_location', t('Optional: site location'), get_config('system','site_location',''), t('Region or country')), - - '$form_security_token' => get_form_security_token("admin_site"), )); } + /** + * @brief Admin page site common post submit and ajax interaction + * @author hilmar runge + * @since 2020-02-04 + * Configure register office duty weekdays and hours + * Syntax: weekdays:hours [weekdays:hours] + * [.d[,d-d.]]]:hhmm-hhmm[,hhmm-hhmm...] + * ranges are between blanks, days are 1-7, where 1 = Monday + * hours are [h]hmm 3-4digit 24 clock values + * ie 0900-1200,1300-1800 for hours + * ie 1-2,4,5 for weekdays + * ie 1-2:900-1800 monday and tuesday open from 9 to 18h + * + * @var $register_duty is the input field from the admin -> site page + * @return the results are in the class vars $error, $msgbg and $jsoo + * $jsoo is + */ + + // 3-4 digit 24h clock regex + const regxTime34 = '/^(?:2[0-3]|[01][0-9]|[0-9])[0-5][0-9]$/'; + var $wdconst = array('','mo','tu','we','th','fr','sa','so'); + + // in + var $register_duty; + // intermediate + var $isajax; + // return + var $jsoo; + var $msgbg; + var $error = 0; + var $msgfg = ''; + + private function duty() { + + $aro=array_fill(1, 7, 0); + + if ($this->isajax) { + $op = (preg_match('/[a-z]{2,4}/', $_REQUEST['zarop'])) ? $_REQUEST['zarop'] : ''; + if ($op == 'zar083') { + $this->msgbg = 'ZAR0130I Testmode:' . $this->eol . $this->msgbg; + } else { + killme(); + exit; + } + } + + if (! $this->register_duty) + $this->register_duty = '-:-'; + + $ranges = preg_split('/\s+/', $this->register_duty); + $this->msgbg .= '..ranges: ' . print_r(count($ranges),true) . $this->eol; + + foreach ($ranges as $rn => $range) { + list($ws,$hs,) = explode(':', $range); + + $ws ? $arw = explode( ',', $ws) : $arw=array(); + $this->msgbg .= ($rn+1).'.weekday ranges: ' . count($arw) . $this->eol; + // $this->msgbg .= print_r($arw,true); + $hs ? $arh = explode( ',', $hs) : $arh=array(); + $this->msgbg .= ($rn+1).'.hour ranges: ' . count($arh) . $this->eol; + + $this->msgbg .= ($rn+1).'.wdays: ' . ( $ws ? print_r($ws,true) : 'none') . ' : ' + . ' hours: ' . print_r($hs,true) . $this->eol; + + // several hs may belog to one wd + // aro[0] is tmp store + foreach ($arh as $hs) { + list($ho,$hc,) = explode( '-', $hs ); + + // no value forces open very early, and be sure having valid hhmm values + !$ho ? $ho = "0000" : ''; + !$hc ? $hc = "0000" : ''; // pseudo + if (preg_match(self::regxTime34, $ho) + && preg_match(self::regxTime34, $hc)) { + + // fix pseudo, allow no reverse range + $hc == "0000" || $ho > $hc ? $hc = "2400" : ''; + + $aro[0][$ho] = 0; + $aro[0][$hc] = 1; + + $this->msgbg .= ($ho ? ' .open:' . $ho : '') . ($hc ? ' close:' . $hc : '') .$this->eol; + } else { + $this->msgbg .= ' .' . t('Invalid 24h time value (hhmm/hmm)') . $this->eol; + $this->msgfg .= ' .ZAR0132E,' . t('Invalid 24h time value (hhmm/hmm)') . $this->eol; + $this->error++; + } + } + + // the weekday(s) values or ranges + foreach ($arw as $ds) { + $wd=explode('-', $ds); + array_key_exists("1", $wd) && $wd[1]=="" ? $wd[1] = "7" : ''; // a case 3- + array_key_exists("1", $wd) && $wd[0]=="" ? $wd[0] = "1" : ''; // a case -3 + !array_key_exists("1", $wd) ? $wd[1] = $wd[0] : ''; // a case 3 + if ($wd[0] > $wd[1]) continue; // reverse order will be ignored // a case 5-3 + if (preg_match('/^[1-7]{1}$/', $wd[0])) { + if (preg_match('/^[1-7]{1}$/', $wd[1])) { + // $this->msgbg .= print_r($wd,true); + for ($i=$wd[0]; $i<=$wd[1]; $i++) { + // take the tmp store for the selected day(s) + $aro[$i]=$aro[0]; + } + } + } + } + //$this->msgbg .= 'aro0: ' . print_r($aro,true) . $this->eol; // 4devels + // clear the tmp store + $aro[0]=array(); + } + // discart the tmp store + unset($aro[0]); + // not configured days close at the beginning 0000h + for ($i=1;$i<=7;$i++) { is_array($aro[$i]) ? '' : $aro[$i] = array("0000" => 1); } + // $this->msgbg .= 'aro: ' . print_r($aro,true) . $this->eol; // 4devels + + if ($this->isajax) { + // tell what we have + // $this->msgbg .= 'aro0: ' . print_r($aro,true) . $this->eol; // 4devels + $this->msgbg .= 'Duty time table:' . $this->eol; + foreach ($aro as $dow => $hrs) { + $this->msgbg .= ' ' . $this->wdconst[$dow] . ' '; + // $this->msgbg .= '**' . print_r($hrs,true); + foreach ($hrs as $h => $o) { + $this->msgbg .= ((!$o) ? $h . ':open' : $h . ':close') . ', '; + } + $this->msgbg = rtrim($this->msgbg, ', ') . $this->eol; + } + + $this->msgbg .= 'Generating 6 random times to check duty hours: ' . $this->eol; + // we only need some random dates from anyway in past or future + // because only the weekday and the clock is to test + for ($i=0; $i<6; $i++) { + $adow = rand(1, 7); // 1 to 7 (days) + $cdow = $this->wdconst[$adow]; + // below is the essential algo to verify a date (of format Hi) meets an open or closed condition + $t = date('Hi', ( rand(time(), 60*60*24+time()) ) ); + $how='closed'; + foreach ($aro[$adow] as $o => $v) { + // $this->msgbg .= 'debug: ' . $o . ' gt ' . $t . ' / ' . $v . $this->eol; // 4devels + if ($o > $t) { + $how = ($v ? 'open' : 'closed'); + break; + } + } + // now we know + $this->msgbg .= ' ' . $cdow . '.' . $t . '=' . $how . ', '; + } + $this->msgbg = rtrim($this->msgbg, ', ') . $this->eol; + } + + /* + //$jov1 = array( 'view1' => $aro, 'view2' => ''); + $jov2=array(); + foreach ($aro as $d => $ts) { + foreach ($ts as $t => $ft) { + $jov2['view2'][$ft][] = $d.$t; + //$ft=="1" && $t=="0000" ? $jov2['view2']["0"][] = $d."2400" : ''; + } + } + $this->msgbg .= print_r($jov2, true) . $this->eol; // 4devels + */ + + $this->joo = json_encode($aro); + // $this->msgbg .= $this->joo . $this->eol; // 4devels + // $this->msgbg .= print_r($aro, true) . $this->eol; // 4devels + $okko = (json_decode($this->joo, true) ? true : false); + if (!$okko) { + $this->msgbg .= 'ZAR0139D,json 4 duty KO crash' . $this->eol; + $this->msgfg .= 'ZAR0139D,json 4 duty KO crash' . $this->eol; + $this->error++; + } + return ; + } + + } |