• Resolved islp

    (@islp)


    Hi, I developed a small plugin for documents management. The plugin is not available to the public, it is strictly related to a particular website. The purpose of the plugin is manage documents like they were pages, create a documents archive, make documents searchable in the default search. It worked fine on some WP versions, then, I couldn’t find WHEN, it broke for some reason.

    The issues:

    1. when I click the name of the user who posted a post, I usually get a list of the posts written by that user: instead, if the plugin is active, I get 404 error;

    2. when I click the name of a month in my posts Archive, I generally get a list of any post posted in that particular month: instead, if the plugin is active, I get a 404 error (no error at all IF for some reason there’s my CPTDocument between the matches);

    I tried flushing permalinks, with no luck.

    htaccess is fine.

    I tried using a default theme on another domain, with a completely new WP, with no luck.

    So, there’s something broken in my plugin, but I don’t understand what.

    Can you help me?

    This is ALL the code:

    <?php
    
    /*
    Plugin Name: MyDocuments
    Plugin URI: https://
    Description: Manages documents, creates documents archive, make them searchable in the default search
    Version: 0.1
    Author: PLSI
    Author URI: https://
    Tags: files, management
    License: for what, it doensn't work either
    Text Domain: plsi-documents
    */
    
    if (!defined('ABSPATH')) exit;
    
    define( 'DIR_PATH', plugin_dir_path( __FILE__ ) );
    
    define('FORMATS', array(
        'pdf' => 290975,
        'doc' => 290977,
        'docx' => 290977,
    	'ppt' => 290976,
    	'pptx' => 290976,
    	'xls' => 290978,
    	'xlsx' => 290978,
    	'multiple_files' => 290974,
    	'generic_type_A' => 290972,
    	'generic_type_B' => 290973
    ));
    
    if ( ! class_exists( 'MyDocuments' ) ) {
    
    	class MyDocuments {
    		
    		public function __construct() {
    			$this->setup_actions();
    		}
    		
    		public function setup_actions() {
    			
    			register_activation_hook( DIR_PATH, array( 'MyDocuments', 'activate' ) );
    			register_deactivation_hook( DIR_PATH, array( 'MyDocuments', 'deactivate' ) );
    			add_action('save_post_docs', [$this, 'save_MyDocument'], 10, 2);
    			add_action('init', [$this, 'add_MyDocuments_custom_post_type']);
    
                add_filter( 'post_updated_messages', function($messages) {
    				global $post, $post_ID;
    				$link = esc_url( get_permalink($post_ID) );
    			
    				$messages['docs'] = array(
    					0 => '',
    					1 => sprintf( __('Document updated. <a href="%s">View document</a>'), $link ),
    					2 => __('Custom field updated.'),
    					3 => __('Custom field deleted.'),
    					4 => __('Document updated.'),
    					5 => isset($_GET['revision']) ? sprintf( __('Document restored to revision from %s'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
    					6 => sprintf( __('Document published. <a href="%s">View document</a>'), $link ),
    					7 => __('Document saved.'),
    					8 => sprintf( __('Document submitted. <a target="_blank" href="%s" rel="noopener noreferrer">Preview document</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
    					9 => sprintf( __('Document scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s" rel="noopener noreferrer">Preview document</a>'), date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), $link ),
    					10 => sprintf( __('Document draft updated. <a target="_blank" href="%s" rel="noopener noreferrer">Preview document</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
    				);
    				return $messages;
    			});
    
    			add_filter( 'bulk_post_updated_messages', function( $bulk_messages, $bulk_counts ) {
    				$bulk_messages['docs'] = array(
    					'updated'   => _n( "%s document updated.", "%s documents updated.", $bulk_counts["updated"] ),
    					'locked'    => _n( "%s document not updated, somebody is editing it.", "%s documents not updated, somebody is editing them.", $bulk_counts["locked"] ),
    					'deleted'   => _n( "%s document permanently deleted.", "%s documents permanently deleted.", $bulk_counts["deleted"] ),
    					'trashed'   => _n( "%s document moved to the Trash.", "%s documents moved to the Trash.", $bulk_counts["trashed"] ),
    					'untrashed' => _n( "%s document restored from the Trash.", "%s documents restored from the Trash.", $bulk_counts["untrashed"] ),
    				);
    			
    				return $bulk_messages;
    			}, 10, 2 );
    
    			// help 
    			add_action('admin_head', function() {
    
    				$screen = get_current_screen();
    				
                    if(($screen->action == 'add' || $screen->action == '') && $screen->id == 'docs')
    				{
    					$args = [
    						'id' => 'docs_help',
    						'title' => 'Document help',
    						'content' => '<h3>Help</h3>help text
    ',
    					];
    				
    					$screen->add_help_tab($args);
    				}
    			});
    
    			
    			add_action('pre_get_posts', function ($query) {
    				if (!is_admin() && $query->is_main_query() && empty($query->query_vars['suppress_filters'])) {
    
    					if (is_archive()) {
    
    						if (is_category()) {
    							$query->set('post_type', ['post', 'docs']);
    						} else {
    							if (!is_tag()) {
    								$query->set('post_type', 'docs');
    							} else {
    								$query->set('post_type', 'post');
    							}
    						}
    					}
    				}
    			});
    
    		
    
    		}
    		
    		public static function activate() {
    			//flush_rewrite_rules( false );
    		}
    		
    		public static function deactivate() {
    			//flush_rewrite_rules( false );
    		}
    
    		function set_ui_labels($singular = 'Post', $plural = 'Posts') {
    			$p_lower = strtolower($plural);
    			$s_lower = strtolower($singular);
    		
    			return [
    				'name' => $plural,
    				'singular_name' => $singular,
    				'menu_name' => $plural,
    				'add_new_item' => "New $singular",
    				'edit_item' => "Edit $singular",
    				'view_item' => "View $singular",
    				'view_items' => "View $plural",
    				'search_items' => "Search $plural",
    				'not_found' => "No $p_lower found",
    				'not_found_in_trash' => "No $p_lower found in trash",
    				'parent_item_colon' => "Parent $singular",
    				'all_items' => "All $plural",
    				'archives' => "$singular Archives",
    				'attributes' => "$singular Attributes",
    				'insert_into_item' => "Insert into $s_lower",
    				'uploaded_to_this_item' => "Uploaded to this $s_lower",
    			];
    		}
    		
    		function add_MyDocuments_custom_post_type()
    		{
                unregister_post_type('docs');
    
    			$labels = $this->set_ui_labels('Document', 'Documents');
    
    			register_post_type('docs', array(
    			        'labels' => $labels,
    			        'public' => true,
                                    'publicly_queryable' => true,
    			        'has_archive' => true,
    			        'menu_icon' => 'dashicons-text-page',
    					'exclude_from_search' => false,
    			        'taxonomies' => ['category'],
    			        'rewrite' => array('slug' => 'docs'),
    			        'supports' => array('title', 'editor', 'author', 'thumbnail', 'excerpt', 'custom-fields', 'revisions'),
    			          )
    			    );
    		}
    		
    		function save_MyDocument( $post_id, $post ) {
    			
    			if (isset($post->post_status) && $post->post_status === 'auto-draft') {
    				return;
    			}
    			
    			
    			$u = $post->post_content;
    
    			if($u === ''){return;}
    
    			$matches = [];
    
    			$DOM = new DOMDocument();
    			
    			$DOM->loadHTML($u);
    			
    			$a = $DOM->getElementsByTagName('a');
    			
    			foreach($a as $link){
    			
    				$matches[]=$link->getAttribute('href');
    			
    			}
    
    			
    			$matches = array_unique($matches);
    			
    			$matches_count = count($matches);
     
    			
    			if($matches_count > 0) {
    
    				if($matches_count == 1){
    
    				
    					$file_extension = wp_check_filetype($matches[0])['ext'];
                        
    					
    					if($file_extension){
    					
    						
    						if(array_key_exists($file_extension, FORMATS)){
    
    						   		
    						    	set_post_thumbnail($post, FORMATS[$file_extension]);
    
    				        	}else{
    
    								
    								set_post_thumbnail($post, FORMATS['generic_type_A']);
    						}
    
    				    }else{
    
    						
    						set_post_thumbnail($post, FORMATS['generic_type_B']);
    
    					}
    
    				}else{
    
    					
    					set_post_thumbnail($post, FORMATS['multiple_files']);
    				
    				}
                
    		}else{
    			
    			delete_post_thumbnail($post);
    		}
    		
    	}
    
    	}
    	
    	
    	$wp_plugin_template = new MyDocuments();
    
    }
Viewing 7 replies - 1 through 7 (of 7 total)
  • Thread Starter islp

    (@islp)

    I found what was causing the issue: if you remove the add_action('pre_get_posts'... code, it seems to work. Problem is I coded this plugin long ago and I really don’t remember what I wanted to do. I commented it too and I wrote it solved “the archive issue”, but I don’t remember this issue, either.

    Moderator bcworkz

    (@bcworkz)

    Your pre_get_posts callback is managing what post types should be queried for various archive queries. Author and date requests are archive queries, but they are neither category nor tag queries, so the post type gets set to “docs”, thus no posts are queried and there were no docs matching the requested date or author.

    Since there are all sorts of archive queries, using not a tag logic isn’t the best approach as it basically sets a new default state. It’s better to address only the exceptions to default so everything else behaves normally.

    I don’t wish to be critical, but it may help in your understanding that this callback, on any WP version, would have never worked on any author or date request that’s intended to return posts. Only docs would be returned if there’s a date or author match. More likely the problem was just not noticed until now.

    Thread Starter islp

    (@islp)

    @bcworkz : well, while it’s very uncommon for me and others to click the author’s name at the end of a post, the users generally use the month archive quite a lot (I’m a user too and I never noticed anything strange, for years, not just few days or weeks).

    My goal with that code was maybe to exclude my custom posts from the results of the date archive, and only have them as search results and in its specific archive (my.domain/docs). There could have been other sub-goals, but I really don’t remember any detail and, even if I generally comment a lot, this time what I left was really poor and didn’t let me fully understand what was the issue I was trying to address.

    Author and date requests are archive queries, but they are neither category nor tag queries (…)

    I used for sure the plugin Query Monitor and built the conditional logic based on the results I saw in its UI. So, I probably noticed when I was in the main archive page is_archive, is_date, is_month and is_ssl were true. When I clicked the author’s name is_archive, is_author and is_ssl were true. And so on.

    But, as I told you, it has been working for years, at least in the monthly archive, where it’s literally impossible to have months without posts (and I never saw any of my custom posts there)

    Thread Starter islp

    (@islp)

    @bcworkz : even if this plugin has never been very important and I completely forgot it, I found 5 minutes to make a little test.

    The origin of the issue is definitely here:

    if (!is_tag()) {
       $query->set('post_type', 'docs');
        } else {
       $query->set('post_type', 'post');
    }

    So,

    when it IS archive, it is NOT category and it is NOT tag, I wanted to display docs.
    When it IS archive, it is NOT category and it is TAG, I wanted to display posts.

    Now, where I get my beautiful 404s I have:

    is_archive, is_date, is_month, is_ssl

    and

    is_archive, is_author, is_ssl

    and the code always falls in the first part of the if, attempting to display docs: when there aren’t docs WP responds with 404.

    Strangely enough, even if this is clearly an error, no error ever displayed before (NOT in the monthly archive, at least), so I suppose that some change at the WP level or at the PHP version level (I upgraded many times) could have hypotetically caused a different interpretation of this code for quite some time. But, it’s just an idea, I’m really surprised.

    I’m quite uncertain about what to do now because, while the preceding part of the code is quite clear, I don’t know why I decided to consider the tag case as a separate one.

    • This reply was modified 2 years, 1 month ago by islp.
    Moderator bcworkz

    (@bcworkz)

    when it IS archive, it is NOT category and it is NOT tag, I wanted to display docs

    But isn’t this why you get 404s? An author or date query IS an archive and not category nor tag. Maybe you should be checking is_author() and ‘is_date()` to get posts? That would be one approach.

    There might be a better approach. The default is to get posts, so you really needn’t do anything when that’s what you want. Simply return without changing anything. You will need to decide under which conditions you want docs or both. Those will be the exceptions you should target in conditional statements. All of the requests we’re discussing are archive queries, so checking is_archive() doesn’t really serve much purpose.

    Your’e better off testing for what you do want and not what you don’t want, e.g. avoid NOT logic. Or if it’s necessary, combine it with another condition to avoid a situation where the conditional statement applies to everything else.

    Thread Starter islp

    (@islp)

    @bcworkz :

    But isn’t this why you get 404s?

    Of course, but what I fail to understand is why things always worked well in the monthly archive.

    Another thing I wanted to point out is that this has been a Saturday afternoon project: since the plugin was never really used by website users, I completely forgot it and did not update the code.

    I’ll treasure any suggestion you posted, thanks. ??

    Moderator bcworkz

    (@bcworkz)

    I can only speak to what’s in front of us today. Differing behavior in the past is not something I can speculate about. I suggest removing the core of your callback, keeping only the not admin and main query parts (and the suppress filters bit if you prefer) Take another run at a logic sequence keeping in mind my “better approach” suggestions from my previous post.

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘Custom post type based plugin breaks month archive resulting in 404 error’ is closed to new replies.