michaeluno / admin-page-framework

Facilitates WordPress plugin and theme development.
http://admin-page-framework.michaeluno.jp/
Other
339 stars 71 forks source link

Problem: Sortable Field with dynamic entries #165

Closed patrickf0 closed 9 years ago

patrickf0 commented 9 years ago

Hi Michael,

I ran into a strange problem. I want to dynamically add some fields that should be sortable. I programmed a primitive example, so you´re able to confirm the problem.

As you can see I dynamically add some fields to a revealer which are sortable, but when I change the order, the order is not saved. Strange thing: When I add them by hand into the set_up method ist works...

Is there a failure in my code?

https://gist.github.com/patrickf0/99c6471e77378ad3bd7e

michaeluno commented 9 years ago

Dynamically updating field attributes when the fields are sorted is working properly. However, it seems the validation callback is not catching the field values added via the field_definition_{...} hooks. That causes the data not to be saved.

I'll see if this can be fixed. Thanks for the report.

Meanwhile, it would be appreciated if you could try with earlier versions of the framework to see if it occurs. To make the test plugin small, you can remove the revealer field from the test plugin as it is not related to this problem. And add a validation callback method to it to log the passed input data.

    public function validation_FilterOrder_MetaBox( $aInput, $aOldInput, $oAdminPage ) {

        AdminPageFramework_Debug::log( $aInput );
        return $aInput;        

    }

Update:

michaeluno commented 9 years ago

I've updated the 3.3.2b branch which should fix this problem. Download.

patrickf0 commented 9 years ago

Strange thing happens when I use a wpdb Query inside the field definition method.

My example uses a static array, but in my project I´m using wpdb-object to retrieve my array...

If figured out that the sorting data is stored when I use this static array:

$posts_by_tax = array(
            array('term_taxonomy_id' => '92','term_id' => '87','taxonomy' => 'ticket_list','description' => '','parent' => '0','count' => '3','object_id' => '1261','term_taxonomy_id' => '92','term_order' => '0','term_id' => '87','name' => '4-Fahrtenkarten','slug' => '4-fahrtenkarten','term_group' => '0','ID' => '1261','post_author' => '17','post_date' => '2014-06-11 15:16:37','post_date_gmt' => '2014-06-11 13:16:37','post_content' => '','post_title' => '4-Fahrtenkarte','post_excerpt' => '','post_status' => 'publish','comment_status' => 'closed','ping_status' => 'closed','post_password' => '','post_name' => '4-fahrtenkarte','to_ping' => '','pinged' => '','post_modified' => '2014-07-04 11:44:02','post_modified_gmt' => '2014-07-04 09:44:02','post_content_filtered' => '','post_parent' => '0','guid' => '','menu_order' => '5','post_type' => 'post_ticket','post_mime_type' => '','comment_count' => '0','post_expire' => NULL),
            array('term_taxonomy_id' => '92','term_id' => '87','taxonomy' => 'ticket_list','description' => '','parent' => '0','count' => '3','object_id' => '1262','term_taxonomy_id' => '92','term_order' => '0','term_id' => '87','name' => '4-Fahrtenkarten','slug' => '4-fahrtenkarten','term_group' => '0','ID' => '1262','post_author' => '17','post_date' => '2014-06-11 15:16:37','post_date_gmt' => '2014-06-11 13:16:37','post_content' => '','post_title' => '4-Fahrtenkarte, Kind','post_excerpt' => '','post_status' => 'publish','comment_status' => 'closed','ping_status' => 'closed','post_password' => '','post_name' => '4-fahrtenkarte-kind','to_ping' => '','pinged' => '','post_modified' => '2014-07-04 11:43:42','post_modified_gmt' => '2014-07-04 09:43:42','post_content_filtered' => '','post_parent' => '0','guid' => '','menu_order' => '6','post_type' => 'post_ticket','post_mime_type' => '','comment_count' => '0','post_expire' => NULL),
            array('term_taxonomy_id' => '92','term_id' => '87','taxonomy' => 'ticket_list','description' => '','parent' => '0','count' => '3','object_id' => '1263','term_taxonomy_id' => '92','term_order' => '0','term_id' => '87','name' => '4-Fahrtenkarten','slug' => '4-fahrtenkarten','term_group' => '0','ID' => '1263','post_author' => '17','post_date' => '2014-06-11 15:16:38','post_date_gmt' => '2014-06-11 13:16:38','post_content' => '','post_title' => '4-Fahrtenkarte, Kurzstrecke','post_excerpt' => '','post_status' => 'publish','comment_status' => 'closed','ping_status' => 'closed','post_password' => '','post_name' => '4-fahrtenkarte-kurzstrecke','to_ping' => '','pinged' => '','post_modified' => '2014-07-04 11:41:34','post_modified_gmt' => '2014-07-04 09:41:34','post_content_filtered' => '','post_parent' => '0','guid' => '','menu_order' => '8','post_type' => 'post_ticket','post_mime_type' => '','comment_count' => '0','post_expire' => NULL),
        );

But when I switch to a query which gives me the exact same array, sorting data is not stored! Has it sth. to do with the global $wpdb var or the query itself? I can´t figure it out.

global $wpdb;

        $sql = "SELECT * FROM $wpdb->term_taxonomy t
                LEFT JOIN $wpdb->term_relationships r ON t.term_taxonomy_id=r.term_taxonomy_id
                LEFT JOIN $wpdb->terms s ON t.term_id=s.term_id
                LEFT JOIN $wpdb->posts p ON p.ID=r.object_id
                WHERE t.taxonomy IN ( $taxonomies )
                AND t.term_id = $term
                AND p.post_status = 'publish'
                ORDER BY p.post_title ASC";

        $posts_by_tax = $wpdb->get_results( $sql, 'ARRAY_A' );

The Log array gives:

[revealer] => Array
    (
        [sort_by_tax] => #fieldrow-revealer_term_87
    )

instead of:

[revealer] => Array
    (
        [sort_by_tax] => #fieldrow-revealer_term_87
        [term_87] => Array
            (
                [0] => 4-Fahrtenkarte, Kurzstrecke
                [1] => 4-Fahrtenkarte
                [2] => 4-Fahrtenkarte, Kind
            )

    )
michaeluno commented 9 years ago

Double check the version number in your actual project. The log file also should indicate the version you are using. It should be 3.3.2b04 or above.

2014/11/03 11:26:53.9457 +3.946 ... 3.3.2b02<--- this part
patrickf0 commented 9 years ago

I´m using v3.3.2b04

michaeluno commented 9 years ago

Try inserting the logging method in your field_definition_{...}() method to see the contents of the modified $aFields array, right before it returns it. It is possible that your database query is not returning expected results.

patrickf0 commented 9 years ago

The query is correct ... if not my sortable fields would not show up but they are correct and the static array is exported from phpmyadmin from the same query...

I figured out that when I use $wpdb->get_results to get the array the sorting-data is not saved, but with the hard coded array it works... I do not quite understand why.

I´m using the $wpdb->get_results method in a foreach several times... I also tried to divert the array-retrieve to another function, but still the same problem...

patrickf0 commented 9 years ago

Ok I tried to use new WP_Query instead of the wpdb-object and now it works...

But I don´t understand it...

michaeluno commented 9 years ago

Are you enabling WP_DEBUG and WP_DEBUG_LOG? If not, turn them on and the debug log should give you some clues.

For your information, the admin page url for saving post data including meta box field data is not the same as the one displaying the post editing page. WordPress redirects the page to http://{site url}/wp-admin/post.php and save the post and returns to the post editing page with the url that has url queries like http://{site url}/wp-admin/post.php?post=443&action=edit&message=1. And the definition_field_{....}() callback method will to be called in the both pages. So you need to make sure that your database query runs fine in the post saving page http://{site url}/wp-admin/post.php.

patrickf0 commented 9 years ago

You´re right, I guess the database query is not running correctly on the post savings page. I just have no idea how to get this query run properly on the post saving page.

I thought that wpdb object is running perfectly... any idea?

michaeluno commented 9 years ago

What I can suggest are:

patrickf0 commented 9 years ago

As you said, the fielddefinition{...} method is called on the post.php when saving the data, but how can I get the post_id at this moment.

Through global $post and $post->ID I get the ID within the validation method, but not within the fielddefinition{...} method. Thats when some of my code is not working any more...

Any idea?

What I wanna do:

public function field_definition_FilterOrder_MetaBox( $aFields ) {

    global $post;
    echo $post->ID;

    $tax_selected = array_pop( get_post_meta( $post->ID, 'taxonomy_sec', false ) );

... 
}
michaeluno commented 9 years ago

Use $_POST['post_ID'] in post.php.

Just keep in mind that no post id is set when you open the post adding page (post-new.php) so I guess your custom term listing output for sortable fields won't work when you first try to create a post.

On the other hand, if you are editing a post, the $_GET['post'] variable holds the ID.

patrickf0 commented 9 years ago

Thanks. Working now.

The Problem with a new post is already cleared, but thanks for the advice.

michaeluno commented 9 years ago

Glad it helped!