Call to undefined function register_extended_post_type()

I tried to replicate example from the Sage book by creating a mu-plugin. This is what I did on local:

  1. Ran composer require johnbillion/extended-cpts to enable custom post types.
  2. Created mu-plugins\post-types\petplace.php:
    <?php
    add_action( 'init', function() {register_extended_post_type( 'petplace'....
  3. Created petswelcome.php to load my custom post type:
    <?php
    require_once(dirname(__FILE__) . '/post-types/petplace.php');
  4. Successfully tested my new post type on local
  5. Added my new files to .gitignore and made sure they were uploaded to my remote
    # Application
    web/app/plugins/*
    ...
    !web/app/plugins/.gitkeep
    web/app/mu-plugins/*/
    !web/app/mu-plugins/post-types/
    !web/app/mu-plugins/extended-cpts/
    ...
    *_development*.sql

Remote
On remote I am getting Uncaught Error: Call to undefined function register_extended_post_type() at error.log.

How do I fix this error?

More information
I downloaded the library and included it manually:
require_once 'extended-cpts/extended-cpts.php';

Now I am getting error Cannot redeclare register_extended_taxonomy()
(previously declared in .../mu-plugins/extended-cpts/functions.php:115)
in .../vendor/johnbillion/extended-cpts/functions.php

Apparently, WordPress no longer thinks register_extended_post_type() is undefined but does not like the same function in two places.

Manual installation works fine on both local and remote (I have to remove CPT library with composer first to avoid double declaration error):
composer remove johnbillion/extended-cpts
require_once 'extended-cpts/extended-cpts.php';

How do you deploy the files to remote location? Are you sure you have uploaded everything from vendor?

How do you deploy the files to remote location?

I commit to my github repo and run ./bin/deploy.sh production petswelcome.org

Are you sure you have uploaded everything from vendor?

yes I am sure, this is why my error points to existing /vendor/johnbillion/extended-cpts/functions.php,

By default Bedrock tells git to ignore any files in folders in mu-plugins (see this line), since composer is tasked with tracking, installing, and updating plugins. Have you checked to make sure the file in your mu-plugin is actually be uploaded? You may need add a line to your .gitignore to make sure your plugin is tracked.

@alwaysblank yes, I had run into .gitignore issue before, I have added my folders to my .gitignore like this:
!web/app/mu-plugins/post-types/
!web/app/mu-plugins/extended-cpts/

I made sure my new folders and files made it to my github repo and remote server (they were not there indeed).

The issue I having now is something else.

Why are you including extended-cpts as a plugin? The author explicitly says not to do this:

Extended CPTs is a developer library, not a plugin, which means you need to include it somewhere in your own project. You can use Composer:

If you are using Bedrock and ran composer require johnbillion/extended-cpts from your Bedrock site directory so that it was added to your site’s composer.json then there is no need manually import the package–it is being autoloaded by Bedrock and the functions it provides will be made available to anything loaded after that. In general when you’re using Composer’s autoloader, you should not manually import files from Composer-managed packages. Your error says that you’re importing the same thing twice, which tries to define an already defined function. This is probably happening because you load it once with require_once and then Composer tries to autoload it later. (That’s just a guess; you’ve provided very little code or context here, and the narrative of what you’ve done and what exactly the problem is is a little confused.)

I’d recommend read up on how the Composer autoloader and PSR-4 work, because Bedrock and Sage make significant use of them:

I’ll try to explain better :sweat:

If you are using Bedrock and ran composer require johnbillion/extended-cpts … the functions it provides will be made available to anything loaded after that.

I agree, but in my case Wordpress invlokes register_extended_post_type() before it registers my CPT library, so it throws undefined function error. It happens only on remote.

Your error says that you’re importing the same thing twice

Yes, I was trying to make a point that Wordpress can “see” my library I had installed with composer but it invokes it “too late”.

will it help if I branch out the version where this error happen and share a link?

That definitely would help.

Again - if you get the error about the function defined twice then you should not get the error about function being undefined. Something is weird here and I would like to see your code.

Are you running composer from your bedrock install or from the sage?

1 Like

this is my test repository with the issue recreated (there is no encryption etc):

Unfortunately I hit letsencrypt weekly limit certificate count so I can’t deploy this exact code right now. The same code caused Call to undefined function register_extended_post_type() few days ago.

You’re requiring johnbillion/extended-cpts in your theme. You should be requiring it in your site. In WordPress’s load order, mu-plugins are loaded before themes, which means that when your mu-plugin loads extended-cpts is not available to be autoloaded.

Even though it’s a few years old at this point, I’d recommend reading through the “Twelve-Factor WordPress App” post series we published about the philosophy behind the roots stack. If you understand why Bedrock is arranged the way it is, then avoiding problems like this is much easier.

In your case, you’ve created a convoluted and ultimately broken dependency chain. If you consider your entire site to be an “App,” then your dependencies are:

  • Plugins (MU and Normal)
  • Your theme
  • WordPress itself
  • Any other PHP packages you’ve installed

If one of those things (in this case your mu-plugin) requires a package (extended-cpts), that package should also be a dependency of your app, so that the presence of that package is dependent on the app not dependent on a separate, semantically unrelated package (your theme).

3 Likes

Wow thanks for the superdetailed answer, this explains how WordPress calls a function before it’s defined. I will declare extended-cpts dependency at the site level and try deployment again.

Twelve-Factor WordPress App

I discovered 12Factor philosophy at my new job recently and saw it again here, so I have no questions why Bedrock is built this way. Thanks again.

This topic was automatically closed after 42 days. New replies are no longer allowed.