PDA

View Full Version : Use array from plugin in template as conditional


hilaryl
10-02-2014, 12:36 AM
Hey Guys,

I have read a lot about using variables from plugins inside the FORUMDISPLAY template. But nothing really covers what I'm trying to do.

What I'm trying to do is create a conditional based on specific parent forumids - but using an array.

I can access the parentlist id's on a page using
{vb:raw $foruminfo[parentlist]}
The parentlist is equal to something like '690,610,-1' (current forumid,parent forumid,no parent).

Once I have that, I want to basically say, if 'parentlist' CONTAINS '610' then show this.

I know you can't do a CONTAINS conditional that way because vbulletin doesn't allow it, and the parenlist is just a string, not an array.

So I need to make a plugin to turn the parentlist into and array. Then register it for use in the FORUMDISPLAY template. For that I used
$parentarray = explode(',', $foruminfo[parentlist]);
vB_Template::preRegister('FORUMDISPLAY', $parentarray);
The hook location for this plugin is set to parse_templates.

Now I want to say in my FORUMDISPLAY template. If $parentarray CONTAINS '610' then show this. For which is used:
<vb:if condition="in_array(610, parentarray)"><!-- It's working --></vb:if>

That doesn't validate in the template though, which is where I'm looking for some guidance.

I believe everything is working up to the conditional statement, and I'm not sure if I'm accessing the parentarray variable in the right way.

Any help would be appreciated.

Thanks,
hilaryl

tbworld
10-02-2014, 01:07 AM
Quick look without reading... ( I will do that later... dinner is calling ) :)


<vb:if condition="in_array(610, $parentarray)"></vb:if>
The hook location is fine.

hilaryl
10-02-2014, 02:18 AM
Quick look without reading... ( I will do that later... dinner is calling ) :)


<vb:if condition="in_array(610, $parentarray))"></vb:if>


The hook location is fine.

I'm not sure if you have typed that correctly or not...but that would mean there would be two close brackets and only one open bracket?

As well as the addition of the '$' before the variable.

Thanks for your quick reply!

Cheers

tbworld
10-02-2014, 02:53 AM
Yep, I typed it quickly and the last paren should be removed. Sorry about that. I corrected the post above. Keep the '$'. :)

I was holding up dinner, and I was suppose to be grilling the steaks. :)

Are you testing on a live hosted board or a local test board? If you are on a local test board add conditionally some diagnostic functions to the safe_functions array. Even "var_dump" can be useful to see if you passed the correct data and type.

hilaryl
10-02-2014, 03:53 AM
Yep, I typed it quickly and the last paren should be removed. Sorry about that. I corrected the post above. Keep the '$'. :)

I was holding up dinner, and I was suppose to be grilling the steaks. :)

Are you testing on a live hosted board or a local test board? If you are on a local test board add conditionally some diagnostic functions to the safe_functions array. Even "var_dump" can be useful to see if you passed the correct data and type.

Haha I appreciate your dedication!

We are on a live server, so my changes are live.

Upon adding the '$', I still get an error message when I 'Save and Reload'.
Warning: Invalid argument supplied for foreach() in [path]/includes/functions.php on line 3555

The following error occurred when attempting to evaluate this template:
%1$s
This is likely caused by a malformed conditional statement. It is highly recommended that you fix this error before continuing, but you may continue as-is if you wish.

Should I just click continue and then make the change?

I would prefer it if what I was doing was legit in terms of vBulletin validation.

Cheers

tbworld
10-02-2014, 04:49 AM
I am now looking into this. I am reproducing your results. It was not doing this on my main system. but then I run a different lexical/parser setup. When I checked it against (vb 4.2.2, vb 4.2.1) -- I received the same error.

This problem might have been around a while. As this sure seems similar.
https://vborg.vbsupport.ru/showthread.php?t=109915

hilaryl
10-02-2014, 04:58 AM
We are running vBulletin 4.1.9 Patch Level 4

Cheers

tbworld
10-02-2014, 05:08 AM
Still testing...

hilaryl
10-02-2014, 05:33 AM
Still testing...

Thanks tbworld! I really appreciate your help with this.

I've had a read of the link you gave above. It appears to be exactly the same problem, however it doesn't appear to be solved.

I don't think the in_array() is the issue, because the FORUMDISPLAY template was able to validate the following, and it works as a conditionally statement too.

<vb:if condition="in_array(610, array(610,690,-1))"><!-- It's Working --></vb:if>

It must have something to do with using a variable as the actual array.

Cheers

tbworld
10-02-2014, 05:48 AM
In line (78) of template search_common.


<vb:if condition="in_array($type, $selectedtypes)"> checked="checked"</vb:if>
vb4.2.1 it parses.
vb4.2.2 it fails.

Does the conditional work correctly, if you force the saving of the template?

TheAdminMarket
10-02-2014, 10:11 AM
Just as idea, without testing anything:

<vb:if condition="in_array($type, $selectedtypes)"> checked</vb:if>


Edited: Seems that I'm out of topic. Have read only the last post and I thought that the code before was already working.

kh99
10-02-2014, 01:06 PM
I think the problem is the preRegister statement, it should be like this:

$parentarray = explode(',', $foruminfo[parentlist]);
vB_Template::preRegister('FORUMDISPLAY', array('parentarray' => $parentarray));

tbworld
10-02-2014, 07:20 PM
I think the problem is the preRegister statement, it should be like this:


Good eye! Yep, preregister variables are merged into an existing array with the template name being the key. So it must be in an array. I was concentrating on the compilation problem, so I didn't even notice. Thanks, I would have missed it. :)

The current problem, is the parsing of the vbulletin conditional when using safe_function "in_array" -- it is failing validation. I have fixed this problem at work so when I get a chance I am going to snoop at my code.

With your fix, his code should work, if he forces a save of the template. :)

hilaryl
10-02-2014, 11:23 PM
In line (78) of template search_common.


<vb:if condition="in_array($type, $selectedtypes)"> checked="checked"</vb:if>
vb4.2.1 it parses.
vb4.2.2 it fails.

Does the conditional work correctly, if you force the saving of the template?

I can't force save for some reason. When I click 'Continue' on the validation error page, it takes me to a page that says 'This template was changed by someone else while you were editing it. YOUR CHANGES HAVE NOT BEEN SAVED ...'. It has the two windows to merge the original with the edited version, so I move the conditional statement into the window I want to save, I click 'Save and Reload'. It then comes up with the original validation error screen with the 'Continue' or 'Go Back', and if I click 'Continue' it comes up with the 'This template was changed .....' again.

I know nobody else is editing anything. So not sure what is going on there.

I have also updated my plugin to what was suggested above - thanks for that!

I also have that conditional you found in the search_common templace, so that would mean that vBulletin does accept it? Or it's just forced a save?

Thanks for your help everyone.

Cheers

--------------- Added 1412297432 at 1412297432 ---------------

I attempted to put the
<vb:if condition="in_array($type, $selectedtypes)"> checked="checked"</vb:if>
into my FORUMDISPLAY template, and that gets the validation error too.

Which is strange since it is being used in the search_common template.

tbworld
10-03-2014, 12:23 AM
I also have that conditional you found in the search_common templace, so that would mean that vBulletin does accept it? Or it's just forced a save?

Which is strange since it is being used in the search_common template.

There is only one use of "in_array" in all the templates that matches your use and it fails validation. I had to force save the template.

---------------------------------------------------------

I can't force save for some reason. When I click 'Continue' on the validation error page, it takes me to a page that says 'This template was changed by someone else while you were editing it.
That error will vacate when the invalid session times out.

Let me know if you still have trouble forcing the save of the template. I do have this problem resolved on my main systems (something I fixed a long time ago), but the code cannot easily be ported and would make you non vb standard, so I am working on a easy circumvent for the problem. :)

hilaryl
10-03-2014, 01:28 AM
That error will vacate when the invalid session times out.

How long does an invalid session take to time out?

I attempted this first yesterday, and then tried it first thing today, and it still came up with the 'Someone else is editing' message.

Thanks for your ongoing support.

Cheers

hilaryl
10-08-2014, 10:54 PM
I do have this problem resolved on my main systems (something I fixed a long time ago), but the code cannot easily be ported and would make you non vb standard, so I am working on a easy circumvent for the problem. :)

How did you go with finding an easy circumvent for this problem?

I still can't force save the template which is frustrating - always comes up with the 'Someone else is editing at the same time' message.

I'm trying to think if there's another way I can get the parentid that I need.

Thanks,
hilaryl

tbworld
10-08-2014, 11:21 PM
In my own code, I fixed some small issues with the lexer, some minor issues with the parsers, and beefed up some error routines. Most of these issues were found due to us extending the templating system. The average user has probably never run into any of these issues, unless they have used the templating system extensively. vBulletin allows you to force a save on almost all errors, it gets around the few validation problems on the stock conditionals, curly, and tag definitions. That was a smart move on their part.

I am not posting the other fixes. I doubt most users will want to alter their source files or have a need for the patches. At this point only someone expanding the templater system would be interested and they are welcome to contact me.

This particular fix will assist the beginner templater as single errors were not being displayed correctly. This did impact you with the safe-function "in_array".

Replace function in "/includes/function.php" with the new function below. Sorry, this cannot be done via a plugin.

function fetch_error_array($errors)
{
$compiled_errors = array();

// TBWORLD - vBulletin.org - 2014.10.05
// Resolves one of the template erroneous compile errors and restores (broken) single error messages.
// This bug exists vBulletin v4.2.0 and earlier --> 4.2.3.beta2.

if (!is_array($errors))
{
$compiled_errors[] = $errors;
return $compiled_errors;
}
else
{
foreach ($errors as $key => $value)
{
if (is_string($value))
{
$compiled_errors[$key] = fetch_error($value);
}
else if (is_array($value))
{
$compiled_errors[$key] = call_user_func_array('fetch_error', $value);
}
}
}
return $compiled_errors;
}

hilaryl
10-09-2014, 01:10 AM
Thanks tbworld.

Ideally we would like to do as little modifying as possible to the core files.

I have actually found a way that works better for what I am trying to achieve - and it validates in the template!

Instead of trying to compare the whole parentlist array (690,610,-1) I've created variables in the custom plugin that are assigned to specific keys in the array (each forum id level).

// Get the second last key in the array and assign it to a variable
$grandparent = $parentarray[count($parentarray)-2];

I do the same to get the third last key.

Now I can access the variable in my template like this
<vb:if condition="in_array($grandparent, array(13,62))"> It's working </vb:if>

This method seems to be exactly what am after, and the best part is I don't have to force save the templates.

Thanks for all your replies everyone. Talking it out and looking at the possible options has helped me understand better what I can do/need to do.

Thanks,
hilaryl

tbworld
10-10-2014, 12:32 AM
Here is some conditional usage that you may want to ponder. Of course all of this can and maybe should be done in PHP, but sometimes this is more fun. I discovered quite a few interesting things when enhancing the template system.

One of the things I modified in the template system is a 'break' for the 'each' conditional. I am pointing this out, because in the crazy example below the routine continues to iterate the array and we may have already found our resultant.


<vb:comment>
Iterates an array for basically no reason, and if a value was found in the array
the create a new variable inside the template for altering a dynamic response. (tbworld method)
</vb:comment>

<vb:each from="show" key="show_key" value="show_value">
<vb:comment>
<!-- Just to show usage -->
key: {vb:var show_key} <br>
value: {vb:var show_value}<br>
</vb:comment>

<!-- Check for existance of key in $show -->
<vb:if condition="array_key_exists('member', $show) AND (!isset($newvar))">
<div>Array Key Exists!</div>

<!-- create or set a value to a variable -->
<vb:if condition="$newvar='Yes we created a new variable $newvar!'"></vb:if>
</vb:if>
</vb:each>

<!-- Display the new variable we just created -->
<dl>
<dd>Did we create a new variable?</dd>
<dt>{vb:raw newvar}</dt>
</dl>

<!-- --------------------------------------------------------------- -->

<!-- Key exists if not NULL -->
<vb:if condition="isset($show['member'])">--isset test --<br /></vb:if>

<!-- Expansion on the above examples, Use with caution! -->

<!-- Create a new Array -->
<vb:if condition="$new_array = array('member', 'fruit', 'fish')" ></vb:if>

<!-- Create a new Key field variable -->
<vb:if condition="$new_test_key='member'"></vb:if>

<!-- Create a variable resultant -->
<vb:if condition="$resultant=in_array($new_array[$new_test_key], $show, false)" >Test Key exist in $show array<br /></vb:if>
Have fun. :)

ozzy47
10-10-2014, 12:41 AM
On thing, <br> should be <br /> to make it XHTML valid. :)

tbworld
10-10-2014, 12:45 AM
On thing, <br> should be <br /> to make it XHTML valid. :)

It was a test case and I was being lazy ... the post focuses on array manipulations and creating template variables within the template. Technically, I didn't set a doctype so it could have been HTML5, although I admit it probably would not have been. The post was never meant to be a "how-to" article for the masses, just a public post between colleagues. There are probably diction and gramatical mistakes too.:)