Changeset 3431360
- Timestamp:
- 01/03/2026 12:12:34 AM (5 months ago)
- Location:
- xv-random-quotes/trunk
- Files:
-
- 10 edited
-
changelog.txt (modified) (1 diff)
-
js/migration.js (modified) (1 diff)
-
readme.txt (modified) (1 diff)
-
src/Output/QuoteOutput.php (modified) (1 diff)
-
src/PostTypes/QuotePostType.php (modified) (4 diffs)
-
src/Rendering/LegacyRenderer.php (modified) (2 diffs)
-
src/Rendering/QuoteRenderer.php (modified) (1 diff)
-
src/RestAPI/QuoteEndpoint.php (modified) (5 diffs)
-
vendor/composer/installed.php (modified) (2 diffs)
-
xv-random-quotes.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
xv-random-quotes/trunk/changelog.txt
r3430809 r3431360 1 1 == XV Random Quotes == 2 3 = 2.2.0 = 4 Bugfix: migration progress text shows correct migrated count 5 Bugfix: quote content key in REST API response 6 Bugfix: after_all/before_all wrappers not used on every quote 7 Improvement: Overview page added back 8 Improvement: Better quote title/preview in admin list 2 9 3 10 = 2.1.0 = -
xv-random-quotes/trunk/js/migration.js
r3430809 r3431360 124 124 const $text = $progressNotice.querySelector('.xv-migration-progress-text'); 125 125 if ($text) { 126 $text.textContent = `Migrated ${result. migrated} of ${result.total} quotes (${percentage}%)`;126 $text.textContent = `Migrated ${result.offset} of ${result.total} quotes (${percentage}%)`; 127 127 } 128 128 } -
xv-random-quotes/trunk/readme.txt
r3430809 r3431360 6 6 Tested up to: 6.9 7 7 Requires PHP: 7.4 8 Stable tag: 2. 1.08 Stable tag: 2.2.0 9 9 License: GPLv2 or later 10 10 License URI: http://www.gnu.org/licenses/gpl-2.0.html -
xv-random-quotes/trunk/src/Output/QuoteOutput.php
r3430809 r3431360 40 40 $this->quote_queries = new QuoteQueries(); 41 41 $this->renderer = new QuoteRenderer(); 42 } 43 44 /** 45 * Get renderer instance 46 * 47 * @return QuoteRenderer 48 */ 49 public function get_renderer() { 50 return $this->renderer; 42 51 } 43 52 -
xv-random-quotes/trunk/src/PostTypes/QuotePostType.php
r3429335 r3431360 93 93 */ 94 94 public function add_custom_columns( $columns ) { 95 // Insert source column after author (taxonomy) 95 // Remove the default title column 96 unset( $columns['title'] ); 97 98 // Insert custom quote column at the beginning (after checkbox) 96 99 $new_columns = array(); 97 100 foreach ( $columns as $key => $value ) { 98 $new_columns[ $key ] = $value; 101 if ( 'cb' === $key ) { 102 $new_columns[ $key ] = $value; 103 $new_columns['quote_preview'] = __( 'Quote', 'xv-random-quotes' ); 104 } else { 105 $new_columns[ $key ] = $value; 106 } 107 108 // Insert source column after author (taxonomy) 99 109 if ( 'taxonomy-quote_author' === $key ) { 100 110 $new_columns['quote_source'] = __( 'Quote Source', 'xv-random-quotes' ); … … 111 121 */ 112 122 public function render_custom_column( $column, $post_id ) { 123 if ( 'quote_preview' === $column ) { 124 $post = get_post( $post_id ); 125 $title = $post->post_title; 126 $content = wp_strip_all_tags( $post->post_content ); 127 128 $edit_link = get_edit_post_link( $post_id ); 129 130 // Start the preview link 131 echo '<a class="row-title" href="' . esc_url( $edit_link ) . '" style="display: flex; align-items: center; gap: 10px;">'; 132 133 // Show image if available (featured image or first image in content) 134 if ( has_post_thumbnail( $post_id ) ) { 135 $first_image = get_the_post_thumbnail( $post_id, array( 50, 50 ), array( 'style' => 'display: block; flex-shrink: 0;' ) ); 136 echo wp_kses_post( $first_image ); 137 } elseif ( $first_image = $this->get_first_image_from_content( $post->post_content ) ) { 138 $first_image = preg_replace( '/(width|height)="\d*"\s*/i', '', $first_image ); 139 $first_image = str_replace( '<img', '<img style="width:50px;height:50px;object-fit:cover;flex-shrink:0;"', $first_image ); 140 echo wp_kses_post( $first_image ); 141 } 142 143 // Show text (title or content excerpt) 144 if ( ! empty( trim( $title ) ) ) { 145 echo '<strong>' . esc_html( $title ) . '</strong>'; 146 } elseif ( ! empty( trim( $content ) ) ) { 147 echo '<span>' . esc_html( wp_trim_words( $content, 10 ) ) . '</span>'; 148 } elseif ( $this->get_alt_text( $first_image ) ) { 149 echo '<span>' . esc_html( $this->get_alt_text( $first_image ) ) . '</span>'; 150 } else { 151 echo '<span>' . esc_html__( '(no content)', 'xv-random-quotes' ) . '</span>'; 152 } 153 154 echo '</a>'; 155 } 156 113 157 if ( 'quote_source' === $column ) { 114 158 $source = get_post_meta( $post_id, '_quote_source', true ); … … 123 167 124 168 /** 169 * Get alt text from an image HTML string 170 * 171 * @param string $image_html Image HTML. 172 * @return string|null Alt text or null if not found. 173 */ 174 private function get_alt_text( $image_html ) { 175 if ( preg_match( '/alt=["\']([^"\']*)["\']/', $image_html, $matches ) ) { 176 return $matches[1]; 177 } 178 return null; 179 } 180 181 /** 125 182 * Make custom columns sortable 126 183 * … … 156 213 } 157 214 } 215 216 /** 217 * Get the first image tag from post content 218 * 219 * @param string $content Post content. 220 * @return string|null First image HTML or null if none found. 221 */ 222 private function get_first_image_from_content( $content ) { 223 preg_match( '/<img[^>]+>/i', $content, $matches ); 224 return ! empty( $matches ) ? $matches[0] : null; 225 } 158 226 } -
xv-random-quotes/trunk/src/Rendering/LegacyRenderer.php
r3430809 r3431360 80 80 } 81 81 82 // Wrap in outer container if not disabled 83 if ( ! $disable_aspect ) { 82 // Only wrap with before_all/after_all when rendering a single quote 83 // For multiple quotes, these wrappers are applied in render_multiple_quotes() 84 if ( ! $disable_aspect && ! $is_multi ) { 84 85 $output = wp_kses_post( $wrappers['before_all'] ) . $output . wp_kses_post( $wrappers['after_all'] ); 85 86 } … … 94 95 * @return array Wrapper settings. 95 96 */ 96 p rivatefunction get_wrappers( $disable_aspect ) {97 public function get_wrappers( $disable_aspect ) { 97 98 if ( $disable_aspect ) { 98 99 return array( -
xv-random-quotes/trunk/src/Rendering/QuoteRenderer.php
r3430809 r3431360 114 114 $output .= '</ul>'; 115 115 116 // Wrap with before_all/after_all for legacy mode 117 if ( ! $disable_aspect ) { 118 $wrappers = $this->legacy_renderer->get_wrappers( $disable_aspect ); 119 $output = wp_kses_post( $wrappers['before_all'] ) . $output . wp_kses_post( $wrappers['after_all'] ); 120 } 121 116 122 return $output; 117 123 } -
xv-random-quotes/trunk/src/RestAPI/QuoteEndpoint.php
r3430809 r3431360 97 97 $contributor = $request->get_param( 'contributor' ); 98 98 99 // Use QuoteOutput class 100 $quote_output = new QuoteOutput(); 101 $html = $quote_output->get_random_quotes( 102 array( 103 'categories' => $categories, 104 'sequence' => $sequence, 105 'multi' => $multi, 106 'offset' => 0, 107 'disableaspect' => $disableaspect, 108 'contributor' => $contributor, 109 ) 110 ); 111 112 // Check if we got any quotes 113 if ( empty( $html ) ) { 114 return new \WP_Error( 115 'no_quotes', 116 'No quotes found matching the criteria', 117 array( 'status' => 404 ) 118 ); 119 } 120 121 // Get quote data for metadata 99 // Get quotes first (before rendering) 122 100 $quote_queries = new QuoteQueries(); 123 101 … … 125 103 $categories_array = ! empty( $categories ) ? explode( ',', $categories ) : array(); 126 104 127 // Get quotes for metadata 105 // Build query args 106 $query_args = array( 107 'posts_per_page' => $multi, 108 ); 109 110 // Add ordering 111 if ( $sequence ) { 112 $query_args['orderby'] = 'date'; 113 $query_args['order'] = 'ASC'; 114 } else { 115 $query_args['orderby'] = 'rand'; 116 } 117 118 // Get quotes 128 119 if ( ! empty( $categories_array ) ) { 129 $quotes = $quote_queries->get_quotes_by_categories( 130 $categories_array, 131 array( 132 'posts_per_page' => $multi, 133 'orderby' => $sequence ? 'rand' : 'date', 134 ) 135 ); 120 $quotes = $quote_queries->get_quotes_by_categories( $categories_array, $query_args ); 136 121 } else { 137 $quotes = $quote_queries->get_all_quotes( 138 array( 139 'posts_per_page' => $multi, 140 'orderby' => $sequence ? 'rand' : 'date', 141 ) 142 ); 122 $quotes = $quote_queries->get_all_quotes( $query_args ); 143 123 } 144 124 … … 150 130 array( 'status' => 500 ) 151 131 ); 132 } 133 134 // Check if we got any quotes 135 if ( empty( $quotes ) ) { 136 return new \WP_Error( 137 'no_quotes', 138 'No quotes found matching the criteria', 139 array( 'status' => 404 ) 140 ); 141 } 142 143 // Render HTML from the same quotes we'll use for metadata 144 $quote_output = new QuoteOutput(); 145 $renderer = $quote_output->get_renderer(); 146 147 if ( $multi > 1 ) { 148 $html = $renderer->render_multiple_quotes( $quotes, $disableaspect ); 149 } else { 150 $html = $renderer->render_quote( $quotes[0], false, $disableaspect ); 152 151 } 153 152 … … 161 160 $quote = $quotes[0]; 162 161 163 $response_data['quote_id'] = $quote->ID; 164 $response_data['quote_text'] = $quote->post_title; 162 $response_data['quote_id'] = $quote->ID; 163 $response_data['quote_text'] = wp_strip_all_tags( $quote->post_content ); 164 $response_data['quote_content'] = $quote->post_content; 165 165 166 166 // Get author … … 183 183 } else { 184 184 // For multi-quote, provide basic metadata 185 $response_data['quote_id'] = 0; 186 $response_data['quote_text'] = ''; 187 $response_data['author'] = ''; 188 $response_data['source'] = ''; 189 $response_data['categories'] = array(); 185 $response_data['quote_id'] = 0; 186 $response_data['quote_text'] = ''; 187 $response_data['quote_content'] = ''; 188 $response_data['author'] = ''; 189 $response_data['source'] = ''; 190 $response_data['categories'] = array(); 190 191 } 191 192 -
xv-random-quotes/trunk/vendor/composer/installed.php
r3429831 r3431360 4 4 'pretty_version' => 'dev-main', 5 5 'version' => 'dev-main', 6 'reference' => ' 1e7b2c70a5d3f77696f34428e28ff6df9eba2ecc',6 'reference' => '6458b7b024b57cfcfe7728209c7cc038570ed3c3', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 14 14 'pretty_version' => 'dev-main', 15 15 'version' => 'dev-main', 16 'reference' => ' 1e7b2c70a5d3f77696f34428e28ff6df9eba2ecc',16 'reference' => '6458b7b024b57cfcfe7728209c7cc038570ed3c3', 17 17 'type' => 'wordpress-plugin', 18 18 'install_path' => __DIR__ . '/../../', -
xv-random-quotes/trunk/xv-random-quotes.php
r3430809 r3431360 5 5 Author: Xavi Ivars 6 6 Author URI: https://xavi.ivars.me/ 7 Version: 2. 1.07 Version: 2.2.0 8 8 Requires at least: 6.0 9 9 Requires PHP: 7.4
Note: See TracChangeset
for help on using the changeset viewer.