Talk PHP to me like I'm 5!

darnoldy

Curmudgeon
Joined
Dec 20, 2004
Messages
1,733
Folks-

I am trying to modify a template from a WordPress plugin. I suspect my problem has more to do with my lack of knowledge of PHP, than specifics of either Wordpress or the plugin. I am an extreme novice at PHP—but I'm the only developer I can afford.

The plugin code:
PHP:
    <?php foreach ( $fields->not( 'social' ) as $field ): ?>
        <?php echo $field->html; ?>
    <?php endforeach; ?>

returns a series of lines of HTML that look like:
HTML:
<div class="wpbdp-field-display wpbdp-field wpbdp-field-value field-display field-value wpbdp-field-tasting_fee wpbdp-field-meta wpbdp-field-type-textfield wpbdp-field-association-meta  " ><label>Tasting Fee:</label> <span class="value">5.00</span></div>

I would like to be able to use the value of some of the fields in other ways: as a conditional to display/hide other content, as a class, as list items, etc. I would also be able to intermix some additional HTML objects among the items (like divs to group some items).

So, how do I go about getting the value of individual fields out of the $fields array, or a sequence of fields?
 

pierce

Habitué
Joined
Apr 10, 2016
Messages
1,165
You need to figure what's in this field var.

Start with

print_r($field);

I'm on a mobile so this is a bit tedious, but that goes somewhere inside the foreach.

Then:

exit();

Right after. Hopefully this will dump what ever is in it.

Then you'll be able to start figuring out stuff.

Field looks like an object, so.. you may need to read the php file that describes this object..

But see what the pront_r does.

There is also dump_var()

Which dumps everything and may crash your browser... So use with caution
 

darnoldy

Curmudgeon
Joined
Dec 20, 2004
Messages
1,733
Well... that was interesting...

I edited the template to:
PHP:
    <?php foreach ( $fields->not( 'social' ) as $field ): ?>
        <?php echo $field->html;
        print_r($field); ?>

    <?php endforeach; ?>

and the resulting items in the display now look like:

HTML:
            <div class="wpbdp-field-display wpbdp-field wpbdp-field-value field-display field-value wpbdp-field-tasting_fee wpbdp-field-meta wpbdp-field-type-textfield wpbdp-field-association-meta  "><label>Tasting Fee:</label> <span class="value">5.00</span></div>

_WPBDP_Lightweight_Field_Display_Item Object
(
    [field:private] =&gt; WPBDP_FormField Object
        (
            [id:private] =&gt; 18
            [type:private] =&gt; WPBDP_FieldTypes_TextField Object
                (
                    [name:private] =&gt; Textfield
                )

            [association:private] =&gt; meta
            [shortname:private] =&gt; tasting_fee
            [label:private] =&gt; Tasting Fee
            [description:private] =&gt;
            [tag:private] =&gt;
            [weight:private] =&gt; 11
            [validators:private] =&gt; Array
                (
                    [0] =&gt; decimal_number
                )

            [display_flags:private] =&gt; Array
                (
                    [0] =&gt; listing
                )

            [field_data:private] =&gt; Array
                (
                )

            [css_classes] =&gt; Array
                (
                )

            [html_attributes] =&gt; Array
                (
                )

        )

    [listing_id:private] =&gt; 22
    [display:private] =&gt; listing
    [html_:private] =&gt; <div class="wpbdp-field-display wpbdp-field wpbdp-field-value field-display field-value wpbdp-field-tasting_fee wpbdp-field-meta wpbdp-field-type-textfield wpbdp-field-association-meta  "><label>Tasting Fee:</label> <span class="value">5.00</span></div>
    [value_:private] =&gt;
    [raw_:private] =&gt;
)
 

darnoldy

Curmudgeon
Joined
Dec 20, 2004
Messages
1,733
pierce — The plugin's documentation says
$fields: object. Instance of WPBDP_Field_Display_List providing easy access to the field values (among other things) for this particular listing. You can do a lot of things with this object, but most of the time you just want to call echo $fields->html; to output the list of fields applying to the listing.
, so you were right about it being an object.
 

pierce

Habitué
Joined
Apr 10, 2016
Messages
1,165
So what exactly are you trying to do?

There is nothing much to use in that object, that will restrict a field from being displayed
 

darnoldy

Curmudgeon
Joined
Dec 20, 2004
Messages
1,733
There is nothing much to use in that object...
I guess the documentation's claim that
You can do a lot of things with this object,...
is a bit overstated!

What I'd like to do is to get access to the values in those fields in such a way that I can use them like:

Code:
<h2 class ="$fields[11]">...
Code:
<if $fields[21]> ... <else /> ... </if>

I editted the template to:
PHP:
   <?php foreach ( $fields->not( 'social' ) as $field ): ?>
        <p><?php echo $field->id; ?>
    <?php echo $field->value; ?></p>
    <?php endforeach; ?>
and got a series of number/value pairs—is there some way to use this foreach loop to create a new array that I can access in the way that I want?
 

pierce

Habitué
Joined
Apr 10, 2016
Messages
1,165
Ok, so the code is probably broken down to 3 layers.

Model - direct access to DB (objects that do $user->getData($userID);)
Controller - the "Objects", that link everything together they process actions like merge 20 $user objects together...
View - The templating system that accesses the the information rendered by the "Controller" foreach $userArray as $user, echo $user->name;...

Your trying to hammer a nail in with the end of a screw driver, because it looks like your trying to do it at the view point.
 

pierce

Habitué
Joined
Apr 10, 2016
Messages
1,165
A debug mode may help show what files are being used.. which may give hints
 

darnoldy

Curmudgeon
Joined
Dec 20, 2004
Messages
1,733
Your trying to hammer a nail in with the end of a screw driver...
I strongly suspected that I may be asking for a purple squirrel—trying to hammer a nail with a screwdriver is better!

Ok, so the code is probably broken down to 3 layers.
Okay— I think I understand that. We need to find the place where the data is actually fetched from the database. WordPress mixes procedures and presentation in their templates in a way that always confounds me.

A debug mode may help show what files are being used.. which may give hints
Great! How do I do that? (Did I mention that I'm a novice?)
 

darnoldy

Curmudgeon
Joined
Dec 20, 2004
Messages
1,733
Well... that was overwhelming! TMI!

okay...I want to go back a bit, 'cause I think I'm missing something.

The PHP Tutorial says:
The foreach loop works only on arrays, and is used to loop through each key/value pair in an array.

Syntax
foreach ($array as $value) {
code to be executed;
}
For every loop iteration, the value of the current array element is assigned to $value and the array pointer is moved by one, until it reaches the last array element.

So, if I understand properly, in:
PHP:
   <?php foreach ( $fields->not( 'social' ) as $field ): ?>
        <p><?php echo $field->value; ?></p>
    <?php endforeach; ?>
an array $fields has been created somewhere previously (in another, enclosing, template?). The foreach then steps through that array and places each element of it into $field, where echo $field->value displays the value property of that element. This is repeated for each element of $fields.

If my reasoning is sound, echo $fields[1]->value; should display the value property of element 1 of the $fields array. But it doesn't! It gives a fatal error, saying that _WPBDP_Lightweight_Field_Display_Item Object cannot be treated as an array. What am I missing?
 

pierce

Habitué
Joined
Apr 10, 2016
Messages
1,165
Oki,

This is part of the class from: class-field-display-list.php

Code:
public function __get( $key ) {
        $field_id = 0;

        if ( 'html' == $key ) {
            $html  = '';
            $html .= implode( '', wp_list_pluck( $this->items_for_display(), 'html' ) );

            // FIXME: move this to a compat layer.
            if ( 'listing' == $this->display ) {
                $html = apply_filters( 'wpbdp_single_listing_fields', $html, $this->listing_id );
            }

            return $html;
        }

        if ( '_h_' == substr( $key, 0, 3 ) )
            return method_exists( $this, 'helper__' . substr( $key, 3 ) ) ? call_user_func( array( $this, 'helper__' . substr( $key, 3 ) ) ) : '';

        if ( 'id' == substr( $key, 0, 2 ) )
            $field_id = absint( substr( $key, 2 ) );

        if ( ! $field_id )
            $field_id = isset( $this->names_to_ids[ $key ] ) ? $this->names_to_ids[ $key ] : 0;

        if ( $field_id && isset( $this->items[ $field_id ] ) )
            return $this->items[ $field_id ];

        wpbdp_debug( 'Invalid field key: ' . $key );
        return new WPBDP_NoopObject(); // FIXME: templates shouldn't rely on a field existing.
        return false;
    }.

you can see here that it is a "GET" or a special type of __get, which allows you to do $object->key type operations.

What your looking for are the other functions:

Code:
public function not( $filter ) {
        return $this->filter( '-' . $filter );
    }

    public function filter( $filter ) {
        $neg = ( '-' == substr( $filter, 0, 1 ) );
        $filter = ( $neg ? substr( $filter, 1 ) : $filter );

        $filtered = array();

        $type_filter = '';
        $association_filter = '';
        $social_filter = ( $filter == 'social' );

        foreach ( $this->items as &$f ) {
            if ( $social_filter && $neg && ! $f->field->display_in( 'social' ) )
                $filtered[] = $f;
            elseif ( $social_filter && ! $neg && $f->field->display_in( 'social' ) )
                $filtered[] = $f;
        }

        $res = new self( $this->listing_id, $this->display, $filtered );
        $res->freeze();

        return $res;
    }

    public function exclude( $fields_ ) {
        $exclude = is_array( $fields_ ) ? $fields_ : explode( ',', $fields_ );
        $filtered = array();

        if ( ! $exclude )
            return $this;

        foreach ( $this->items as $f ) {
            if ( in_array( 'id_' . $f->id, $exclude ) || in_array( 't_' . $f->field->get_tag(), $exclude, true ) || in_array( $f->field->get_short_name(), $exclude, true ) )
                continue;

            $filtered[] = $f;
        }

        $res = new self( $this->listing_id, $this->display, $filtered );
        $res->freeze();
        return $res;
    }

So... its hard for me to wrap my head around it.. because i dont understand it fully as I am only picking parts out.
 

darnoldy

Curmudgeon
Joined
Dec 20, 2004
Messages
1,733
pierce —I really appreciate your help. This plugin does almost everything I need (once I buy some of the premium modules). The only real sticking point is the ability to control the display of the listings to the degree that I want. I have posted in the author's support forum—we'll see what he has to say.
 

pierce

Habitué
Joined
Apr 10, 2016
Messages
1,165
the only clue i have is that there is a tasting fee that costs "5"

are you trying to limit the tasting fee between 0-10 or 5-20?

or some other filter
 

darnoldy

Curmudgeon
Joined
Dec 20, 2004
Messages
1,733
At the point of display, I don't want to do any filtering at all. All of the search functions have been done, this page is displaying the chosen record from the database.
The script, as written, assumes that the values in each of the fields within that record will become page content. Because of its mechanism, the foreach wraps the value of each field in the same html tag.

I want to be able to wrap different html around some of them.

I want to use the value of one of the fields as a class within a div tag.

I would like to use a couple of the values as conditionals, to control the display of other values.
 

darnoldy

Curmudgeon
Joined
Dec 20, 2004
Messages
1,733
Right... but I may have confused you.

That is one field out of the 20 or so that are in the record. I only posted I one to show the structure.
 
Top