title: Code doesn't work any more : jQuery.parseJSON requires a valid JSON string
body: <p>I'm a beginner self-made in coding. I've got a complexe theme which works well in <a href="/questions/tagged/wordpress" class="post-tag" title="show questions tagged &#39;wordpress&#39;" rel="tag">wordpress</a> since 2012. Since then some stuff didn't work anymore. Though I often use <a href="/questions/tagged/jqmigrate" class="post-tag" title="show questions tagged &#39;jqmigrate&#39;" rel="tag">jqmigrate</a> to change and correct what's needed to be changed or is deprecated. Tired of always changing stuff I've updated wordpress to adapt that theme from now. </p>
  
  <p>I've got that new warning :  </p>
  
  <blockquote>
    <p>jQuery.parseJSON requires a valid JSON string</p>
  </blockquote>
  
  <p>concerning that exact line : </p>
  
  <pre><code>hooks = jQuery.parseJSON(hooks);
  </code></pre>
  
  <p>in this part of code :</p>
  
  <pre><code>/**
   * SMOF js
   *
   * contains the core functionalities to be used
   * inside SMOF
   */
  
  jQuery.noConflict();
  
  /** Fire up jQuery - let's dance! 
   */
  jQuery(document).ready(function($){
  
          jQuery("select.seo-select").children().removeAttr('selected');
          jQuery("select.seo-select").change(function(){
                  $input = jQuery(this).parent().prev();
                  $text = jQuery(this).val();
                  if($input.val() != ''){
                      $text = ' | '+jQuery(this).val();
                  }
                  $input.val($input.val()+$text);
                  jQuery(this).children().removeAttr('selected');
          });
  
      //(un)fold options in a checkbox-group
      jQuery('.fld').change(function() {
          var $fold='.f_'+this.id;
          $($fold).slideToggle('normal', "swing");
      });
  
      //delays until AjaxUpload is finished loading
      //fixes bug in Safari and Mac Chrome
      if (typeof AjaxUpload != 'function') { 
              return ++counter &lt; 6 &amp;&amp; window.setTimeout(init, counter * 500);
      }
  
      //hides warning if js is enabled            
      $('#js-warning').hide();
  
      //Tabify Options            
      $('.group').hide();
  
      // Display last current tab 
      if ($.cookie("of_current_opt") === null) {
          $('.theme_options .group:first').fadeIn('fast');    
          $('.theme_options #of-nav li:first').addClass('current');
      } else {
  
          var hooks = $('#hooks').html();
          hooks = jQuery.parseJSON(hooks);
          if(hooks) {
                      $.each(hooks, function(key, value) {
  
                              if ($.cookie("of_current_opt") == '#of-option-'+ value) {
                                      $('.theme_options .group#of-option-' + value).fadeIn();
                                      $('.theme_options #of-nav li.' + value).addClass('current');
                              }
  
                      });
                  }
  
      }
  </code></pre>
  
  <p>I haven't found response for that problem in other posts. Except one that seemed to be relevant. I've tried to add this at the top as adviced in <a href="https://stackoverflow.com/a/24512828/8844128">https://stackoverflow.com/a/24512828/8844128</a> but it didn't change anything : </p>
  
  <pre><code>var json = $.parseJSON(jsonString || "null");
  </code></pre>
  
  <p>Maybe it's a different problem. Does anybody has an explanation and even better a valid solution I could use?</p>
  
  <ul>
  <li>jquery-migrate.js?ver=1.4.1:45</li>
  <li>jquery.js?ver=1.12.4:2</li>
  <li>wordpress : 4.9.4</li>
  <li>site : <a href="http://conexion.cluster003.ovh.net/Janay/" rel="nofollow noreferrer" title="My Site">My Site</a></li>
  </ul>
  
  <p>As asked in the comments it's used in the theme's admin option interface pages when you trigger the background image popup. Here are the admin code where <code>hook</code> appears at line 159 :  </p>
  
  <pre><code>jQuery.noConflict();
  jQuery(document).ready(function($){
  
      //hide hidden section on page load.
      jQuery('#section-body_bg, #section-body_bg_custom, #section-body_bg_properties').hide();
  
      //delays until AjaxUpload is finished loading
      //fixes bug in Safari and Mac Chrome
      if (typeof AjaxUpload != 'function') { 
          return ++counter &lt; 6 &amp;&amp; window.setTimeout(init, counter * 500);
      }
      //hides warning if js is enabled            
      $('#js-warning').hide();
  
      //Tabify Options            
      $('.group').hide();
  
      // Display last current tab 
      if ($.cookie("of_current_opt") === null) {
          $('.group:first').fadeIn(); 
          $('#of-nav li:first').addClass('current');
      } else {
  
              var hooks = &lt;?php
  $hooks = of_get_header_classes_array();
  echo json_encode($hooks);
  ?&gt;;
  
                  $.each(hooks, function(key, value) { 
  
                      if ($.cookie("of_current_opt") == '#of-option-'+ value) {
                          $('.group#of-option-' + value).fadeIn();
                          $('#of-nav li.' + value).addClass('current');
                      }
  
                  });
  
              }
  </code></pre>
  
  <p>and then at line 1190 :   </p>
  
  <pre><code>$header_class = ereg_replace("[^A-Za-z0-9]", "", strtolower($value['name']));
                      $jquery_click_hook = ereg_replace("[^A-Za-z0-9]", "", strtolower($value['name']));
                      $jquery_click_hook = "of-option-" . $jquery_click_hook;
                      $menu .= '&lt;li class="' . $header_class . '"&gt;&lt;a title="' . $value['name'] . '" href="#' . $jquery_click_hook . '"&gt;' . $value['name'] . '&lt;/a&gt;&lt;/li&gt;';
                      $output .= '&lt;div class="group" id="' . $jquery_click_hook . '"&gt;&lt;h2&gt;' . $value['name'] . '&lt;/h2&gt;' . "\n";
                      break;
  </code></pre>
  
  <p>Is there a way I can send the <a href="/questions/tagged/php" class="post-tag" title="show questions tagged &#39;php&#39;" rel="tag">php</a> file inline if it helps see how everything connects?</p>