WordPress.org

Ready to get started?Download WordPress

Forums

http://wordpress.org/plugins/plugin-organizer/ Breaks 3.7 (20 posts)

  1. Radices
    Member
    Posted 9 months ago #

    Should add this one to the Master List. The author is working on a fix. Hacking the core can work as a temporary solution. (Did for me)

    Call to undefined function wp_get_current_user() in /home/.../public_html/.../wordpress/wp-includes/user.php on line 215

    that doesn't require the uploading of the entire INCLUDES directory.

    You need to add this line to the top of your CAPABILITIES.PHP file -

    require_once ('pluggable.php');

    so it looks like this -

    <?php
    
    require_once ('pluggable.php');
    /**
     * WordPress Roles and Capabilities.
  2. Samuel Wood (Otto)
    Tech Ninja
    Posted 9 months ago #

    This is not a valid solution. Hacking core never is, really.

    Instead, the author of this plugin should move this line of code:

    http://plugins.svn.wordpress.org/plugin-organizer/tags/3.2.6/plugin-organizer.php

    $PluginOrganizer = new PluginOrganizer(WP_PLUGIN_DIR . "/" . plugin_basename(dirname(__FILE__)), plugins_url("", __FILE__));

    That should not be happening in the main body of the plugin. Instead, he should be putting it in a function and hooking that function to the plugins_loaded hook.

    It is not valid to do anything that requires user information (or any pluggable function) until the plugins_loaded hook fires. This happens after the pluggable.php file is loaded.

    Additionally, all those "add_actions" and everything else in that main plugin body, which all need the $PluginOrganizer variable, should be moved into the class itself. Into the constructor or somewhere else. Then they can be modified to not reference the global variable, by using the $this variable to add in the various hooks needed.

  3. Jeff Sterup
    Member
    Posted 9 months ago #

    Neither of you seem to understand the problem or the "proper" temporary solution. The wp_query->get_posts function has been modified in the new version of WordPress. It now calls a function defined in pluggable.php which isn't defined until after plugins are loaded. That is a bug that I need to report to the wp developers. A temporary solution is to include pluggable.php in the top of the PluginOrganizerMU.class.php file.

  4. Spiril
    Member
    Posted 9 months ago #

    @Jeff - Could you please tell me how to include pluggable.php - what code and where exactly should I place it. I would appreciate your help very much and I'm sure others would too, thank you. :)

  5. Radices
    Member
    Posted 9 months ago #

    Adding the following code at line 11 of the PluginOrganizerMU.class.php file in your mu-plugins folder will get rid of the error but may cause other problems.

    require_once( ABSPATH . WPINC . '/pluggable.php' );
    The pluggable.php file has several functions in it that can be overridden by plugins. If you are using any plugins that need to override the functions within it those plugins will most likely fail because they will not be able to redefine the functions. I would suggest trying this if you are in need of an immediate fix. I will continue to work on a permanent fix but using pluggable.php in this way is not recommended.

  6. Spiril
    Member
    Posted 9 months ago #

    Thanks Radices - I found that also in another thread and it works. I hope I haven't created problems for my other plugins.

    Plugin Organizer is one of the best plugins so I really hope the plugin Author comes up with a fix soon.

    Thanks for the plugin Jeff - nice work.

  7. Radices
    Member
    Posted 9 months ago #

    You can also get the latest version of WordPress here and just replace the includes/user.php file. You can then undo the changes in PluginOrganizerMU.class.php and everything should work properly.

  8. Samuel Wood (Otto)
    Tech Ninja
    Posted 9 months ago #

    Jeff, that isn't a "bug". Plugins should not be calling functionality like "get_posts" until after the plugins_loaded action hook, at minimum.

    Plugins should not "do" anything of substance when they're loaded, because the WordPress environment is not fully defined when plugins are loaded. If you try to do something like that, then you're doing it too early in the process.

    Also, adding pluggable.php like that to where you're suggesting is too soon because it breaks the pluggable functionality. The pluggable.php must be included after plugins are loaded, because that is how plugins can override the pluggable functions.

    This isn't a core bug. You need to adjust your plugin to not do whatever it is doing at load time, and instead defer that functionality until the plugins_loaded action hook.

  9. Samuel Wood (Otto)
    Tech Ninja
    Posted 9 months ago #

    Radices: That new adjustment to the user.php file will eliminate the symptom, but it won't fix the cause. Even with that fix, the data that will be returned to a get_posts call made too early will have incorrect user id's (they'll be zero).

  10. Jeff Sterup
    Member
    Posted 9 months ago #

    Samuel Wood, Yes I understand what you're saying and no PluginOrganizer is not doing anything when it is loaded. It only calls get_posts when the active_plugins option hook is called to determine which plugins to load based off of postmeta. I have looked for a better way for an mu plugin to get a piece of postmeta but it looks as if the core is built to only allow that with the entire post. Is there a way for me to query the post_id for a post that has postmeta matching a given url at that point? Then use that post_id to pull a seperate piece of postmeta containing the list of plugins? As far as I know get_posts is the only way to accomplish it.

  11. Samuel Wood (Otto)
    Tech Ninja
    Posted 9 months ago #

    Yes, I see the problem. You have a separate MU plugin that hooks in very early, so then when it loads the active plugins list, you filter it and in that filter you're trying to get_posts.

    The short of it is that you shouldn't be storing what plugins load in the posts table. That's a pretty bad place to store system-critical information, and what plugin code is loading is definitely what I would consider system-critical. WP stores the list of active plugins in the options table, you should store your list there too, as a single option, instead of as a custom post type.

    Retrieving a list of posts, even a list of custom posts, is a relatively expensive operation. This operation should be minimized to the extent possible, and loading a bunch of data from the posts table just to load plugins is frankly silly.

  12. Jeff Sterup
    Member
    Posted 9 months ago #

    Ok, there is absolutely nothing wrong with storing an array in the postmeta table and that is absolutely the best way to store it since every post can have a separate array. This is functionality that the community really wants. Before wp 3.7 there was a variable set for the user_id in the get_posts function. That has now been removed and replaced with a function call that is not defined. How is that not a bug? Seems I've uncovered more than one bug in the wordpress core. Aside from the code change that caused this error there needs to be a function where I can give it a string and it returns an array of post id's by matching it on the meta values in the database. Having to return an array containing the entire post object for several posts when I just need the post_id is ridiculous bloat. Please stop being close minded and actually take a look at my plugin and what it does. What you are suggesting will not work. I can create my own custom queries but this is also frowned on I think.

  13. Samuel Wood (Otto)
    Tech Ninja
    Posted 9 months ago #

    Before wp 3.7 there was a variable set for the user_id in the get_posts function. That has now been removed and replaced with a function call that is not defined. How is that not a bug?

    Before 3.7, the user id came from a global which, at that point in the code, would not have been set correctly. So the information in there was invalid (zero).

    In 3.7, you get an error. And rightfully so, honestly, because the data should not be available at that point in time. The user information code has always been in pluggable functions, and pluggable functions have to be loaded after plugins.

    A patch has been made to trunk to restore the broken behavior, by simply having it use zero there. However, this only hides the error, it doesn't fix the problem. If you attempt to get post information like this before "plugins_loaded" (or "init"), then the information will be incorrect.

    Things load in a certain order for a reason, and if you attempt to do something before the relevant code has loaded, then you're going to get incorrect results.

    Aside from the code change that caused this error there needs to be a function where I can give it a string and it returns an array of post id's by matching it on the meta values in the database.

    Querying based on meta_value is a horrible idea and should not be done.
    The meta_value column is not indexed and arbitrarily large (TEXT field). So any query based on it will probably cause a slow table-scan.

    Searching based on meta_value does not scale, basically. It's fine for like a small blog or something, but once you start getting into hundreds of thousands of posts, your performance will tank. The meta tables are meant to be arbitrary data, not arbitrary *searchable* data.

    If you need to store information to find posts in this manner, then it should be a taxonomy, not meta. Taxonomies are optimized for this sort of thing.

  14. Radices
    Member
    Posted 9 months ago #

    The problem was that the WordPress update crashed and white screened because the core did not handle the error gracefully.

    Putting it on the backs of plugin developers is well elitist to be kind. I understand that your a Ninja Otto, and we are mere peons however do you think you might offer up solutions instead of insults and criticism.

    There is a real need in the community for selective plugin loading at the post and page level. Yes that's what this plugin does, I only say this because it's obvious you have no idea what its function is. Or if you do you have no idea how to do it differently than Jeff has done. Perhaps you could expand on how a user could at the post level, select which plugins to load and which plugins not to load using Taxonomies?

  15. Jeff Sterup
    Member
    Posted 9 months ago #

    I can surely switch the query to use a taxonomy but this will still have the same problem with using the get_posts function. How can I query the post id based off of the permalink without loading an array containing the full post objects? Why do i have to load the entire post object when I just want the id? I only store the permalink in postmeta because the core gives no other option for doing it at that point. So what do you suggest? Because simply saying it is not right is not going to solve it.

  16. Samuel Wood (Otto)
    Tech Ninja
    Posted 9 months ago #

    How can I query the post id based off of the permalink without loading an array containing the full post objects?

    That's just my point. You can't do any form of query of the posts table properly at any point in time before all the plugins are loaded.

    Which is why it's a bad idea to use the posts table, in any way, to store information about what plugins are going to load.

    If you want to solve your problem, then you only have one legitimate option that is future-proof: Don't store that type of information in the posts or postmeta tables. Store it somewhere else. The options table would be preferred.

  17. Samuel Wood (Otto)
    Tech Ninja
    Posted 9 months ago #

    Or honestly, make your own table for this sort of thing.

    You're wanting to store a bunch of information indexed by (essentially) the permalink, and then to be able to retrieve it prior to the main query being executed, then use that information to change the load sequence accordingly.

    This sort of thing obviously isn't suitable for the posts table, because the query hasn't executed yet and the rewrites have not even been parsed. WordPress, at that point in time, has no idea what post is actually being queried for. It won't know that until the wp() function is run, which doesn't happen until after wp-load.php has exited.

    All the stuff WordPress does inside the wp-load process is to load stuff up. It doesn't parse the query until the wp() function is called (from wp-blog-header.php), which in turn calls the $wp->main() code. The main query isn't ready until the 'wp' action fires. So even 'init' is really too early to base anything off the main page query.

    So you're basically having to do your own index based on the URL in some way, or execute a whole long running query process. But what you really want is just some data about the post that the current URL is referring to.

    Which sounds very much like a case of "make your own table" to me. Two columns, one can be the url or whatever index you wish to use, the other can be an array of the plugins or whatever information you want to use to change the load order.

    Normal queries don't happen until the load order is well and truly over, so changing the load order based on the query is always going to be problematic, no matter how you slice it. Perhaps the queried URL is more reliable for your needs.

  18. Jeff Sterup
    Member
    Posted 9 months ago #

    Ok so you are obviously not going to see that this is a bug and not a feature, as you have explained it. If the meta table is not built for searching why would you ever put functionality into the core to search off of the meta value? Why is it not valid to use a function that has been provided in earlier included code at the time my plugin executes its option hook?
    Its not about the rules you have made for the wordpress core. Its about basic structure. If you provide me a function it should work. If that function worked without errors in the past you should not introduce an error and then blame the person calling your provided function. There was a set variable in the old version of the function. It has been replaced by an undefined function call.
    There is no reason I can't retrieve a post once the functionality is included. I don't want the other plugins added functionality to interfere with my queries so waiting until they are loaded would not make any sense. I can understand that you are saying the core is built that way and it is not going to change. So I guess I will have to move some or all of the data into a separate table and go back to dealing with the headaches this caused so many people.

  19. Samuel Wood (Otto)
    Tech Ninja
    Posted 9 months ago #

    If the meta table is not built for searching why would you ever put functionality into the core to search off of the meta value?

    Oh, believe me, if I was in charge, that functionality would not be there.

    Why is it not valid to use a function that has been provided in earlier included code at the time my plugin executes its option hook?

    Because the function has not been loaded yet. There are cross-intersecting concerns here. Functions use code from many other files in various ways. And yet the files have to load in some particular order. If you try to do things before the relevant functions are loaded and ready, then you're going to get errors or incorrect results. Pick your poison.

    If you provide me a function it should work. If that function worked without errors in the past you should not introduce an error and then blame the person calling your provided function. There was a set variable in the old version of the function. It has been replaced by an undefined function call.

    Like I said earlier, the fatal error has been fixed in the latest trunk version of WordPress, and the fix will very likely be in 3.7.1. However, that doesn't make calling this function too early capable of giving you the correct responses.

    You're relying on undocumented and undefined behaviors of a complex system. There are defined and supported behaviors for functions and timing and when things are supposed to happen. And then there are side-effects. You have been relying on the fact that a side-effect worked for a very long time, but that effect was never an intended or documented behavior. So when it broke, well, I'm surprised that you are surprised.

    There is no reason I can't retrieve a post once the functionality is included.

    Even with the fix, you still cannot retrieve the post *properly* because the users have not loaded. And if your suggested fix of loading pluggable.php yourself is implemented, then you break other plugins that are trying to override the pluggable functions.

    Essentially, you have a no-win situation. I'm trying to suggest a way for you to win the situation, and that way is to not store this information in posts or post meta, and to not use post-queries to access it. This solves your problem. I'm sorry that you don't like the solution or my answers, but those answers are not going to change just because you disagree with them.

    You're free to disagree with me. I don't mind. Many do. But I'm legitimately trying to help you here by telling you ways of restructuring your code to overcome your problems and future-proof it. I'm not just being a dick. Really.

  20. Sergey Biryukov
    WordPress Dev
    Posted 9 months ago #

    The wp_query->get_posts function has been modified in the new version of WordPress. It now calls a function defined in pluggable.php which isn't defined until after plugins are loaded.

    Fixed in WordPress 3.7.1: http://core.trac.wordpress.org/ticket/25690.

    Aside from the code change that caused this error there needs to be a function where I can give it a string and it returns an array of post id's by matching it on the meta values in the database. Having to return an array containing the entire post object for several posts when I just need the post_id is ridiculous bloat.

    You can add 'fields' => 'ids' to your get_posts() call if you only need the IDs. I would really look into implementing Otto's suggestions though.

Reply

You must log in to post.

About this Topic