✏️ 正在编辑: Inputs.php
路径:
/home/eblama1/sms.karnplayinland.com/functions/Inputs.php
提示:
您可以编辑任何文件(包括二进制文件),但请注意不当修改可能导致文件损坏。
<?php /** * Input functions * * @package RosarioSIS * @subpackage functions */ /** * Date Input * * @example DateInput( DBDate(), '_values[CATEGORY_' . $category['ID'] . ']' ) * * @uses PrepareDate() to display Month / Day / Year Select fields + JSCalendar integration * * @uses GetInputID() to generate ID from name * @uses FormatInputTitle() to format title * @uses InputDivOnclick() * if ( AllowEdit() && !isset( $_REQUEST['_ROSARIO_PDF'] ) && $value != '' && $div ) * * @param string $value Input value. * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * @param boolean $allow_na Allow N/A (empty value) (optional). Defaults to true. * @param boolean $required Required date fields (optional). Defaults to false. * * @return string Input HTML */ function DateInput( $value, $name, $title = '', $div = true, $allow_na = true, $required = false ) { $id = GetInputID( $name ); $ftitle = FormatInputTitle( $title, '', $value == '' && $required ); if ( ! AllowEdit() || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return ( $value != '' ? ProperDate( $value ) : '-' ) . FormatInputTitle( $title ); } $options = [ 'required' => $required, ]; if ( $value == '' || ! $div ) { return PrepareDate( $value, '_' . $name, $allow_na, $options ) . $ftitle; } $options = $options + [ 'Y' => 1, 'M' => 1, 'D' => 1 ]; $input = PrepareDate( $value, '_' . $name, $allow_na, $options ) . $ftitle; return InputDivOnclick( $id, $input, ( $value != '' ? ProperDate( $value ) : '-' ), FormatInputTitle( $title ) ); } /** * Text Input * * @example TextInput( Config( 'NAME' ), 'values[config][NAME]', _( 'Program Name' ), 'required' ) * * @uses GetInputID() to generate ID from name * @uses FormatInputTitle() to format title * @uses InputDivOnclick() * if ( AllowEdit() && !isset( $_REQUEST['_ROSARIO_PDF'] ) && $value != '' && $div ) * * @param string $value Input value. * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param string $extra Extra HTML attributes added to the input. * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * * @return string Input HTML */ function TextInput( $value, $name, $title = '', $extra = '', $div = true ) { $id = GetInputID( $name ); // mab - support array style $option values $display_val = is_array( $value ) ? $value[1] : $value; $value = is_array( $value ) ? $value[0] : $value; $required = $value == '' && mb_strpos( $extra, 'required' ) !== false; if ( ! AllowEdit() || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return ( $value != '' ? $display_val : '-' ) . FormatInputTitle( $title ); } // Input size / length based on value number of chars if ( mb_strpos( $extra, 'size=' ) === false ) { // Max size is 32 (more or less 300px) $size = min( mb_strlen( (string) $value ), 32 ); // Min size is 2 (more or less 35px) $size = max( $size, 2 ); $extra .= $value != '' ? ' size="' . $size . '"' : ' size="12"'; } // Specify input type via $extra (email,...). $type = mb_strpos( $extra, 'type=' ) === false ? 'type="text"' : ''; $input = '<input ' . $type . ' id="' . $id . '" name="' . AttrEscape( $name ) . '" value="' . AttrEscape( $value ) . '" ' . $extra . '>' . FormatInputTitle( $title, $id, $required ); if ( is_null( $value ) || trim( $value ) == '' || ! $div ) { return $input; } return InputDivOnclick( $id, $input, ( $value != '' ? $display_val : '-' ), FormatInputTitle( $title ) ); } /** * Password Input * * @example echo PasswordInput( '********', 'PASSWORD', _( 'Password' ), 'required strength' ); * * @since 4.4 * @since 5.5.1 Fill input value if $value != '********'. * @since 11.1 Prevent using App name, username, or email in the password * * @global $_ROSARIO['PasswordInput']['user_inputs'] used in PasswordReset.php, FirstLogin.fnc.php & Preferences.php * * @uses GetInputID() to generate ID from name * @uses FormatInputTitle() to format title * @uses InputDivOnclick() * if ( AllowEdit() && !isset( $_REQUEST['_ROSARIO_PDF'] ) && $value != '' && $div ) * @uses TextInput * * @param string $value Input value. * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param string $extra Extra HTML attributes. Pass 'strength' to display strength indicator. * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * * @return string Input HTML */ function PasswordInput( $value, $name, $title = '', $extra = '', $div = true ) { global $_ROSARIO; $id = GetInputID( $name ); $strength = ( mb_strpos( $extra, 'strength' ) !== false ); // mab - support array style $option values $display_val = is_array( $value ) ? $value[1] : $value; $value = is_array( $value ) ? $value[0] : $value; $required = $value == '' && mb_strpos( $extra, 'required' ) !== false; if ( ! AllowEdit() || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return ( $value != '' ? $display_val : '-' ) . FormatInputTitle( $title ); } // Default input size. if ( $value == '' && mb_strpos( $extra, 'size=' ) === false ) { $extra .= ' size="17"'; } elseif ( mb_strpos( $extra, 'size=' ) === false ) { $extra .= ' size="' . ( strlen( $value ) + 5 ) . '"'; } $extra .= ' type="password" autocomplete="new-password"'; $input = TextInput( ( $value !== str_repeat( '*', 8 ) ? $value : '' ), $name, '', $extra, false ); $lock_icons = button( 'unlocked', '', '', 'password-toggle password-show' ) . button( 'locked', '', '', 'password-toggle password-hide' ); $password_strength_bars = ''; $min_required_strength = $strength ? Config( 'PASSWORD_STRENGTH' ) : 0; if ( $strength && $min_required_strength ) { $password_strength_bars = '<div class="password-strength-bars"> <span class="score0"></span> <span class="score1"></span> <span class="score2"></span> <span class="score3"></span> <span class="score4"></span> </div>'; } // @since 11.1 Prevent using App name, username, or email in the password $user_inputs = array_merge( [ Config( 'NAME' ) ], // Add username & email to this global var before calling PasswordInput(). issetVal( $_ROSARIO['PasswordInput']['user_inputs'], [] ) ); ob_start(); // Call our jQuery PasswordStrength plugin based on zxcvbn. ?> <script> $('#' + <?php echo json_encode( $id ); ?>).passwordStrength( <?php echo (int) $min_required_strength; ?>, // Error message when trying to submit the form. <?php echo json_encode( _( 'Your password must be stronger.' ) ); ?>, <?php echo json_encode( $user_inputs ); ?> ); </script> <?php $password_strength_js = ob_get_clean(); $input .= $lock_icons . $password_strength_bars . FormatInputTitle( $title, $id, $required ) . $password_strength_js; $input = '<div class="password-input-wrapper">' . $input . '</div>'; if ( is_null( $value ) || trim( $value ) == '' || ! $div ) { return $input; } return InputDivOnclick( $id, $input, ( $value != '' ? $display_val : '-' ), FormatInputTitle( $title ) ); } /** * Multi Languages Text Input * * @since 5.5.2 Fix save first language in ML fields if not en_US.utf8. * * @example MLTextInput( Config( 'TITLE' ), 'values[config][TITLE]', _( 'Program Title' ) ) * * @uses GetInputID() to generate ID from name * @uses FormatInputTitle() to format title * * @uses ParseMLField() to get localized options * * @global $RosarioLocales Returns simple TextInput() if only 1 locale set * @global $locale Get current locale * * @param string $value Input value. * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param string $extra Extra HTML attributes added to the input. * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * * @return string Input HTML */ function MLTextInput( $value, $name, $title = '', $extra = '', $div = true ) { global $RosarioLocales, $locale; $value = is_array( $value ) ? $value[0] : $value; if ( count( $RosarioLocales ) < 2 ) { return TextInput( ParseMLField( $value, $locale ), $name, $title, $extra, $div ); } $id = GetInputID( $name ); if ( AllowEdit() && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { // Ng - foreach possible language. ob_start(); ?> <script> function setMLvalue(id, loc, value){ var res = document.getElementById(id).value.split("|"); if (loc === "") { res[0] = value; } else { var found = 0; for ( var i = 1; i < res.length; i++ ) { if (res[i].substring(0, loc.length) == loc) { found = 1; if (value === "") { for ( var j = i + 1; j < res.length; j++ ) res[j - 1] = res[j]; res.pop(); } else { res[i] = loc + ":" + value; } } } if ((found === 0) && (value !== "")) res.push(loc + ":" + value); } document.getElementById(id).value = res.join("|"); } </script> <?php $return = ob_get_clean(); $return .= '<div class="ml-text-input"><input type="hidden" id="' . $id . '" name="' . AttrEscape( $name ) . '" value="' . AttrEscape( $value ) . '" autocomplete="off">'; if ( mb_strpos( $extra, 'size=' ) === false && $value != '' ) { // MLInput size based on current locale value length. $extra .= ' size="' . mb_strlen( ParseMLField( $value ) ) . '"'; } foreach ( (array) $RosarioLocales as $key => $loc ) { $language = function_exists( 'locale_get_display_language' ) ? ucfirst( locale_get_display_language( $loc, $locale ) ) : str_replace( '.utf8', '', $loc ); $return .= '<label><img src="locale/' . $loc . '/flag.png" class="button bigger" alt="' . AttrEscape( $language ) . '" title="' . AttrEscape( $language ) . '"> '; //$return .= TextInput(ParseMLField($value, $loc),'ML_'.$name.'['.$loc.']','',$extra." onchange=\"javascript:setMLvalue('".$name."','".($id==0?'':$loc)."',this.value);\"",false); $onchange_js = 'setMLvalue(' . json_encode( $id ) . ',' . json_encode( $loc ) . ',this.value);'; $return .= TextInput( ParseMLField( $value, $loc ), 'ML_' . $name . '[' . $loc . ']', '', $extra . ( $key == 0 ? ' required' : '' ) . ' onchange="' . AttrEscape( $onchange_js ) . '"', false ); $return .= '</label><br>'; } $return .= '</div>'; $title_break = ''; } else { $return = ParseMLField( $value ); $title_break = '<br>'; } return $return . FormatInputTitle( $title, '', false, $title_break ); } /** * Textarea Input * * @example TextAreaInput( $RET[1]['DESCRIPTION'], 'values[DESCRIPTION]' ) * * @uses GetInputID() to generate ID from name * @uses FormatInputTitle() to format title * @uses InputDivOnclick() * * @uses MarkDownInputPreview() * * @uses ShowDown jQuery plugin for MarkDown rendering called using the .markdown-to-html CSS class * * @param string $value Input value. * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param string $extra Extra HTML attributes added to the input. * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * @param string $type markdown|tinymce|text Text Type (optional). Defaults to 'markdown'. * * @return string Input HTML */ function TextAreaInput( $value, $name, $title = '', $extra = '', $div = true, $type = 'markdown' ) { $id = GetInputID( $name ); $required = $value == '' && mb_strpos( $extra, 'required' ) !== false; $ftitle = FormatInputTitle( $title, $id, $required ); $ftitle_nobr = FormatInputTitle( $title, $id, $required, '' ); if ( $type === 'tinymce' && mb_strpos( (string) $extra, 'required' ) !== false ) { // Remove required attribute, TinyMCE bug. $extra = str_replace( 'required', '', $extra ); } $display_val = '-'; if ( $value != '' ) { $display_val = nl2br( $value ); if ( $type === 'markdown' ) { // Convert MarkDown to HTML. $display_val = '<div class="markdown-to-html">' . $value . '</div>'; } elseif ( $type === 'tinymce' ) { $display_val = '<div class="tinymce-html">' . $value . '</div>'; } } if ( ! AllowEdit() || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return $display_val . ( $type !== 'text' && $display_val !== '-' ? FormatInputTitle( $title, '', false, '' ) : FormatInputTitle( $title ) ); } // Columns. /*if ( mb_strpos( $extra, 'cols' ) === false ) { $extra .= ' cols=30'; $cols = 30; } else $cols = mb_substr( $extra, mb_strpos( $extra, 'cols' ) + 5, 2 ) *1;*/ // Rows. if ( mb_strpos( $extra, 'rows' ) === false ) { $extra .= ' rows=4'; } $textarea = ( $type === 'markdown' ? MarkDownInputPreview( $id ) : '' ) . '<textarea id="' . $id . '" name="' . AttrEscape( $name ) . '" ' . $extra . '>' . // Fix Stored XSS security issue: escape textarea HTML. htmlspecialchars( // Prevent double encoding single quote ('), was encoded by SanitizeHTML() or SanitizeMarkDown() str_replace( ''', "'", (string) $value ) ) . '</textarea>' . ( $type === 'tinymce' ? $ftitle_nobr : $ftitle ); if ( $value == '' || ! $div ) { return $textarea; } return InputDivOnclick( $id, $textarea, $display_val, FormatInputTitle( $title ) ); } /** * TinyMCE Input (HTML editor) * * Note: if you will pass additional CSS classes in the `$extra` parameter * Add the `tinymce-horizontal` class for Horizontal PDF. * Do not forget the `tinymce` class required to trigger TinyMCE. * * @todo Fix <label>, see http://stackoverflow.com/questions/4258701/tinymce-accessibility-label-for * @todo Allow passing options to TinyMCE (plugins, ...) * * @example TinyMCEInput( $RET[1]['TEMPLATE'], 'tinymce_textarea' ) * @example TinyMCEInput( $html, 'tinymce_horizontal', _( 'Horizontal PDF' ), 'class="tinymce-horizontal"' ) * * @uses TextAreaInput() * * @see TinyMCE Javascript plugin for HTML edition in assets/js/tinymce/ * * @since 2.9 * * @global $locale Locale to translate TinyMCE interface. * * @param string $value Input value. * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param string $extra Extra HTML attributes added to the input (optional). Defaults to ''. * * @return string Input HTML */ function TinyMCEInput( $value, $name, $title = '', $extra = '' ) { global $locale; static $js_included = false; $div = false; $wrapper = ''; $extra = 'class="tinymce" ' . $extra; if ( mb_strpos( (string) $extra, 'class=' ) !== false ) { // If has .tinymce-horizontal class, add wrapper, needed here. if ( mb_strpos( (string) $extra, 'tinymce-horizontal' ) !== false ) { $extra = str_replace( 'tinymce-horizontal', '', $extra ); $wrapper = '<div class="tinymce-horizontal">'; } } $textarea = TextAreaInput( $value, $name, $title, $extra, $div, 'tinymce' ); if ( ! AllowEdit() || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return $textarea; } if ( $wrapper ) { $textarea = $wrapper . $textarea . '</div>'; } $tinymce_js = ''; if ( ! $js_included ) { $tinymce_language = ''; $tinymce_directionality = 'ltr'; if ( $locale !== 'en_US.utf8' ) { if ( file_exists( 'assets/js/tinymce/langs/' . mb_substr( $locale, 0, 2 ) . '.js' ) ) { // For example: es (Spanish). $tinymce_language = mb_substr( $locale, 0, 2 ); } elseif ( file_exists( 'assets/js/tinymce/langs/' . mb_substr( $locale, 0, 5 ) . '.js' ) ) { // For example: fr_FR (French). $tinymce_language = mb_substr( $locale, 0, 5 ); } if ( $tinymce_language ) { $lang_2_chars = mb_substr( $locale, 0, 2 ); // Right to left direction. $RTL_languages = [ 'ar', 'he', 'dv', 'fa', 'ur', 'ps' ]; $tinymce_directionality = in_array( $lang_2_chars, $RTL_languages ) ? 'rtl' : 'ltr'; } } // Include main TinyMCE javascript // and its configuration (plugin, language...). ob_start(); ?> <script src="assets/js/tinymce/tinymce.min.js?v=4.9.8"></script> <script> tinymceSettings = { selector: '.tinymce', plugins: 'link image pagebreak paste table textcolor colorpicker code fullscreen hr media lists', toolbar: "bold italic underline bullist numlist alignleft aligncenter alignright alignjustify link image forecolor backcolor code fullscreen", menu: { // file: {title: 'File', items: 'newdocument'}, edit: {title: 'Edit', items: 'undo redo | cut copy paste pastetext'}, insert: {title: 'Insert', items: 'media | hr pagebreak | inserttable cell row column'}, // view: {title: 'View', items: 'visualaid'}, format: {title: 'Format', items: 'formats | removeformat'} }, paste_data_images: true, images_upload_handler: function (blobInfo, success, failure) { success("data:" + blobInfo.blob().type + ";base64," + blobInfo.base64()); }, pagebreak_separator: '<div style="page-break-after: always;"></div>', language: <?php echo json_encode( $tinymce_language ); ?>, directionality : <?php echo json_encode( $tinymce_directionality ); ?>, relative_urls: false, // verify_html: false, remove_script_host: false, external_plugins: { // Add your plugins using the action hook below. } }; </script> <?php /** * TinyMCE before init action hook * * @since 5.3 */ do_action( 'functions/Inputs.php|tinymce_before_init' ); ?> <script> tinymce.init(tinymceSettings); </script><!-- /TinyMCE --> <?php $tinymce_js = ob_get_clean(); $js_included = true; } return $tinymce_js . $textarea; } /** * Adds MarkDown preview to <textarea> input fields * Adds Write & Preview tabs + MD button above the field * * @uses MarkDownInputPreview() Javascript function * @see warehouse.js, and below for AJAX calls handling * @since 2.9 * * @param string $input_id input ID attribute value. * * @return HTML preview link & preview DIV */ function MarkDownInputPreview( $input_id ) { if ( ! $input_id ) { return false; } ob_start(); ?> <div class="md-preview"> <a href="#" onclick="<?php echo AttrEscape( 'MarkDownInputPreview(' . json_encode( $input_id ) . '); return false;' ); ?>" class="tab disabled"><?php echo _( 'Write' ); ?></a> <a href="#" onclick="<?php echo AttrEscape( 'MarkDownInputPreview(' . json_encode( $input_id ) . '); return false;' ); ?>" class="tab"><?php echo _( 'Preview' ); ?></a> <a href="https://gitlab.com/francoisjacquet/rosariosis/wikis/Markdown-Cheatsheet" title="<?php echo AttrEscape( _( 'Mastering MarkDown' ) ); ?>" target="_blank" class="md-link"> <img class="button" src="assets/themes/<?php echo Preferences( 'THEME' ); ?>/btn/md_button.png" alt="<?php echo AttrEscape( _( 'Mastering MarkDown' ) ); ?>"> </a> <div class="markdown-to-html" id="<?php echo GetInputID( 'divMDPreview' . $input_id ); ?>"></div> </div> <?php return ob_get_clean(); } /** * Checkbox Input * * @example CheckboxInput( $value, 'values[' . $id . '][' . $name . ']', '', $value, $id == 'new', button( 'check' ), button( 'x' ) ); * * @uses GetInputID() to generate ID from name * @uses InputDivOnclick() * if ( AllowEdit() && !isset( $_REQUEST['_ROSARIO_PDF'] ) && ! $new && $div ) * * @param string $value Input value. * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param string $checked Deprecated. * @param boolean $new New input (optional). Defaults to false. * @param string $yes Checked value text (optional). Defaults to 'Yes'. * @param string $yes Not checked value text (optional). Defaults to 'No'. * @param string $extra Extra HTML attributes added to the input. * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * * @return string Input HTML */ function CheckboxInput( $value, $name, $title = '', $checked = '', $new = false, $yes = 'Yes', $no = 'No', $div = true, $extra = '' ) { $checked = ''; // $checked has been deprecated -- it remains only as a placeholder. if ( $value && $value !== 'N' ) { $checked = ' checked'; } if ( AllowEdit() && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { $id = GetInputID( $name ); $checkbox = '<input type="hidden" name="' . AttrEscape( $name ) . '" value="">' . // Save unchecked value! '<label class="checkbox-label"> <input type="checkbox" name="' . AttrEscape( $name ) . '" id="' . $id . '" value="Y"' . $checked . ' ' . $extra . '> ' . $title . '</label>'; if ( $new || ! $div ) { return $checkbox; } return InputDivOnclick( $id, $checkbox, ( $value ? ( $yes === 'Yes' ? _( 'Yes' ) : $yes ) : ( $no === 'No' ? _( 'No' ) : $no ) ), ' <span class="checkbox-label">' . $title . '</span>' ); } return ( $value ? ( $yes === 'Yes' || isset( $_REQUEST['LO_save'] ) ? _( 'Yes' ) : $yes ) : ( $no === 'No' || isset( $_REQUEST['LO_save'] ) ? _( 'No' ) : $no ) ) . ( $title !== '' ? ' ' . $title : '' ); } /** * Multiple Checkbox Input * Do not forget to add '[]' (array) after your input name. * * @since 4.2 * @since 4.5 Allow associative $options array. * @since 6.1 Allow numeric key (ID) in associative $options array. * @since 10.8.1 Fix save all unchecked, add hidden empty checkbox * * @example MultipleCheckboxInput( $value, 'values[' . $id . '][' . $name . '][]' ); * * @uses GetInputID() to generate ID from name * @uses InputDivOnclick() * if ( AllowEdit() && !isset( $_REQUEST['_ROSARIO_PDF'] ) && ! $new && $div ) * @uses InputDivOnclick() * * @param string $value Input value(s), delimited by 2 pipes. For example: '||Value1||Value2||'. * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param array $options Input options: array( option_value => option_text ). * @param string $extra Extra HTML attributes added to the input. (optional). * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * * @return string Inputs HTML */ function MultipleCheckboxInput( $value, $name, $title, $options, $extra = '', $div = true ) { $id = GetInputID( $name ); $required = $value == '' && mb_strpos( $extra, 'required' ) !== false; $multiple_value = ( $value != '' ) ? str_replace( '||', ', ', mb_substr( $value, 2, -2 ) ) : '-'; if ( ! AllowEdit() || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return $multiple_value . FormatInputTitle( $title ); } $multiple_html = '<table class="cellspacing-0 cellpadding-5"><tr class="st">'; $i = 0; $associative_array = $options !== array_values( $options ); foreach ( (array) $options as $option_value => $option ) { if ( $i++ % 3 == 0 && $i > 1 ) { $multiple_html .= '</tr><tr class="st">'; } if ( ! $associative_array ) { // Not an associative array, use Text as value. $option_value = $option; } $multiple_html .= '<td><label> <input type="checkbox" name="' . AttrEscape( $name ) . '" value="' . AttrEscape( $option_value ) . '" ' . $extra . ' ' . ( $option != '' && mb_strpos( (string) $value, '||' . $option_value . '||' ) !== false ? ' checked' : '' ) . '> ' . ( $option != '' ? $option : '-' ) . '</label></td>'; } $multiple_html .= '</tr></table>' . FormatInputTitle( $title, '', $required, '' ); $multiple_html .= '<input type="hidden" name="' . AttrEscape( $name ) . '" value="">'; if ( trim( (string) $value, '|' ) == '' || ! $div ) { return $multiple_html; } return InputDivOnclick( $id, $multiple_html, $multiple_value, FormatInputTitle( $title ) ); } /** * Select Input * * @since 5.6 Support option groups (`<optgroup>`) by adding 'group' to $extra. * @since 6.0 Support multiple values. * @since 10.8.4 Fix save multiple SelectInput() when none selected, add hidden empty input (only if $allow_na) * * @example SelectInput( $value, 'values[' . $id . '][' . $name . ']', '', $options, 'N/A', $extra ) * * @uses GetInputID() to generate ID from name * @uses FormatInputTitle() to format title * @uses InputDivOnclick() * if ( AllowEdit() && !isset( $_REQUEST['_ROSARIO_PDF'] ) && $value != '' && $div ) * * @param string $values Input value(s). * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param array $options Input options: array( option_value => option_text ) or with groups: array( group_name => array( option_value => option_text ) ). * @param string|boolean $allow_na Allow N/A (empty value); set to false to disallow (optional). Defaults to N/A. * @param string $extra Extra HTML attributes added to the input. Add 'group' to enable options grouping. * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * * @return string Input HTML */ function SelectInput( $values, $name, $title = '', $options = [], $allow_na = 'N/A', $extra = '', $div = true ) { $id = GetInputID( $name ); $required = $values == '' && mb_strpos( (string) $extra, 'required' ) !== false; $is_multiple = is_array( $options ) && mb_strpos( (string) $extra, 'multiple' ) !== false; $values = $is_multiple ? (array) $values : // Mab - support array style $option values. ( is_array( $values ) ? [ $values[0] ] : [ $values ] ); $make_display_val = function( $values, $options ) { $display_val = []; foreach ( (array) $values as $value ) { if ( isset( $options[ $value ] ) ) { $display_val[] = is_array( $options[ $value ] ) ? $options[ $value ][1] : $options[ $value ]; } } return implode( ', ', $display_val ); }; $is_group = is_array( $options ) && is_array( reset( $options ) ) && mb_strpos( $extra, 'group' ) !== false; if ( $is_group ) { $display_val = []; foreach ( (array) $options as $group_options ) { $display_value = $make_display_val( $values, $group_options ); if ( $display_value ) { $display_val[] = $display_value; } } $display_val = implode( ', ', $display_val ); } else { $display_val = $make_display_val( $values, $options ); } if ( ! AllowEdit() || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { if ( $display_val == '' ) { $display_val = '-'; if ( $allow_na !== false ) { $display_val = $allow_na === 'N/A' ? _( 'N/A' ) : $allow_na; } } return $display_val . FormatInputTitle( $title ); } $select = '<select name="' . AttrEscape( $name ) . '" id="' . $id . '" ' . $extra . '>'; if ( $allow_na !== false ) { $select .= '<option value="">' . ( $allow_na === 'N/A' ? _( 'N/A' ) : $allow_na ) . '</option>'; } $make_option = function( $values, $key, $val ) { $selected = ''; $key .= ''; foreach ( (array) $values as $value ) { if ( $value == $key && ( !( $value == false && $value !== $key ) || ( $value === '0' && $key === 0 ) ) ) { $selected = ' selected'; break; } } return '<option value="' . AttrEscape( $key ) . '"' . $selected . '>' . ( is_array( $val ) ? $val[0] : $val ) . '</option>'; }; if ( $is_group ) { foreach ( (array) $options as $group => $group_options ) { $select .= '<optgroup label="' . AttrEscape( $group ) . '">'; foreach ( (array) $group_options as $key => $val ) { $select .= $make_option( $values, $key, $val ); } $select .= '</optgroup>'; } } else { // Mab - append current val to select list if not in list. if ( ! $is_multiple && $values[0] != '' && ( ! is_array( $options ) || ! array_key_exists( $values[0], $options ) ) ) { $options[ $values[0] ] = [ $values[0], '<span style="color:red">' . $values[0] . '</span>' ]; $display_val = '<span style="color:red">' . $values[0] . '</span>'; } foreach ( (array) $options as $key => $val ) { $select .= $make_option( $values, $key, $val ); } } $select .= '</select>' . FormatInputTitle( $title, $id, $required ); if ( $is_multiple && $allow_na !== false ) { // Fix save multiple SelectInput() when none selected, add hidden empty input (only if $allow_na) $select .= '<input type="hidden" name="' . AttrEscape( $name ) . '" value="">'; } if ( ! isset( $values[0] ) || $values[0] == '' || ! $div ) { return $select; } return InputDivOnclick( $id, $select, $display_val, FormatInputTitle( $title ) ); } /** * Multi Languages Select Input * * @example MLSelectInput( * $RET['CATEGORY_ID'], * 'tables[' . $_REQUEST['id'] . '][CATEGORY_ID]', * _( 'User Field Category' ), * $categories_options, * false * ); * * @uses GetInputID() to generate ID from name * @uses FormatInputTitle() to format title * @uses InputDivOnclick() * if ( AllowEdit() && !isset( $_REQUEST['_ROSARIO_PDF'] ) && $value != '' && $div ) * * @uses ParseMLField() to get localized options * * @global $RosarioLocales Returns simple SelectInput() if only 1 locale set * @global $locale Get current locale * * @param string $value Input value. * @param string $name Input name. * @param string $title Input title. * @param array $options Input options: array( option_value => option_text ). * @param string|boolean $allow_na Allow N/A (empty value); set to false to disallow (optional). Defaults to N/A. * @param string $extra Extra HTML attributes added to the input. * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * * @return string Input HTML */ function MLSelectInput( $value, $name, $title, $options, $allow_na = 'N/A', $extra = '', $div = true ) { global $RosarioLocales, $locale; // Mab - support array style $option values. $value = is_array( $value ) ? $value[0] : $value; if ( count( $RosarioLocales ) < 2 ) { return SelectInput( ParseMLField( $value, $locale ), $name, $title, $options, $div ); } $id = GetInputID( $name ); $required = $value == '' && mb_strpos( $extra, 'required' ) !== false; // Mab - append current val to select list if not in list. if ( $value != '' && ( ! is_array( $options ) || !array_key_exists( $value, $options ) ) ) { $options[ $value ] = [ $value, '<span style="color:red">' . $value . '</span>' ]; } if ( AllowEdit() && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { $select = '<select name="' . AttrEscape( $name ) . '" id="' . $id . '" '.$extra.'>'; if ( $allow_na !== false ) { $select .= '<option value="">' . ( $allow_na === 'N/A' ? _( 'N/A' ) : $allow_na ) . '</option>'; } foreach ( (array) $options as $key => $val ) { $selected = ''; $key .= ''; if ( $value == $key && ( ! ( $value == false && $value !== $key ) || ( $value === '0' && $key === 0 ) ) ) { $selected = ' selected'; } $val_locale = ParseMLField( ( is_array( $val ) ? $val[0] : $val ), $locale ); $select .= '<option value="' . AttrEscape( $key ) . '"' . $selected . '>' . $val_locale . '</option>'; } $select .= '</select>' . FormatInputTitle( $title, $id, $required ); if ( $value == '' || ! $div ) { return $select; } return InputDivOnclick( $id, $select, ParseMLField( ( is_array( $options[ $value ] ) ? $options[ $value ][1] : $options[ $value ] ), $locale ), FormatInputTitle( $title ) ); } $display_val = is_array( $options[ $value ] ) ? $options[ $value ][1] : $options[ $value ]; if ( $display_val == '' ) { $display_val = '-'; if ( $allow_na !== false ) { $display_val = $allow_na === 'N/A' ? _( 'N/A' ) : $allow_na; } } else { $display_val = ParseMLField( $display_val, $locale ); } return $display_val . FormatInputTitle( $title ); } /** * SelectInput() wrapper which adds jQuery Chosen. * * Chosen is a library for making long, unwieldy select boxes more friendly. * @link https://github.com/harvesthq/chosen * * @since 2.9.5 * @deprecated since 10.7 Use Select2Input() instead. Fixes the overflow issue. * * @example ChosenSelectInput( $value, 'values[' . $id . '][' . $name . ']', '', $options, 'N/A', $extra ) * * @uses SelectInput() to generate the Select input * * @param string $value Input value. * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param array $options Input options: array( option_value => option_text ). * @param string|boolean $allow_na Allow N/A (empty value); set to false to disallow (optional). Defaults to N/A. * @param string $extra Extra HTML attributes added to the input. * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * * @return string Input HTML */ function ChosenSelectInput( $value, $name, $title = '', $options = [], $allow_na = 'N/A', $extra = '', $div = true ) { static $chosen_included = false; $js = ''; if ( ! $chosen_included && AllowEdit() && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { ob_start(); ?> <!-- Chosen --> <script src="assets/js/jquery-chosen/chosen.jquery.min.js"></script> <link rel="stylesheet" href="assets/js/jquery-chosen/chosen.min.css"> <script> $(document).ready(function(){ $('.chosen-select').chosen('.chosen-select'); }); </script> <?php $chosen_included = true; $js = ob_get_clean(); } // Right to left direction. $RTL_languages = [ 'ar', 'he', 'dv', 'fa', 'ur' ]; $chosen_rtl = in_array( mb_substr( $_SESSION['locale'], 0, 2 ), $RTL_languages ) ? ' chosen-rtl' : ''; if ( ! $extra || mb_strpos( $extra, 'class=' ) === false ) { $extra .= ' class="chosen-select' . $chosen_rtl . '"'; } elseif ( mb_strpos( $extra, 'class=' ) !== false ) { $extra = str_replace( [ 'class="', "class='" ], [ 'class="chosen-select' . $chosen_rtl . ' ', "class='chosen-select" . $chosen_rtl . ' ' ], $extra ); } // Translate default "Select Some Options" multiple placeholder. if ( mb_strpos( $extra, 'multiple' ) !== false && mb_strpos( $extra, 'data-placeholder=' ) === false ) { $extra .= ' data-placeholder="' . AttrEscape( _( 'Select some Options' ) ) . '"'; } $return = $js . SelectInput( $value, $name, $title, $options, $allow_na, $extra, $div ); if ( $value != '' && $div && AllowEdit() && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { $id = GetInputID( $name ); // On InputDivOnClick(), call Chosen. $return .= '<script>$("#div' . $id . '").on("click", function(){ $("#' . $id . '").chosen(); });</script>'; } return $return; } /** * SelectInput() wrapper which adds jQuery Select2. * * Select2 gives you a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options. * @link https://select2.org/ * * @since 10.7 * * @example Select2Input( $value, 'values[' . $id . '][' . $name . ']', '', $options, 'N/A', $extra ) * * @uses SelectInput() to generate the Select input * * @param string $value Input value. * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param array $options Input options: array( option_value => option_text ). * @param string|boolean $allow_na Allow N/A (empty value); set to false to disallow (optional). Defaults to N/A. * @param string $extra Extra HTML attributes added to the input. * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true. * * @return string Input HTML */ function Select2Input( $value, $name, $title = '', $options = [], $allow_na = 'N/A', $extra = '', $div = true ) { static $select2_included = false; $js = ''; if ( ! $select2_included && AllowEdit() && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { ob_start(); ?> <!-- Select2 --> <script src="assets/js/jquery-select2/select2.min.js"></script> <link rel="stylesheet" href="assets/js/jquery-select2/select2.min.css"> <script> $(document).ready(function(){ $('.select2-select').select2({ language: { noResults: function() { return ''; } } }); }); </script> <?php $select2_included = true; $js = ob_get_clean(); } if ( ! $extra || mb_strpos( $extra, 'class=' ) === false ) { $extra .= ' class="select2-select"'; } elseif ( mb_strpos( $extra, 'class=' ) !== false ) { $extra = str_replace( [ 'class="', "class='" ], [ 'class="select2-select ', "class='select2-select " ], $extra ); } // Translate default "Select Some Options" multiple placeholder. if ( mb_strpos( $extra, 'multiple' ) !== false && mb_strpos( $extra, 'data-placeholder=' ) === false ) { $extra .= ' data-placeholder="' . AttrEscape( _( 'Select some Options' ) ) . '"'; } $return = $js . SelectInput( $value, $name, $title, $options, $allow_na, $extra, $div ); if ( $value != '' && $div && AllowEdit() && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { $id = GetInputID( $name ); // On InputDivOnClick(), call Select2 (once). $return .= '<script>var select2Div' . $id . '=false; $("#div' . $id . '").on("click", function() { if (select2Div' . $id . ') return; select2Div' . $id . '=true; $("#' . $id . '").select2({ language: { noResults: function() { return ""; } } }); });</script>'; } return $return; } /** * Radio Input * * @example RadioInput( $value, 'values[' . $id . '][COLOR]', '', $color_options ); * * @uses GetInputID() to generate ID from name * @uses FormatInputTitle() to format title * @uses InputDivOnclick() * if ( AllowEdit() && !isset( $_REQUEST['_ROSARIO_PDF'] ) && ! $new && $div ) * * @param string $value Input value * @param string $name Input name * @param string $title Input title. * @param array $options Input options: array( option_value => option_text ) * @param string|boolean $allow_na Allow N/A (empty value); set to false to disallow (optional). Defaults to N/A * @param string $extra Extra HTML attributes added to the input (optional). * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true * * @return string Input HTML */ function RadioInput( $value, $name, $title, $options, $allow_na = 'N/A', $extra = '', $div = true ) { $id = GetInputID( $name ); $required = $value == '' && mb_strpos( $extra, 'required' ) !== false; // mab - append current val to select list if not in list if ( $value != '' && ( ! is_array( $options ) || ! array_key_exists( $value, $options ) ) ) { $options[ $value ] = [ $value, '<span style="color:red">' . $value . '</span>' ]; } if ( AllowEdit() && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { $table = '<table class="cellspacing-0 cellpadding-5"><tr class="st">'; $i = 0; if ( $allow_na !== false ) { $table .= '<td><label><input type="radio" name="' . AttrEscape( $name ) . '" value=""' . ( $value == '' ? ' checked' : '' ) . ' ' . $extra . '> ' . ( $allow_na === 'N/A' ? _( 'N/A' ) : $allow_na ) . '</label></td>'; $i++; } foreach ( (array) $options as $key => $val ) { if ( $i++ % 3 == 0 && $i > 1 ) { $table .= '</tr><tr class="st">'; } $checked = ''; $key .= ''; if ( $value == $key && ( !( $value == false && $value !== $key ) || ( $value === '0' && $key === 0 ) ) ) { $checked = ' checked'; } $table .= '<td><label><input type="radio" name="' . AttrEscape( $name ) . '" value="' . AttrEscape( $key ) . '"' . $checked . ' ' . $extra . '> ' . ( is_array( $val ) ? $val[0] : $val ) . '</label></td>'; } $table .= '</tr></table>'; $table .= FormatInputTitle( $title, '', $required, '' ); if ( $value == '' || ! $div ) { return $table; } return InputDivOnclick( $id, $table, is_array( $options[ $value ] ) ? $options[ $value ][1] : $options[ $value ], FormatInputTitle( $title ) ); } $display_val = ! isset( $options[ $value ] ) ? '' : ( is_array( $options[ $value ] ) ? $options[ $value ][1] : $options[ $value ] ); if ( $display_val == '' ) { $display_val = '-'; if ( $allow_na !== false ) { $display_val = $allow_na === 'N/A' ? _( 'N/A' ) : $allow_na; } } return $display_val . FormatInputTitle( $title ); } /** * Color Picker Input * * @example ColorInput( $value, 'values[' . $id . '][' . $column . ']', _( 'Color' ) ); * * @since 2.9 * @since 5.4 Remove $type param. * * @param string $value Color value * @param string $name Input name attribute * @param string $title Input title (label) * @param string $extra Extra HTML attributes added to the input (optional). * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true * * @return string Color Picker Input HTML */ function ColorInput( $value, $name, $title = '', $extra = '', $div = true ) { if ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) || strpos( $_SERVER['HTTP_USER_AGENT'], 'Trident/7' ) ) { // Is Internet Explorer: not compatible with color input. return ColorInputMiniColors( $value, $name, $title, 'hidden', $extra, $div ); } $id = GetInputID( $name ); $required = $value == '' && mb_strpos( $extra, 'required' ) !== false; $color_rect = '<div class="color-input-value" style="background-color:' . $value . ';"></div>'; if ( ! AllowEdit() || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return $color_rect . FormatInputTitle( $title, '', '', '' ); } $input = '<input type="color" name="' . AttrEscape( $name ) . '" id="' . $id . '" value="' . AttrEscape( $value ) . '"' . $extra . '>'; $input .= FormatInputTitle( $title, $id, $required ); if ( $value == '' || ! $div ) { return $input; } return InputDivOnclick( $id, $input, $color_rect, FormatInputTitle( $title ) ); } /** * Color Picker Input for browsers not supporting HTML5 color input * @link http://caniuse.com/#search=input%20type * * @example ColorInputMiniColors( $value, 'values[' . $id . '][' . $column . ']', '', 'hidden', 'data-position="bottom right"' ); * * @deprecated * * @since 5.4 * * @uses jQuery MiniColors plugin * * @see assets/js/jquery-minicolors/ for plugin files * * @link https://github.com/claviska/jquery-minicolors/ * * @param string $value Color value * @param string $name Input name attribute * @param string $title Input title (label) * @param string $type hidden|text Input type attribute (optional). Defaults to 'hidden' * @param string $extra Extra HTML attributes added to the input (optional). * @param boolean $div Is input wrapped into <div onclick>? (optional). Defaults to true * * @return string Color Picker Input HTML */ function ColorInputMiniColors( $value, $name, $title = '', $type = 'hidden', $extra = '', $div = true ) { static $included = false; $id = GetInputID( $name ); $required = $value == '' && mb_strpos( $extra, 'required' ) !== false; $color_rect = '<div class="color-input-value" style="background-color:' . $value . ';"></div>'; if ( ! AllowEdit() || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return $color_rect . FormatInputTitle( $title, '', '', '' ); } $js = ''; if ( ! $included ) { ob_start(); ?> <!-- MiniColors --> <link rel="stylesheet" href="assets/js/jquery-minicolors/jquery.minicolors.css"> <script src="assets/js/jquery-minicolors/jquery.minicolors.js"></script> <script>$(document).ready(function(){ $('.minicolors').each(function(){ $(this).minicolors({ position: $(this).attr('data-position') || 'bottom left' }); }); });</script> <?php $js = ob_get_clean(); $included = true; } ob_start(); ?> <input type="<?php echo AttrEscape( $type ); ?>" name="<?php echo AttrEscape( $name ); ?>" id="<?php echo $id; ?>" class="minicolors" value="<?php echo AttrEscape( $value ); ?>" <?php echo $extra; ?>> <?php $color = ob_get_clean() . FormatInputTitle( $title, $id, $required ); if ( $value == '' || ! $div ) { return $js . $color; } return $js . InputDivOnclick( $id, $color, $color_rect, FormatInputTitle( $title ) . '<script>$("#div' . $id . '").on("click", function(){ $("#' . $id . '").minicolors({ position: $("#' . $id . '").attr("data-position") || "bottom left" }); });</script>' ); } /** * Captcha Input * * @example CaptchaInput( 'captcha' . rand( 100, 9999 ), _( 'Captcha' ) ); * * @since 3.5 * * @see assets/js/warehouse.js for captcha JS functions. * * @uses $_SESSION['CaptchaInput'] * Places input name in session * so we can retrieve & check the input & answer values before processing form * * @param string $name Input name attribute (array: 'input' & 'answer' indexes available). * @param string $title Input title (label) * @param string $extra Extra HTML attributes added to the input (optional). * * @return string Captcha Input HTML */ function CaptchaInput( $name, $title, $extra = '' ) { // Place input name in session // so we can retrieve & check the input & answer values before processing form. $_SESSION['CaptchaInput'] = $name; $id_base = GetInputID( $name ); $required = true; ob_start(); ?> <div class="captcha"> <span id="<?php echo $id_base; ?>-n1"></span> + <span id="<?php echo $id_base; ?>-n2"></span> = <input id="<?php echo $id_base; ?>-input" name="<?php echo AttrEscape( $name ); ?>[input]" type="number" required> <input id="<?php echo $id_base; ?>-answer" name="<?php echo AttrEscape( $name ); ?>[answer]" type="hidden" <?php echo $extra; ?>> <?php echo FormatInputTitle( $title, $id_base . '-input', $required ); ?> </div> <script>captcha(<?php echo json_encode( $id_base ); ?>);</script> <?php return ob_get_clean(); } /** * Check Captcha * Compare captcha input with answer. * * @since 3.5 * * @uses $_SESSION['CaptchaInput'] where captcha name is stored. * * @see Create User / Student forms. * * @example if ( ! CheckCaptcha() ) $error[] = _( 'Captcha' ); * * @return boolean True if no captcha or if captcha passed, else false. */ function CheckCaptcha() { if ( ! isset( $_SESSION['CaptchaInput'] ) || ! $_SESSION['CaptchaInput'] ) { return true; } // Get submitted captcha using captcha name saved in session. $captcha = isset( $_REQUEST[ $_SESSION['CaptchaInput'] ] ) ? $_REQUEST[ $_SESSION['CaptchaInput'] ] : []; // Compare input & answer. return $captcha && $captcha['input'] === $captcha['answer']; } /** * File Input * Warning: contrary to other *Input() functions, there is no AllowEdit() check * so the file input will also be visible to students, parents & teachers. * * @since 3.8.1 * @since 5.2 Add $max_file_size param & max file size validation. * @since 7.8 Handle `multiple` files attribute. See FileUploadMultiple(). * * @example FileInput( 'file', _( 'File' ), 'required' ) * @example FileInput( 'files[]', _( 'Files' ), 'multiple' ) * * @uses GetInputID() to generate ID from name * @uses FormatInputTitle() to format title * * @param string $name Input name. * @param string $title Input title (optional). Defaults to ''. * @param string $extra Extra HTML attributes added to the input. Defaults to ''. * @param int $max_file_size Maximum File Size, in Mb. Optional. Defaults to FileUploadMaxSize(). * * @return string Input HTML */ function FileInput( $name, $title = '', $extra = '', $max_file_size = 0 ) { require_once 'ProgramFunctions/FileUpload.fnc.php'; $id = GetInputID( $name ); $required = mb_strpos( $extra, 'required' ) !== false; $ftitle = FormatInputTitle( $title, $id, $required ); // Input size / length based on value number of chars. if ( mb_strpos( $extra, 'size=' ) === false ) { $extra .= ' size="10"'; } $max_file_size = $max_file_size > 0 && $max_file_size < FileUploadMaxSize() ? $max_file_size : FileUploadMaxSize(); // Input title indicating Maximum file size. if ( mb_strpos( $extra, 'title=' ) === false ) { $extra .= ' title="' . AttrEscape( sprintf( _( 'Maximum file size: %01.0fMb' ), $max_file_size ) ) . '"'; } return '<input type="file" id="' . $id . '" name="' . AttrEscape( $name ) . '" ' . $extra . ' onchange="fileInputSizeValidate(this,' . (float) $max_file_size . ');"><span class="loading"></span>' . $ftitle; } /** * No Input * Simulate Input formatting for a non-editable Input / Value * * @example NoInput( $person[1]['PHONE'], _( 'Home Phone' ) ) * * @uses FormatInputTitle() to format title * * @param string $value Input value * @param string $title Input title (optional). Defaults to '' * * @return string Value + Formatted Title */ function NoInput( $value, $title = '' ) { $ftitle = FormatInputTitle( $title ); $value = ( $value != '' ? $value : '-' ); if ( AllowEdit() && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return '<span class="no-input-value">' . $value . '</span>' . $ftitle; } return $value . $ftitle; } /** * Checkbox onclick * When clicked the checkbox value is submitted & the URL is opened * * @example DrawHeader( CheckBoxOnclick( 'by_name', _( 'Sort by Name' ) ); * * @param string $name Input name * @param string $title Title * * @return string Checkbox onclick HTML */ function CheckBoxOnclick( $name, $title = '' ) { $onclick_URL = PreparePHP_SELF( $_REQUEST, [], isset( $_REQUEST[ $name ] ) && $_REQUEST[ $name ] == 'Y' ? [ $name => '' ] : [ $name => 'Y' ] ); $input = '<input type="checkbox" name="' . AttrEscape( $name ) . '" value="Y"' . ( isset( $_REQUEST[ $name ] ) && $_REQUEST[ $name ] == 'Y' ? ' checked' : '' ) . ' onclick="' . AttrEscape( 'ajaxLink(' . json_encode( $onclick_URL ) . ');' ) . '">'; if ( $title != '' ) { $input = '<label>' . $input . ' ' . $title . '</label>'; } return $input; } /** * Get Javascript friendly input HTML ID attribute * From name attribute value * * @since 2.9 * @since 9.0 Use AttrEscape() * * @example GetInputID( 'cust[CUSTOM_1]' ); will return "custCUSTOM_1" * * @param string $name Input name attribute * * @return string Input ID attribute */ function GetInputID( $name ) { if ( empty( $name ) ) { return $name; } $id = str_replace( [ '[', ']', '-', ' ' ], '', $name ); return AttrEscape( $id ); } /** * Format Input Title * Adds line break, <label> & .legend-gray CSS class to Title string * * @since 2.9 * * @example $id = GetInputID( $name ); * $required = $value == '' && mb_strpos( $extra, 'required' ) !== false; * $ftitle = FormatInputTitle( $title, $id, $required ); * * @uses Use it if your *Field type (ie. password) is not supported to get a standardized Title * or as an InputDivOnclick() argument * * @param string $title Input Title * @param string $id Input id attribute (optional). Defaults to '' * @param boolean $required Required Input & AllowEdit() ? CSS class is .legend-red * @param string $break Break before title (optional). Defaults to '<br>' * * @return string Formatted Input Title */ function FormatInputTitle( $title, $id = '', $required = false, $break = '<br>' ) { if ( $title === '' ) { return ''; } if ( mb_strpos( (string) $title, 'a11y-hidden' ) !== false ) { // Accessibility hidden title: force break to empty string. $break = ''; } else { // Not hidden, add legend class color. $class = $required && AllowEdit() ? 'legend-red' : 'legend-gray'; $title = '<span class="' . AttrEscape( $class ) . '">' . $title . '</span>'; } // Add label only if id attribute given if ( $id !== '' ) { $title = '<label for="' . $id . '">' . $title . '</label>'; } return $break . $title; } /** * Input <div> onclick * Wraps the Input HTML inside a <div> with Value & Input Formatted Title below * The <div> makes the Input HTML appear and editable when clicked * * @todo Fix JS error var is not defined when InputDivOnclick() called twice! * * @since 2.9 * * @example $return = InputDivOnclick( $id, $textarea_html, $display_val, $ftitle ); * * @uses Use it if you would like to wrap various fields * (ie. Student / User Name => First Name, Middle Name, Last Name) * * @param string $id Input ID * @param string $input_html Input HTML * @param string $value Input value * @param string $input_ftitle Input Formatted Title * * @return string Wrapped Input HTML inside a <div> with Value & Input Formatted Title below */ function InputDivOnclick( $id, $input_html, $value, $input_ftitle ) { // @since 9.0 JS Sanitize string for legal variable name. // @link https://stackoverflow.com/questions/12339942/sanitize-strings-for-legal-variable-names-in-php $id_sanitized = preg_replace( '/^(?![a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$/', '', $id ); $script = '<script>var html' . $id_sanitized . '=' . json_encode( $input_html ).';</script>'; $value = $value == '' ? '-' : $value; $onfocus_js = 'addHTML(html' . $id_sanitized . ',\'div' . $id_sanitized . '\',true); $(\'#' . $id_sanitized . '\').focus(); $(\'#div' . $id_sanitized . '\').click();'; $event = 'onfocus'; if ( strpos( $_SERVER['HTTP_USER_AGENT'], 'Trident/7' ) || strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) ) { /** * Fix IE not propagating focus event to parent on click * Related to this CSS rule: `.underline-dots { display: inline-block; }` * * @since 11.8.1 * * @link https://stackoverflow.com/questions/51404782/focus-event-not-fired-on-focusable-parent-html-element-with-display-flex-in-ie1 */ $event = 'onclick'; } $div_onclick = '<div id="div' . $id_sanitized . '"> <div class="onclick" tabindex="0" ' . $event . '="' . // Do not not convert single quotes to gain a few bytes htmlspecialchars( $onfocus_js, ENT_COMPAT, null, false ) . '">' . ( mb_stripos( $value, '<div' ) === 0 ? '<div class="underline-dots">' . $value . '</div>' : '<span class="underline-dots">' . $value . '</span>' ) . $input_ftitle . '</div></div>'; return $script . $div_onclick; } /** * Make Choose Checkbox * * Use in extra columns for ListOutput * * DBGet() callback * AND use first, to set controller checkbox & default checked value & $THIS_RET column if need be. * * @since 4.3 * @since 10.0 Fix remove parent link to sort column, see ListOutput.fnc.php * @since 11.5 Add 'required' option to $value param. Prevent submitting form if no checkboxes are checked. * * First, set controller: * @example $extra['columns_before'] = [ 'CHECKBOX' => MakeChooseCheckbox( '', 'STUDENT_ID', 'student' ) ]; * @example $extra['columns_before'] = [ 'CHECKBOX' => MakeChooseCheckbox( 'Y_required', '', 'st' ) ]; * Then, use as DBGet() callback: * @example $extra['functions'] = [ 'CHECKBOX' => 'MakeChooseCheckbox' ]; * * @param string $value DB value or checked ('Y') or 'required'|'Y_required' to prevent submitting form if none checked. * @param string $column Current DBGet column or $THIS_RET column to use (optional). * @param string $controller_name Controller name (set first only), ie. 'student' will give 'student[]' (optional). * * @return string Checkbox HTML or checked state if PDF/export */ function MakeChooseCheckbox( $value, $column = '', $controller_name = '' ) { global $THIS_RET; static $controller_column, $name, $checked, $controller_i = 1; // Handle multiple controllers on the same page. if ( ! empty( $controller_name ) ) { $controller_column = $column; $name = $controller_name; $checked = mb_substr( $value, 0, 1 ) === 'Y'; $required = mb_strpos( $value, 'required' ) !== false; if ( isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return $checked ? '✔️' : ''; } $id = 'controller' . $controller_i; $return = '<input type="checkbox" value="Y" name="' . $id . '" id="' . $id . '" onclick="' . AttrEscape( 'checkAll(this.form,this.checked,' . json_encode( $name . '[]' ) . ');' ) . '"' . ( $checked ? ' checked' : '' ) . '> <label for="' . $id . '" class="a11y-hidden">' . _( 'Check All' ) . '</label>'; if ( ! $required ) { return $return; } ob_start(); // JS Prevent submitting form if no checkboxes are checked. ?> <script> $('#<?php echo $id; ?>').closest('form').on('submit', function(e) { if ( ! $('input[name=<?php echo json_encode( $name . '[]' ); ?>]:checked').length ) { e.preventDefault(); e.stopImmediatePropagation(); $('#<?php echo $id; ?>')[0].scrollIntoView({behavior: "smooth"}); alert(<?php echo json_encode( _( 'You must choose at least one element from the list.' ) ); ?>); return false; } }); </script> <?php return $return . ob_get_clean(); } if ( isset( $_REQUEST['_ROSARIO_PDF'] ) ) { return $checked ? '✔️' : ''; } if ( ! empty( $controller_column ) ) { $value = issetVal( $THIS_RET[ $controller_column ], '' ); } return '<label><input type="checkbox" name="' . AttrEscape( $name ) . '[]" value="' . AttrEscape( $value ) . '"' . ( $checked ? ' checked' : '' ) . '><span class="a11y-hidden">' . _( 'Select' ) . '</span></label>'; } /** * Escape HTML attribute * Protects against XSS (Javascript execution) * * @see URLEscape() to escape href, action & src attributes * @see GetInputID() to escape id attribute * * @example $html = '<span title="' . AttrEscape( $value ) . '">' . _( 'Text' ) . '</span>'; * @example <span title="<?php echo AttrEscape( $value ); ?\>"><?php echo _( 'Text' ); ?\></span> * * @uses htmlspecialchars * * @since 9.0 * * @param string $value Text to be escaped. * * @return string Escaped string. */ function AttrEscape( $value ) { return htmlspecialchars( (string) $value, ENT_QUOTES, null, false ); }
💾 保存文件
← 返回文件管理器