'1', 'search' => true, 'center' => true, 'count' => true, 'sort' => empty( $group ), 'header_color' => Preferences( 'HEADER' ), 'responsive' => true, 'add' => true, ); $options = empty( $options ) ? $default_options : array_replace_recursive( $default_options, $options ); $LO_page = issetVal( $_REQUEST['LO_page'], '' ); // FJ bugfix ListOutput sorting when more than one list in a page. $LO_sort = issetVal( $_REQUEST['LO_sort'], '' ); $LO_dir = issetVal( $_REQUEST['LO_dir'], '' ); $LO_search = issetVal( $_REQUEST['LO_search'], '' ); $LO_save = issetVal( $_REQUEST['LO_save'], '' ); if ( ! $options['add'] || ! AllowEdit() || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { if ( ! empty( $link ) ) { unset( $link['add'] ); unset( $link['remove'] ); } } $result_count = $display_count = count( (array) $result ); if ( $result_count > 1000 ) { // Limit to 1000! $result_count = 1000; // Remove results above 1000. $result = array_slice( $result, 0, 1000, true ); } $num_displayed = 1000; // PREPARE LINKS ---. $extra = URLEscape( 'LO_page=' . $LO_page . '&LO_sort=' . $LO_sort . '&LO_dir=' . $LO_dir . '&LO_search=' . $LO_search ); $PHP_tmp_SELF = PreparePHP_SELF( $_REQUEST, array( 'LO_page', 'LO_sort', 'LO_dir', 'LO_search', 'LO_save', ) ); // END PREPARE LINKS ---. // UN-GROUPING $group_count = empty( $group ) ? false : count( $group ); if ( $group_count && $result_count ) { $group_result = $result; unset( $result ); $result[0] = ''; foreach ( (array) $group_result as $item1 ) { foreach ( (array) $item1 as $item2 ) { if ( $group_count == 1 ) { $result[] = $item2; continue; } foreach ( (array) $item2 as $item3 ) { if ( $group_count == 2 ) { $result[] = $item3; continue; } foreach ( (array) $item3 as $item4 ) { $result[] = $item4; } } } } unset( $result[0] ); $result_count = count( $result ); } // END UN-GROUPING $display_zero = false; // PRINT HEADINGS, PREPARE PDF, AND SORT THE LIST ---. if ( $result_count != 0 ) { $count = $remove = 0; if ( isset( $link['remove']['variables'] ) ) { $remove = count( $link['remove']['variables'] ); } $cols = count( $column_names ); // HANDLE SEARCHES ---. if ( $result_count && $options['search'] && $LO_search !== '' ) { // @since 5.8. $result = _listSearch( $result, $LO_search ); $result_count = $display_count = count( $result ); if ( $result_count ) { $column_names['RELEVANCE'] = _( 'Relevance' ); } if ( is_array( $group ) && count( $group ) ) { $options['count'] = false; $display_zero = true; } } // END SEARCHES ---. if ( $LO_sort ) { foreach ( (array) $result as $sort ) { if ( mb_substr( $sort[$LO_sort], 0, 4 ) != '' ) - 4 ) ); } $dir = $LO_dir == -1 ? SORT_DESC: SORT_ASC; if ( $result_count > 1 ) { if ( is_int( $sort_array[1] ) || is_double( $sort_array[1] ) ) { array_multisort( $sort_array, $dir, SORT_NUMERIC, $result ); } else { array_multisort( $sort_array, $dir, $result ); } for ( $i = $result_count - 1; $i >= 0; $i-- ) { $result[$i + 1] = $result[$i]; } unset( $result[0] ); } } } // List Before hook. do_action( 'functions/ListOutput.fnc.php|list_before' ); // HANDLE SAVING THE LIST ---. if ( $options['save'] && (int) $LO_save === (int) $options['save'] && ! headers_sent() ) { _listSave( $result, $column_names, $singular, $plural, Preferences( 'DELIMITER' ) ); } // END SAVING THE LIST ---. if ( $result_count > 0 || $LO_search !== '' ) { // HANDLE MISC ---. if ( ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { if ( empty( $LO_page ) || $LO_page < 1 ) { $LO_page = 1; } if ( empty( $LO_dir ) ) { $LO_dir = 1; } $start = ( $LO_page - 1 ) * $num_displayed + 1; $stop = $start + ( $num_displayed - 1 ); if ( $stop > $result_count ) { $stop = $result_count; } if ( $result_count >= $num_displayed ) { $where_message = ' ' . sprintf( _( 'Displaying %d through %d' ), $start, $stop ) . ''; } } else { $start = 1; $stop = $result_count; if ( $cols > 8 || ! empty( $_REQUEST['expanded_view'] ) ) { // For wkhtmltopdf. $_SESSION['orientation'] = 'landscape'; } } // END MISC ---. } $class = ''; if ( $plural && $plural !== '.' ) { $class = mb_strtolower( preg_replace( '/([^\-a-z\/0-9]+)/i', '-', $plural ) ); } echo '
'; // SEARCH BOX & MORE HEADERS ---. if ( ! empty( $options['header'] ) ) { echo '
' . $options['header'] . '
'; } $list_has_nav = false; if ( $options['count'] || $display_zero || ( $options['save'] || $options['search'] && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) ) { $list_has_nav = true; echo ''; $colspan = 1; if ( $options['search'] && ! isset( $_REQUEST['_ROSARIO_PDF'] ) && ( $result_count > 0 || $LO_search ) ) { echo ''; $colspan++; } echo '
'; $has_count_text = false; if ( $singular !== '.' && $plural !== '.' && $options['count'] ) { if ( $display_count > 0 ) { echo '' . sprintf( ngettext( '%d %s was found.', '%d %s were found.', $display_count ), $display_count, ngettext( $singular, $plural, $display_count ) ) . ''; } echo empty( $where_message ) ? '' : $where_message; $has_count_text = true; } if ( ( $options['count'] || $display_zero ) && ( $result_count == 0 || $display_count == 0 ) ) { // No results message. Default to "Results". echo '' . sprintf( _( 'No %s were found.' ), ngettext( ( $singular === '.' ? _( 'Result' ) : $singular ), ( $plural === '.' ? _( 'Results' ) : $plural ), 0 ) ) . ''; $has_count_text = true; } if ( $options['save'] && ! isset( $_REQUEST['_ROSARIO_PDF'] ) && $result_count > 0 ) { echo $has_count_text ? ' ' : ''; // Save / Export list button. echo '' . _( 'Export list' ) . ''; } echo ''; // Do not remove search URL due to document.URL = 'index.php' in old IE browsers. $search_URL = PreparePHP_SELF( $_REQUEST, array( 'LO_search' ) ); echo ' '; echo '
'; } // END SEARCH BOX & MORE HEADERS ---. if ( $result_count > 0 ) { echo '
'; $i = 1; if ( $remove && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { echo ''; $i++; } if ( $cols ) { foreach ( (array) $column_names as $key => $value ) { $direction = $LO_sort == $key ? -1 * $LO_dir : 1; $i++; if ( isset( $_REQUEST['_ROSARIO_PDF'] ) ) { echo ''; continue; } if ( $options['sort'] ) { echo ''; continue; } echo ''; } } echo ''; // mab - enable add link as first or last if ( isset( $link['add']['first'] ) && ( $stop - $start + 1 ) >= $link['add']['first'] ) { if ( $link['add']['link'] && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { echo ''; } elseif ( $link['add']['span'] && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { echo ''; } elseif ( $link['add']['html'] && $cols ) { echo ''; if ( $remove && ! isset( $_REQUEST['_ROSARIO_PDF'] ) && $link['add']['html']['remove'] ) { echo ''; } elseif ( $remove && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { echo ''; } foreach ( (array) $column_names as $key => $value ) { echo ''; } echo ''; $count++; } } for ( $i = $start; $i <= $stop; $i++ ) { $item = $result[$i]; if ( isset( $_REQUEST['_ROSARIO_PDF'] ) && count( $item ) ) { $key = array_keys( $item ); $size = count( $key ); for ( $j = 0; $j < $size; $j++ ) { $value = preg_replace( '!([^<]+)<.*!i', '\\1', $item[$key[$j]] ); $value = preg_replace( '!!i', '', $value ); $item[$key[$j]] = preg_replace( "/
/", '', $value ); } } echo '
'; $count++; if ( $remove && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { $button_title = issetVal( $link['remove']['title'] ); $button_link = empty( $link['remove']['link'] ) ? PreparePHP_SELF( array(), array_keys( $link['remove']['variables'] ) ) : URLEscape( $link['remove']['link'] ); foreach ( (array) $link['remove']['variables'] as $var => $val ) { $button_link .= URLEscape( '&' . $var . '=' . $item[$val] ); } echo ''; } $color = issetVal( $item['row_color'] ); if ( $cols ) { foreach ( (array) $column_names as $key => $value ) { echo $color === Preferences( 'HIGHLIGHT' ) ? ''; continue; } if ( ! empty( $link[$key]['js'] ) ) { echo ' $val ) { echo URLEscape( '&' . $var . '=' . $item[$val] ); } echo '"); return false;\''; } else { echo ''; echo issetVal( $item[$key], '***' ); echo ''; } } echo ''; } if ( ! isset( $link['add']['first'] ) || ( $stop - $start + 1 ) < $link['add']['first'] ) { if ( isset( $link['add']['link'] ) && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { echo ''; } elseif ( isset( $link['add']['span'] ) && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { echo ''; } elseif ( isset( $link['add']['html'] ) && $cols ) { echo ''; if ( $remove && ! isset( $_REQUEST['_ROSARIO_PDF'] ) && ! empty( $link['add']['html']['remove'] ) ) { echo ''; } elseif ( $remove && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { echo ''; } foreach ( (array) $column_names as $key => $value ) { echo ''; } echo ''; } } echo '
' . _( 'Delete' ) . '' . ParseMLField( $value ) . '' . ParseMLField( $value ) . '' . ParseMLField( $value ) . '
' . button( 'add', $link['add']['title'], $link['add']['link'] ) . '
' . button( 'add' ) . $link['add']['span'] . '
' . $link['add']['html']['remove'] . '' . button( 'add' ) . '' . $link['add']['html'][$key] . '
' . button( 'remove', $button_title, '"' . $button_link . '"' ) . '' : ''; if ( empty( $link[$key] ) || $item[$key] === false || isset( $_REQUEST['_ROSARIO_PDF'] ) ) { echo issetVal( $item[$key], ' ' ); echo '
' . button( 'add', issetVal( $link['add']['title'], '' ), $link['add']['link'] ) . '
' . button( 'add' ) . $link['add']['span'] . '
' . $link['add']['html']['remove'] . '' . button( 'add' ) . '' . issetVal( $link['add']['html'][$key], '' ) . '
'; echo empty( $options['header'] ) ? '' : '
'; } // END PRINT THE LIST ---. // NO RESULTS, BUT HAS ADD FIELDS ---. if ( $result_count == 0 ) { if ( ! empty( $link['add']['link'] ) && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { echo '
' . button( 'add', issetVal( $link['add']['title'], '' ), $link['add']['link'] ) . '
'; } elseif ( ( ! empty( $link['add']['html'] ) || ! empty( $link['add']['span'] ) ) && count( $column_names ) && ! isset( $_REQUEST['_ROSARIO_PDF'] ) ) { if ( ! empty( $link['add']['html'] ) ) { echo '
'; echo ''; foreach ( (array) $column_names as $key => $value ) { echo ''; } echo ''; foreach ( (array) $column_names as $key => $value ) { echo ''; } echo '
' . _( 'Delete' ) . '' . str_replace( ' ', ' ', $value ) . '
'; echo ! empty( $link['add']['html']['remove'] ) ? $link['add']['html']['remove'] : button( 'add' ); echo '' . issetVal( $link['add']['html'][$key], '' ) . '
'; } elseif ( ! empty( $link['add']['span'] ) ) { echo '
' . button( 'add' ) . $link['add']['span'] . '
'; } } echo empty( $options['header'] ) ? '' : '
'; } // END NO RESULTS, BUT HAS ADD FIELDS ---. echo ''; // .list-outer. // List After hook. do_action( 'functions/ListOutput.fnc.php|list_after' ); } /** * Reindex Results * Starting from 1 * * Local function * * @example $result = _ReindexResults( $result ); * * @param array $array Array to reindex * @return array Reindexed Array */ function _ReindexResults( $array ) { $new = array(); $i = 1; foreach ( (array) $array as $value ) { $new[$i] = $value; $i++; } return $new; } class Rosario_List implements Countable { /** * Get the count of elements in the container array. * * @link http://php.net/manual/en/countable.count.php * * @return int */ public function count() { return count( $this->container ); } } /** * Search List * * Local function * * @example $result = _listSearch( $result, $LO_search ); * @since 5.8 * * @param array $result ListOutput result. * @param string $LO_search ListOutput search term. * @return array $result Searched result. */ function _listSearch( $result, $LO_search ) { $result_count = count( $result ); $search_term = trim( mb_strtolower( str_replace( "''", "'", $LO_search ) ) ); if ( mb_substr( $search_term, 0, 1 ) != '"' || mb_substr( $search_term, -1, 1 ) != '"' ) { $search_term = str_replace( '"', '', $search_term ); while ( $space_pos = mb_strpos( $search_term, ' ' ) ) { $terms[mb_substr( $search_term, 0, $space_pos )] = 1; $search_term = mb_substr( $search_term, ( $space_pos + 1 ) ); } $terms[trim( $search_term )] = 1; } else { // Search "expression". $search_term = str_replace( '"', '', $search_term ); $terms[$search_term] = 1; } /* TRANSLATORS: List of words ignored during search operations */ $ignored_words = explode( ', ', _( 'of, the, a, an, in' ) ); foreach ( $ignored_words as $word ) { unset( $terms[trim( $word )] ); } foreach ( (array) $result as $key => $value ) { $values[$key] = 0; foreach ( (array) $value as $val ) { // FJ better list searching by isolating the values. $val = mb_strtolower( strip_tags( preg_replace( '/]*>(.*?)<\/script>/is', "", $val ) ) ); if ( $search_term == $val ) { // +25 if Exact match. $values[$key] += 25; continue; } foreach ( (array) $terms as $term => $one ) { if ( mb_strpos( $val, $term ) !== FALSE ) { // +3 for each Term found. $values[$key] += 3; } } } if ( $values[$key] == 0 ) { unset( $values[$key] ); unset( $result[$key] ); $result_count--; } } // Add Relevance column. if ( ! $result_count ) { return $result; } array_multisort( $values, SORT_DESC, $result ); $result = _ReindexResults( $result ); $values = _ReindexResults( $values ); $last_value = 1; $scale = ( 100 / $values[$last_value] ); for ( $i = $last_value; $i <= $result_count; $i++ ) { $score = (int) ( $values[$i] * $scale ); $result[$i]['RELEVANCE'] = '
' . $score . '
'; } return $result; } /** * Save / Export List to CSV (OpenOffice), Tab (Excel) or XML * * Local function * * @example _listSave( $result, $column_names, Preferences( 'DELIMITER' ) ); * @since 2.9 * @since 5.8 Export list to Excel using MicrosoftXML (more reliable). * * @param array $result ListOutput $result * @param array $column_names ListOutput $column_names * @param string $singular ListOutput $singular * @param string $plural ListOutput $plural * @param string $delimiter CSV|Tab|XML * @return void Outputs file and exits */ function _listSave( $result, $column_names, $singular, $plural, $delimiter ) { $format_value = function ( $value ) { $value = trim( preg_replace( '/ +/', // Remove double spaces. ' ', str_replace( array( "\r", "\n", "\t", '[br][br]' ), // Convert new lines to [br], remove tabs. array( '', '[br]', '', '[br]' ), html_entity_decode( // Decode HTML entities. strip_tags( // Remove HTML tags. str_ireplace( array( ' ', '
' ), // Convert   to space,
to [br]. array( ' ', '[br]' ), $value ) ), ENT_QUOTES ) ) ) ); // Remove first [br] if any. return mb_strpos( $value, '[br]' ) === 0 ? mb_substr( $value, 4 ) : $value; }; switch ( $delimiter ) { case 'CSV': $extension = 'csv'; $delimiter = ','; break; case 'XML': $extension = 'xml'; $delimiter = ""; break; default: // Tab. $extension = 'xls'; $delimiter = "\t"; break; } // Clear output. ob_end_clean(); $formatted_columns = $formatted_result = array(); // Format Columns. foreach ( (array) $column_names as $column ) { if ( $column !== '' ) { $column = ParseMLField( $column ); $column = $format_value( $column ); $column = str_replace( '[br]', ' ', $column ); } if ( $extension === 'csv' ) { $column = '"' . str_replace( '"', '""', $column ) . '"'; } $formatted_columns[] = $column; } $i = $extension === 'xls' ? 1 : 0; // Format Results. foreach ( (array) $result as $item ) { $formatted_result[$i] = array(); foreach ( (array) $column_names as $key => $value ) { $value = issetVal( $item[$key], '' ); if ( $value !== '' ) { $value = preg_replace( '!([^<]+)<.*!i', '\\1', $value ); $value = preg_replace( '!!i', '', $value ); $value = $format_value( $value ); $replace_br = $extension === 'xml' ? '[br]' : ' '; $value = str_replace( '[br]', $replace_br, $value ); } if ( $extension === 'csv' ) { $value = '"' . str_replace( '"', '""', $value ) . '"'; } $formatted_result[$i][] = $value; } $i++; } // Generate output. if ( $extension === 'xls' ) { /** * Export list to Excel using MicrosoftXML (more reliable). * * @uses php-excel class. * * @since 5.8 * * @link https://github.com/oliverschwarz/php-excel */ require_once 'classes/ExcelXML.php'; $excel_xml = new Excel_XML; $formatted_rows = array_merge( array( $formatted_columns ), $formatted_result ); $excel_xml->addWorksheet( ProgramTitle(), $formatted_rows ); $excel_xml->sendWorkbook( ProgramTitle() . '.xls' ); exit(); } elseif ( $extension === 'csv' ) { // 1st line: Columns. $output = implode( $delimiter, $formatted_columns ); $output .= "\n"; // Then values. foreach ( (array) $formatted_result as $result_line ) { $output .= implode( $delimiter, $result_line ); $output .= "\n"; } } // XML. else { $sanitize_xml_tag = function ( $name ) { // Remove punctuation excepted underscores, points and dashes. $name = preg_replace( "/(?![.\-_])\p{P}/u", '', $name ); // Lowercase and replace spaces by underscores. $name = mb_strtolower( str_replace( ' ', '_', $name ) ); if ( (string) (int) mb_substr( $name, 0, 1 ) === mb_substr( $name, 0, 1 ) ) { // Name cannot start with a number. $name = '_' . $name; } return $name; }; $elements = 'items_set'; $element = 'item'; if ( $plural !== '.' ) { // Sanitize XML tag names. $elements = $sanitize_xml_tag( $plural ); $element = $sanitize_xml_tag( $singular ); } $output = '' . "\n" . '<' . $elements . '>' . "\n"; foreach ( (array) $formatted_result as $result_line ) { $output .= "\t" . '<' . $element . '>' . "\n"; foreach ( (array) $result_line as $key => $value ) { if ( $formatted_columns[$key] === '' ) { $column = 'column_' . ( $key + 1 ); } else { // Sanitize XML tag names. $column = $sanitize_xml_tag( $formatted_columns[$key] ); } // http://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents $value = str_replace( '[br]', '
', htmlspecialchars( $value, ENT_QUOTES ) ); $output .= "\t\t" . '<' . $column . '>' . $value . '' . "\n"; } $output .= "\t" . '' . "\n"; } $output .= ''; } // Download file header( "Cache-Control: public" ); header( "Content-Type: application/" . $extension ); header( "Content-Length: " . strlen( $output ) ); header( "Content-Disposition: inline; filename=\"" . ProgramTitle() . "." . $extension . "\"\n" ); echo $output; exit(); }