Inserting different variables in JavaScript

13 posts by 4 authors in: Forums > CMS Builder
Last Post: February 24, 2014   (RSS)

By gkornbluth - January 13, 2014

OK, I’m stumped again.

I’m trying to adapt a menu generator called anylink menu from Dynamic Drive to work with CMSB, and I can’t get the $output variables to work correctly.

I’ve set up a multi-record editor called navigation_menu_entries with fields for ‘entry’ (the nav menu main category), a check box that indicates whether to use sub menus or not, and 6 Sub Menu URL and Sub Menu Link text field combinations.

The required code for the menu generator to work is pretty simple ( a 3 entry example):

var about={divclass:'anylinkmenu', inlinestyle:'width:150px; background:#DAD2D0', linktarget:''}
about.items=[
    ["Resume", "http://www.artculturegroup.com/resume.php"],
    ["Biography", "http://www.artculturegroup.com/biography.php"] //no comma following last entry!
]

var studio_art={divclass:'anylinkmenu', inlinestyle:'width:150px background:#DAD2D0', linktarget:''}
studio_art.items=[
    ["Clay", "http://www.artculturegroup.com/studio-art.php?discipline=clay"],
    ["Glass", "http://www.artculturegroup.com/studio-art.php?discipline=glass"],
    ["Photography", "http://www.artculturegroup.com/studio-art.php?discipline=photograpy"],
    ["Mixed Media", "http://www.artculturegroup.com/studio-art.php?discipline=mixed-media"] //no comma following last entry!
]

// A menu entry with no sub menus (divclass and items empty)
var public_art={divclass:'', inlinestyle:'width:150px background:#DAD2D0', linktarget:''}
public_art.items=[
]

So far, my code to generate the above, with up to six submenu entries, is:

    <?php $output = ''; ?>
    <?php foreach ($navigation_menu_entriesRecords as $record): ?>
<?php if($record['use_submenu'] == '1'):?> <?php $divclass = "anylinkmenu" ?><?php else:?><?php $divclass = "" ?><?php endif?>

<?php $entry = strtolower($record['entry']) ?>

<?php $sub1 = "" ?><?php $sub2 = "" ?><?php $sub3 = "" ?><?php $sub4 = "" ?><?php $sub5 = "" ?><?php $sub6 = "" ?>

<?php if($record['submenu_link_1_url']):?>
<?php $sub1 = "[" . "\"" . $record['submenu_link_1_text']. "\"" ."," . "\"" . $record['submenu_link_1_url'] ."\"" ." ]"  . ",";?>
<?php endif?>

<?php if($record['submenu_link_2_url']):?>
<?php $sub2 = "[" . "\"" . $record['submenu_link_2_text']. "\"" ."," . "\"" . $record['submenu_link_2_url'] ."\"" ." ]"  . ",";?>
<?php endif?>

<?php if($record['submenu_link_3_url']):?>
<?php $sub1 = "" ?><?php $sub3 = "[" . "\"" . $record['submenu_link_3_text']. "\"" ."," . "\"" . $record['submenu_link_3_url'] ."\"" ." ]"  . ",";?>
<?php endif?>

<?php if($record['submenu_link_4_url']):?>
<?php $sub4 = "[" . "\"" . $record['submenu_link_4_text']. "\"" ."," . "\"" . $record['submenu_link_4_url'] ."\"" ." ]"  . ",";?>
<?php endif?>

<?php if($record['submenu_link_5_url']):?>
<?php $sub5 = "[" . "\"" . $record['submenu_link_5_text']. "\"" ."," . "\"" . $record['submenu_link_5_url'] ."\"" ." ]"  . ",";?>
<?php endif?>

<?php if($record['submenu_link_6_url']):?>
<?php $sub6 = "[" . "\"" . $record['submenu_link_6_text']. "\"" ."," . "\"" . $record['submenu_link_6_url'] ."\"" ." ]"  . ",";?>
<?php endif?>

 <?php if($record['submenu_link_1_url']):?>
 
 <?php $output  .= "$sub1" . "$sub2" . "$sub3" . "$sub4" . "$sub5" . "$sub6" ;

    $output= rtrim($output,","); // remove trailing comma

?>
<?php endif?>

var <?= $entry ?>={divclass:'<?= $divclass ?>', inlinestyle:'width:150px; background:#DAD2D0', linktarget:''}
<?= $entry ?>.items=[
    <?= $output?>

]
<?php endforeach ?>
]  

The result however, cumulatively puts the same $output into each var (once a $subn variable is defined it’s used in all subsequent vars) and I don’t know how to remedy this situation:

var about={divclass:'anylinkmenu', inlinestyle:'width:150px; background:#DAD2D0', linktarget:''} about.items=[ ["Resume","http://www.artculturegroup.com/resume.com" ],["Biography","http://www.artculturegroup.com/biography.com" ] ]

var eco_art={divclass:'', inlinestyle:'width:150px; background:#DAD2D0', linktarget:''} eco_art.items=[ ["Resume","http://www.artculturegroup.com/resume.com" ],["Biography","http://www.artculturegroup.com/biography.com" ] ]

var public_art={divclass:'', inlinestyle:'width:150px; background:#DAD2D0', linktarget:''} public_art.items=[ ["Resume","http://www.artculturegroup.com/resume.com" ],["Biography","http://www.artculturegroup.com/biography.com" ] ]

var studio_art={divclass:'', inlinestyle:'width:150px; background:#DAD2D0', linktarget:''} studio_art.items=[ ["Resume","http://www.artculturegroup.com/resume.com" ],["Biography","http://www.artculturegroup.com/biography.com" ] ]

var consulting={divclass:'', inlinestyle:'width:150px; background:#DAD2D0', linktarget:''} consulting.items=[ ["Resume","http://www.artculturegroup.com/resume.com" ],["Biography","http://www.artculturegroup.com/biography.com" ] ]

var contact={divclass:'', inlinestyle:'width:150px; background:#DAD2D0', linktarget:''} contact.items=[ ["Resume","http://www.artculturegroup.com/resume.com" ],["Biography","http://www.artculturegroup.com/biography.com" ] ] ]

Thanks for any assistance from the many coding gurus,


Jerry Kornbluth

The first CMS Builder reference book is now available on-line!







Take advantage of a free 3 month trial subscription, only for CMSB users, at: http://www.thecmsbcookbook.com/trial.php

By ross - January 20, 2014

Hi Jerry

Thanks for posting!

Could you attach your example files along with the schemas for all the sections in CMS Builder required? I'd like to have a quick play around with the code locally to see what I am able to come up with.

Thanks!

-----------------------------------------------------------
Cheers,
Ross Fairbairn - Consulting
consulting@interactivetools.com

Hire me! Save time by getting our experts to help with your project.
Template changes, advanced features, full integration, whatever you
need. Whether you need one hour or fifty, get it done fast with
Priority Consulting: http://www.interactivetools.com/consulting/

By gkornbluth - January 20, 2014 - edited: January 20, 2014

Hi Ross,

Here are the files that I think you'll need.

There are entries in the About and the Studio Art records and as I mentioned above, only the entries from the about record gets passed to the $output in the menucontents file.

Thanks for taking an interest in this.

Jerry Kornbluth

The first CMS Builder reference book is now available on-line!







Take advantage of a free 3 month trial subscription, only for CMSB users, at: http://www.thecmsbcookbook.com/trial.php

By gkornbluth - January 20, 2014 - edited: January 20, 2014

Hi Ross,

It didn't change much but I found and fixed one small error in the js.php file (the new one is uploaded)

Jerry

The first CMS Builder reference book is now available on-line!







Take advantage of a free 3 month trial subscription, only for CMSB users, at: http://www.thecmsbcookbook.com/trial.php

By gkornbluth - January 27, 2014 - edited: January 27, 2014

Chris,

Thank you for the suggestions and the work you put into this.

Tomorrow, after I get the basics working, I'll address the variable issue.

Best,

Jerry Kornbluth

The first CMS Builder reference book is now available on-line!







Take advantage of a free 3 month trial subscription, only for CMSB users, at: http://www.thecmsbcookbook.com/trial.php

By gkornbluth - January 28, 2014

Hi Chris,

Thank you, that code worked perfectly.

Are you saying that  a variable with the name 'entry' is a problem, or that the idea of using a variable at all presents a security issue.

And,at the risk of asking too much, how would you modify the code you offered to work with a loop that returned values for each text and url entry in each record in the navigation menu entry table?

Best,

Jerry

The first CMS Builder reference book is now available on-line!







Take advantage of a free 3 month trial subscription, only for CMSB users, at: http://www.thecmsbcookbook.com/trial.php

By Chris - January 29, 2014

Hi Jerry,

These are some pretty advanced security considerations, so if you occasionally skip doing an htmlencode() on a field, this isn't relevant at all (because the same attacks could be done on any non-htmlencoded fields.)

Consider if you had a record with the "entry" field set to the following:

foo = "bar"; alert("XSS Attack!"); foo

The resulting Javascript code you'd be generating would be:

var foo = "bar"; alert("XSS Attack!"); foo = {divclass:...

The security concern is that, if someone is able to gain access to create or modify your navigation_menu records, they can set the "entry" field to some arbitrary Javascript and attack your users by making requests on their behalf (for example, by using AJAX to submit to an Edit My Profile form on your site, changing their email address to an email address the attacker controls, then sending a Reset Password request.) It's generally a good idea to guard against all potential attacks, and to treat all data as potentially compromised (even if it comes from your database which only you (hopefully) control!)

The guard against this problem is relatively simple: only output potentially compromised data into strings (not as variable names), so instead of composing a bunch of variable names, just build up an object instead:

var about = ...;
var eco_art = ...;
var public_art = ...;

vs.

var menus = {};
menus['about'] = ...;
menus['eco_art'] = ...;
menus['public_art'] = ...;

Assuming you json_encode() those strings, there would be no way for bad data to break out of its intended use as an object key.

I didn't look into how your variables are used (about, eco_art, public_art, etc.), so I'm not sure how much else in your code would need to be changed to work with an object instead of a bunch of variables.

Does that answer your question?

All the best,
Chris

By gkornbluth - January 29, 2014

Hi Chris,

I'm sure it all makes sense but it's a bit over my head.

The variables are used to define the navigation menu entries.

Each entry may or may not have drop down menus associated with them.

They variable names come from the 'entry' field in the navigation_menu_entries table. One record for each navigation menu main category.

I was hoping to keep the menu dynamic so that when a record was added it created a new nav menu main category.

If a drop down is required for the new entry, then the use_submenu field in the record is set to 1 (yes) and the link information for each of the drop down sub menus is added to that record's submenu_link_text and submenu_link_url fields.

Hope that makes sense.

Jerry Kornbluth

The first CMS Builder reference book is now available on-line!







Take advantage of a free 3 month trial subscription, only for CMSB users, at: http://www.thecmsbcookbook.com/trial.php

By gregThomas - February 4, 2014

Hi Jerry,

I think something like this might work:

foreach ($navigation_menu_entriesRecords as $record) {
  
  // determine div class
  $divClass = "";
  if ($record['use_submenu'] == '1') { $divClass = "anylinkmenu"; }
  
  // determine variable name
  $entry = strtolower($record['entry']);
  
  // determine item list    
  $items = array();
  if($record['use_submenu']']){
    if ($record['submenu_link_1_url']) { $items[] = array($record['submenu_link_1_text'], $record['submenu_link_1_url']); }
    if ($record['submenu_link_2_url']) { $items[] = array($record['submenu_link_2_text'], $record['submenu_link_2_url']); }
    if ($record['submenu_link_3_url']) { $items[] = array($record['submenu_link_3_text'], $record['submenu_link_3_url']); }
    if ($record['submenu_link_4_url']) { $items[] = array($record['submenu_link_4_text'], $record['submenu_link_4_url']); }
    if ($record['submenu_link_5_url']) { $items[] = array($record['submenu_link_5_text'], $record['submenu_link_5_url']); }
    if ($record['submenu_link_6_url']) { $items[] = array($record['submenu_link_6_text'], $record['submenu_link_6_url']); }
  }
  
  // output javascript
  echo "var $entry = {divclass:'$divClass', inlinestyle:'width:150px; background:#DAD2D0', linktarget:''};\n";
  echo "$entry.items = " . json_encode($items) . ";\n";
}

So I've added an if statement around the code that creates the sub menu links. If the use_submenu check box is ticked, then the code will run that creates an array of sub menu items. Otherwise an empty json object will be created.

Let me know if this doesn't work.

Thanks!

Greg

Greg Thomas







PHP Programmer - interactivetools.com