Example #1
0
 /**
  * Handle menu uploads and downloads.
  * This is a callback for the 'admin_menu_editor_header' action.
  * 
  * @param string $action
  * @return void
  */
 function menu_editor_header($action = '')
 {
     $wp_menu_editor = $this->wp_menu_editor;
     //Handle menu download requests
     if ($action == 'download_menu') {
         $export = $this->get_exported_menu();
         if (empty($export['menu']) || empty($export['filename'])) {
             die("Exported data not found");
         }
         //Force file download
         header("Content-Description: File Transfer");
         header('Content-Disposition: attachment; filename="' . $export['filename'] . '"');
         header("Content-Type: application/force-download");
         header("Content-Transfer-Encoding: binary");
         header("Content-Length: " . strlen($export['menu']));
         /* The three lines below basically make the download non-cacheable */
         header("Cache-control: private");
         header("Pragma: private");
         header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
         echo $export['menu'];
         die;
         //Handle menu uploads
     } elseif ($action == 'upload_menu') {
         header('Content-Type: text/html');
         if (empty($_FILES['menu'])) {
             echo $wp_menu_editor->json_encode(array('error' => "No file specified"));
             die;
         }
         $file_data = $_FILES['menu'];
         if (filesize($file_data['tmp_name']) > $this->export_settings['max_file_size']) {
             $this->output_for_jquery_form($wp_menu_editor->json_encode(array('error' => "File too big")));
             die;
         }
         //Check for general upload errors.
         if ($file_data['error'] != UPLOAD_ERR_OK) {
             switch ($file_data['error']) {
                 case UPLOAD_ERR_INI_SIZE:
                     $message = sprintf('The uploaded file exceeds the upload_max_filesize directive in php.ini. Limit: %s', strval(ini_get('upload_max_filesize')));
                     break;
                 case UPLOAD_ERR_FORM_SIZE:
                     $message = "The uploaded file exceeds the internal file size limit. Please contact the developer.";
                     break;
                 case UPLOAD_ERR_PARTIAL:
                     $message = "The file was only partially uploaded";
                     break;
                 case UPLOAD_ERR_NO_FILE:
                     $message = "No file was uploaded";
                     break;
                 case UPLOAD_ERR_NO_TMP_DIR:
                     $message = "Missing a temporary folder";
                     break;
                 case UPLOAD_ERR_CANT_WRITE:
                     $message = "Failed to write file to disk";
                     break;
                 case UPLOAD_ERR_EXTENSION:
                     $message = "File upload stopped by a PHP extension";
                     break;
                 default:
                     $message = 'Unknown upload error #' . $file_data['error'];
                     break;
             }
             $this->output_for_jquery_form($wp_menu_editor->json_encode(array('error' => $message)));
             die;
         }
         $file_contents = file_get_contents($file_data['tmp_name']);
         //Check if this file could plausibly contain an exported menu
         if (strpos($file_contents, $this->export_settings['old_format_string']) !== false) {
             //This is an exported menu in the old format.
             $data = $wp_menu_editor->json_decode($file_contents, true);
             if (!(isset($data['menu']) && is_array($data['menu']))) {
                 $this->output_for_jquery_form($wp_menu_editor->json_encode(array('error' => "Unknown or corrupted file format")));
                 die;
             }
             try {
                 $menu = ameMenu::load_array($data['menu'], false, true);
             } catch (InvalidMenuException $ex) {
                 $this->output_for_jquery_form($wp_menu_editor->json_encode(array('error' => $ex->getMessage())));
                 die;
             }
         } else {
             if (strpos($file_contents, ameMenu::format_name) !== false) {
                 //This is an export file in the new format.
                 try {
                     $menu = ameMenu::load_json($file_contents, false, true);
                 } catch (InvalidMenuException $ex) {
                     $this->output_for_jquery_form($wp_menu_editor->json_encode(array('error' => $ex->getMessage())));
                     die;
                 }
             } else {
                 //This is an unknown file.
                 $this->output_for_jquery_form($wp_menu_editor->json_encode(array('error' => "Unknown file format")));
                 die;
             }
         }
         //Merge the imported menu with the current one.
         $menu['tree'] = $wp_menu_editor->menu_merge($menu['tree']);
         //Everything looks okay, send back the menu data
         $this->output_for_jquery_form(ameMenu::to_json($menu));
         die;
     }
 }
 private function display_editor_ui()
 {
     //Prepare a bunch of parameters for the editor.
     $editor_data = array('message' => isset($this->get['message']) ? intval($this->get['message']) : null, 'images_url' => plugins_url('images', $this->plugin_file), 'hide_advanced_settings' => $this->options['hide_advanced_settings'], 'show_extra_icons' => $this->options['show_extra_icons'], 'settings_page_url' => $this->get_settings_page_url(), 'show_deprecated_hide_button' => $this->options['show_deprecated_hide_button'], 'dashicons_available' => wp_style_is('dashicons', 'done'));
     //Build a tree struct. for the default menu
     $default_tree = ameMenu::wp2tree($this->default_wp_menu, $this->default_wp_submenu);
     $default_menu = ameMenu::load_array($default_tree);
     //Is there a custom menu?
     if (!empty($this->merged_custom_menu)) {
         $custom_menu = $this->merged_custom_menu;
     } else {
         //Start out with the default menu if there is no user-created one
         $custom_menu = $default_menu;
     }
     //The editor doesn't use the color CSS. Including it would just make the page bigger and waste bandwidth.
     unset($custom_menu['color_css']);
     unset($custom_menu['color_css_modified']);
     //Encode both menus as JSON
     $editor_data['default_menu_js'] = ameMenu::to_json($default_menu);
     $editor_data['custom_menu_js'] = ameMenu::to_json($custom_menu);
     //Create a list of all known capabilities and roles. Used for the drop-down list on the access field.
     $all_capabilities = ameRoleUtils::get_all_capabilities();
     //"level_X" capabilities are deprecated so we don't want people using them.
     //This would look better with array_filter() and an anonymous function as a callback.
     for ($level = 0; $level <= 10; $level++) {
         $cap = 'level_' . $level;
         if (isset($all_capabilities[$cap])) {
             unset($all_capabilities[$cap]);
         }
     }
     $all_capabilities = array_keys($all_capabilities);
     natcasesort($all_capabilities);
     //Multi-site installs also get the virtual "Super Admin" cap, but only the Super Admin sees it.
     if (is_multisite() && !isset($all_capabilities['super_admin']) && is_super_admin()) {
         array_unshift($all_capabilities, 'super_admin');
     }
     $editor_data['all_capabilities'] = $all_capabilities;
     //Create a list of all roles, too.
     $all_roles = ameRoleUtils::get_role_names();
     asort($all_roles);
     $editor_data['all_roles'] = $all_roles;
     //Include hint visibility settings
     $editor_data['show_hints'] = $this->get_hint_visibility();
     require dirname(__FILE__) . '/editor-page.php';
 }
            }
        } elseif ($second[$key] !== $value) {
            $difference[$key] = $value;
        }
    }
    return $difference;
}
add_action('admin_init', function () {
    global $wp_menu_editor;
    $menu = $wp_menu_editor->load_custom_menu();
    if (empty($menu)) {
        return;
    }
    $compressed = ameMenu::compress($menu);
    $loaded = ameMenu::load_json(ameMenu::to_json($compressed));
    $expected = ameMenu::load_json(ameMenu::to_json($menu));
    $diff1 = ame_test_array_diff_assoc_recursive($expected, $loaded);
    $diff2 = ame_test_array_diff_assoc_recursive($loaded, $expected);
    if (!empty($diff1) || !empty($diff2)) {
        header('X-AME-Test-Failed: compression', true, 500);
        echo "<h1>Test failed: Compression causes data loss!</h1>";
        echo "<p>Loading compressed and uncompressed versions of the same menu configuration produced different results.</p>";
        echo '<p>Keys that are missing or different in the compressed configuration (expected vs compressed):</p>';
        echo '<pre>';
        echo htmlentities(print_r($diff1, true));
        echo '</pre>';
        echo '<h2>Reverse diff (compressed vs expected):</h2>';
        echo '<pre>';
        echo htmlentities(print_r($diff2, true));
        echo '</pre>';
        exit;
Example #4
0
 /**
  * Handle menu uploads and downloads.
  * This is a callback for the 'admin_menu_editor_header' action.
  * 
  * @param string $action
  * @return void
  */
 function menu_editor_header($action = '')
 {
     $wp_menu_editor = $this->wp_menu_editor;
     //Handle menu download requests
     if ($action == 'download_menu') {
         $export = $this->get_exported_menu();
         if (empty($export['menu']) || empty($export['filename'])) {
             die("Exported data not found");
         }
         //Force file download
         header("Content-Description: File Transfer");
         header('Content-Disposition: attachment; filename="' . $export['filename'] . '"');
         header("Content-Type: application/force-download");
         header("Content-Transfer-Encoding: binary");
         header("Content-Length: " . strlen($export['menu']));
         /* The three lines below basically make the download non-cacheable */
         header("Cache-control: private");
         header("Pragma: private");
         header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
         echo $export['menu'];
         die;
         //Handle menu uploads
     } elseif ($action == 'upload_menu') {
         header('Content-Type: text/html');
         if (empty($_FILES['menu'])) {
             echo $wp_menu_editor->json_encode(array('error' => "No file specified"));
             die;
         }
         $file_data = $_FILES['menu'];
         if (filesize($file_data['tmp_name']) > $this->export_settings['max_file_size']) {
             echo '<textarea cols="50" rows="5">', $wp_menu_editor->json_encode(array('error' => "File too big")), '</textarea>';
             die;
         }
         $file_contents = file_get_contents($file_data['tmp_name']);
         //Check if this file could plausibly contain an exported menu
         if (strpos($file_contents, $this->export_settings['old_format_string']) !== false) {
             //This is an exported menu in the old format.
             $data = $wp_menu_editor->json_decode($file_contents, true);
             if (!(isset($data['menu']) && is_array($data['menu']))) {
                 echo '<textarea cols="50" rows="5">', $wp_menu_editor->json_encode(array('error' => "Unknown or corrupted file format")), '</textarea>';
                 die;
             }
             try {
                 $menu = ameMenu::load_array($data['menu']);
             } catch (InvalidMenuException $ex) {
                 echo '<textarea cols="50" rows="5">', $wp_menu_editor->json_encode(array('error' => $ex->getMessage())), '</textarea>';
                 die;
             }
         } else {
             if (strpos($file_contents, ameMenu::format_name) !== false) {
                 //This is an export file in the new format.
                 try {
                     $menu = ameMenu::load_json($file_contents);
                 } catch (InvalidMenuException $ex) {
                     echo '<textarea cols="50" rows="5">', $wp_menu_editor->json_encode(array('error' => $ex->getMessage())), '</textarea>';
                     die;
                 }
             } else {
                 //This is an unknown file.
                 echo '<textarea cols="50" rows="5">', $wp_menu_editor->json_encode(array('error' => "Unknown file format")), '</textarea>';
                 die;
             }
         }
         //Merge the imported menu with the current one.
         $menu['tree'] = $wp_menu_editor->menu_merge($menu['tree']);
         //Everything looks okay, send back the menu data
         die('<textarea>' . ameMenu::to_json($menu) . '</textarea>');
     }
 }
 /**
  * Import admin menu configuration from a JSON file.
  *
  * ## OPTIONS
  *
  * <file>
  * : Import file name.
  *
  * @param array $args
  */
 public function import($args)
 {
     $fileName = $args[0];
     if (!is_readable($fileName)) {
         WP_CLI::error('The file doesn\'t exist or isn\'t readable.');
         return;
     }
     $json = file_get_contents($fileName);
     try {
         $loadedMenu = ameMenu::load_json($json);
     } catch (Exception $ex) {
         WP_CLI::error($ex->getMessage());
         return;
     }
     $menuEditor = $this->getMenuEditor();
     $menuEditor->set_custom_menu($loadedMenu);
     WP_CLI::success('Import completed.');
 }
Example #6
0
 private function display_editor_ui()
 {
     //Prepare a bunch of parameters for the editor.
     $editor_data = array('message' => isset($this->get['message']) ? intval($this->get['message']) : null, 'images_url' => $this->plugin_dir_url . '/images', 'hide_advanced_settings' => $this->options['hide_advanced_settings']);
     //Build a tree struct. for the default menu
     $default_tree = ameMenu::wp2tree($this->default_wp_menu, $this->default_wp_submenu);
     $default_menu = ameMenu::load_array($default_tree);
     //Is there a custom menu?
     if (!empty($this->merged_custom_menu)) {
         $custom_menu = $this->merged_custom_menu;
     } else {
         //Start out with the default menu if there is no user-created one
         $custom_menu = $default_menu;
     }
     //Encode both menus as JSON
     $editor_data['default_menu_js'] = ameMenu::to_json($default_menu);
     $editor_data['custom_menu_js'] = ameMenu::to_json($custom_menu);
     //Create a list of all known capabilities and roles. Used for the drop-down list on the access field.
     $all_capabilities = ameRoleUtils::get_all_capabilities();
     //"level_X" capabilities are deprecated so we don't want people using them.
     //This would look better with array_filter() and an anonymous function as a callback.
     for ($level = 0; $level <= 10; $level++) {
         $cap = 'level_' . $level;
         if (isset($all_capabilities[$cap])) {
             unset($all_capabilities[$cap]);
         }
     }
     $all_capabilities = array_keys($all_capabilities);
     natcasesort($all_capabilities);
     $editor_data['all_capabilities'] = $all_capabilities;
     //Create a list of all roles, too.
     $all_roles = ameRoleUtils::get_role_names();
     //Multi-site installs also get the virtual "Super Admin" role
     if (is_multisite() && !isset($all_roles['super_admin'])) {
         $all_roles['super_admin'] = 'Super Admin';
     }
     asort($all_roles);
     $editor_data['all_roles'] = $all_roles;
     //Include hint visibility settings
     $editor_data['show_hints'] = $this->get_hint_visibility();
     require dirname(__FILE__) . '/editor-page.php';
 }