public function __construct($menu_term_slug)
 {
     parent::__construct();
     $menu = wp_get_nav_menu_object($menu_term_slug);
     if (!empty($menu)) {
         $this->menu = $menu;
         $nav_menu_items = wp_get_nav_menu_items($this->menu->term_id);
         cfd_tmp_dbg('nav_menu_items_raw.txt', $nav_menu_items, 'print');
         foreach ($nav_menu_items as $item) {
             $menu_item = wp_setup_nav_menu_item($item);
             $menu_item->metadata = get_metadata('post', $item->ID);
             foreach ($menu_item->metadata as $key => &$value) {
                 $value[0] = maybe_unserialize($value[0]);
             }
             if ($menu_item->type == 'post_type') {
                 $menu_item->parent = get_post($menu_item->metadata['_menu_item_object_id'][0]);
             } elseif ($menu_item->type == 'taxonomy' && (!property_exists($menu, 'object') || $menu->object != 'custom')) {
                 $menu_item->term = get_term($menu_item->metadata['_menu_item_object_id'][0], $menu_item->metadata['_menu_item_object'][0]);
             }
             $this->items[] = $menu_item;
         }
     } else {
         throw new Exception(__('Invalid menu id', 'cf-deploy') . ': ' . esc_attr($menu_term_slug));
     }
 }
 public function preflight_batch()
 {
     $batch_items = $this->batch->get_deploy_data(false, true);
     if (empty($batch_items)) {
         return false;
     }
     // give plugins a chance to attach extra data for comparison
     $extras = $this->get_preflight_extras();
     if (!empty($extras)) {
         $batch_items['extras'] = $extras;
         unset($extras);
     }
     cfd_tmp_dbg('preflight_send_data.txt', $batch_items);
     $params = array('server' => $this->options['remote_server'][0]['address'], 'auth_key' => $this->options['remote_server'][0]['key'], 'method' => 'preflight', 'args' => array('batch_items' => $batch_items));
     $ret = $this->send($params);
     if (!$ret->success) {
         echo '<div class="error batch-error message"><p><b>' . __('Fatal Error: Batch Preflight Failed', 'cf-deploy') . '</b></p></div>';
         echo $ret->message;
         $this->add_admin_message('__error__', $ret->message);
         return false;
     } else {
         $this->batch->parse_preflight_data($ret->message);
         return true;
     }
 }
 /**
  * Return display data for batch display screen
  *
  * @param string $type 
  * @return array
  */
 public function get_comparison_data($type)
 {
     $ret = false;
     switch ($type) {
         case 'post_types':
             if (count($this->c_data['post_types'])) {
                 foreach ($this->c_data['post_types'] as $post_type => $post_objects) {
                     $ret[$post_type] = array();
                     if (count($post_objects) && count($this->s_data['post_types'][$post_type])) {
                         foreach ($post_objects as $id => $post) {
                             if (!empty($this->s_data['post_types'][$post_type][$id])) {
                                 $post->status = $this->s_data['post_types'][$post_type][$id];
                                 $post->modified = null;
                                 $post->errors = null;
                                 $post->profile();
                                 if (empty($post->status['remote_status'])) {
                                     $post->modified[] = __('new', 'cf-deploy');
                                 } elseif (!empty($post->status['remote_status'])) {
                                     // modified time
                                     if (strtotime($post->post_modified) > strtotime($post->status['remote_status']['post_modified'])) {
                                         $post->modified[] = __('local newer', 'cf-deploy');
                                     } elseif (strtotime($post->post_modified) < strtotime($post->status['remote_status']['post_modified'])) {
                                         $post->modified[] = __('remote newer', 'cf-deploy');
                                     }
                                     // meta profile
                                     if (md5(serialize($post->profile['meta'])) != md5(serialize($post->status['remote_status']['profile']['meta']))) {
                                         $post->modified[] = __('meta', 'cf-deploy');
                                     }
                                     // attachments: we need to prune attachments a bit to get an accurate comparison. prune: post_parent, post_name
                                     $atts = array('a' => $post->profile['attachments'], 'b' => $post->status['remote_status']['profile']['attachments']);
                                     foreach ($atts as &$attachments) {
                                         if (!empty($attachments)) {
                                             foreach ($attachments as &$attachment) {
                                                 unset($attachment['post']['post_parent'], $attachment['post']['post_name']);
                                             }
                                         }
                                     }
                                     if (md5(serialize($atts['a'])) != md5(serialize($atts['b']))) {
                                         $post->modified[] = __('attachments', 'cf-deploy');
                                     }
                                     unset($atts);
                                     // taxonomies
                                     if (md5(serialize($post->profile['taxonomies'])) != md5(serialize($post->status['remote_status']['profile']['taxonomies']))) {
                                         $post->modified[] = __('taxonomies', 'cf-deploy');
                                     }
                                     // attachment content
                                     if ($post_type == 'attachment') {
                                         foreach ($post->profile['post'] as $key => $value) {
                                             if ($post->status['remote_status']['profile']['post'][$key] !== $value) {
                                                 $post->modified[] = 'local and remote differ';
                                                 break;
                                             }
                                         }
                                     }
                                 }
                                 if (!empty($post->modified) || $post->force_in_batch) {
                                     if (!empty($this->data['post_types'][$post_type]) && in_array($post->ID, $this->data['post_types'][$post_type])) {
                                         $post->selected = true;
                                     }
                                     $ret[$post_type][$id] = $post;
                                 }
                             }
                         }
                         if (!empty($this->s_data['post_types'][$post_type]['__error__'])) {
                             $ret[$post_type]['__error__'] = $this->s_data['post_types'][$post_type]['__error__'];
                         }
                     }
                 }
             }
             break;
         case 'users':
             if (count($this->c_data[$type])) {
                 cfd_tmp_dbg('c_data_users.txt', $this->c_data[$type], 'print');
                 foreach ($this->c_data[$type] as $id => $object) {
                     if (!empty($this->s_data[$type][$id])) {
                         $object->status = $this->s_data[$type][$id];
                         cfd_tmp_dbg('c_data_users_status.txt', $object->status, 'print');
                         $_u = new cfd_user(array('user_id' => $object->ID));
                         $local_profile = serialize($_u->profile());
                         cfd_tmp_dbg('local_user_profile.txt', $local_profile, 'print');
                         $object->modified = 'no';
                         if (empty($object->status['remote_status'])) {
                             $object->modified = 'new';
                         } else {
                             $registered_difference = $object->user_registered != $object->status['remote_status']['user_registered'];
                             $profile_difference = $local_profile != $object->status['remote_status']['profile'];
                             $in_batch = !empty($this->data['users']) && in_array($object->ID, $this->data['users']);
                             if (empty($object->status['remote_status']) || $registered_difference || $profile_difference || $in_batch) {
                                 $object->modified = 'profile';
                             }
                         }
                         if ($object->modified != 'no') {
                             if (!empty($this->data[$type]) && in_array($object->ID, $this->data[$type])) {
                                 $object->selected = true;
                             }
                             $ret[$id] = $object;
                         }
                     }
                 }
                 if (!empty($this->s_data[$type]['__error__'])) {
                     $ret['__error__'] = $this->s_data[$type]['__error__'];
                 }
             }
             break;
         case 'taxonomies':
             if (count($this->c_data[$type])) {
                 foreach ($this->c_data[$type] as $tax_type => $objects) {
                     if (count($objects)) {
                         foreach ($objects as $id => $object) {
                             $object->status = $this->s_data[$type][$tax_type][$id];
                             $object->modified = null;
                             if (empty($object->status['remote_status'])) {
                                 $object->modified = 'new';
                             } elseif (!empty($object->status['remote_status'])) {
                                 if ($object->name != $object->status['remote_status']['name']) {
                                     $object->modified[] = 'name';
                                 }
                                 if ($object->description != $object->status['remote_status']['description']) {
                                     $object->modified[] = 'description';
                                 }
                                 if ($object->parent != $object->status['remote_status']['parent']) {
                                     $object->modified[] = 'parent';
                                 }
                             }
                             $in_batch = !empty($this->data[$type]) && in_array($object->term_id, $this->data[$type][$tax_type]);
                             if (!empty($object->modified) || $in_batch) {
                                 if (!empty($this->data[$type][$tax_type]) && in_array($object->term_id, $this->data[$type][$tax_type])) {
                                     $object->selected = true;
                                 }
                                 $ret[$tax_type][$id] = $object;
                             }
                         }
                         if (!empty($this->s_data[$type][$tax_type]['__error__'])) {
                             $ret[$tax_type]['__error__'] = $this->s_data[$type][$tax_type]['__error__'];
                         }
                     }
                 }
             }
             break;
         case 'bookmarks':
             if (count($this->c_data[$type])) {
                 foreach ($this->c_data[$type] as $id => $object) {
                     $object->status = $this->s_data[$type][$id];
                     $status_difference = !empty($object->status['remote_status']['link_hash']) && $object->status['link_hash'] != $object->status['remote_status']['link_hash'];
                     $in_batch = !empty($this->data[$type]) && in_array($object->link_id, $this->data[$type]);
                     if (empty($object->status['remote_status']) || $status_difference || $in_batch) {
                         if (!empty($this->data[$type]) && in_array($object->link_id, $this->data[$type])) {
                             $object->selected = true;
                         }
                         $ret[$id] = $object;
                     }
                 }
                 if (!empty($this->s_data[$type]['__error__'])) {
                     $ret['__error__'] = $this->s_data[$type]['__error__'];
                 }
             }
             break;
         case 'menus':
             if (count($this->c_data[$type])) {
                 foreach ($this->c_data[$type] as $id => $object) {
                     $object->status = $this->s_data[$type][$id];
                     if (isset($object->status['remote_status'])) {
                         $modified_difference = $object->last_modified() != $object->status['remote_status']['last_modified'];
                     } else {
                         $modified_difference = true;
                     }
                     $in_batch = !empty($this->data[$type]) && in_array($object->id(), $this->data[$type]);
                     if (empty($object->status['remote_status']) || $modified_difference || $in_batch) {
                         if (!empty($this->data[$type]) && in_array($object->id(), $this->data[$type])) {
                             $object->selected = true;
                         }
                         $ret[$id] = $object;
                     }
                 }
                 if (!empty($this->s_data[$type]['__error__'])) {
                     $ret['__error__'] = $this->s_data[$type]['__error__'];
                 }
             }
             break;
         default:
             throw new Exception(__('Unknown type requested: ', 'cf-deploy') . $type);
             break;
     }
     return $ret;
 }
 /**
  * Import a single user
  * 
  * @param array $user
  * @return array
  */
 protected function import_user($user)
 {
     $local_user = get_user_by('login', $user['data']['user_login']);
     $local_user_object = new WP_User($local_user->ID);
     $update = !empty($local_user) ? true : false;
     if (!function_exists('wp_insert_user')) {
         include_once ABSPATH . 'wp-includes/registration.php';
     }
     // args used by wp_insert_user & wp_update_user
     // makes for an easy merge and a reminder of just what is handled at that time
     $insert_user_args = array('user_login' => null, 'user_nicename' => null, 'user_url' => null, 'user_email' => null, 'display_name' => null, 'nickname' => null, 'first_name' => null, 'last_name' => null, 'description' => null, 'rich_editing' => null, 'user_registered' => null, 'role' => null, 'use_ssl' => 0, 'admin_color' => null, 'comment_shortcuts' => null);
     foreach (_wp_get_user_contactmethods() as $contact_method => $contact_method_name) {
         $insert_user_args[$contact_method] = null;
     }
     cfd_tmp_dbg('importing_user.txt', $user, 'print');
     foreach ($insert_user_args as $key => &$arg) {
         if ($key == 'role') {
             $arg = $user['roles'][0];
         } else {
             if (!empty($user['data'][$key])) {
                 $arg = $user['data'][$key];
             }
         }
     }
     cfd_tmp_dbg('importing_user_args.txt', $insert_user_args, 'print');
     if ($update) {
         $local_userdata = get_object_vars(get_userdata($local_user->ID));
         $insert_user_args = array_merge($local_userdata, $insert_user_args);
         unset($insert_user_args['user_pass']);
         $user_id = wp_update_user($insert_user_args);
     } else {
         if (email_exists($user['data']['user_email'])) {
             $this->add_import_message('users', '__error__', sprintf(__('Email address "%s" already exists for another user', 'cf-deploy'), $user['data']['user_email']));
             return false;
         }
         // set generic password for new user
         $insert_user_args['user_password'] = time();
         $user_id = wp_insert_user($insert_user_args);
     }
     if (empty($user_id) || is_wp_error($user_id)) {
         $errstring = sprintf(__('Import failed for user "%s".', 'cf-deploy'), $user['data']['user_nicename']);
         if (is_wp_error($user_id)) {
             $errstring .= ' ' . __('Error:', 'cf-deploy') . ' ' . $user_id->get_error_message();
         }
         $this->add_import_message('users', '__error__', $errstring);
         $ret = false;
     } else {
         // Set/Update Capabilities & Roles
         $u = new WP_User($user_id);
         // set roles, remove all existing and replace with what is being brought in
         foreach ($u->roles as $role) {
             $u->remove_role($role);
         }
         foreach ($user['roles'] as $role) {
             $u->add_role($role);
         }
         // set caps, remove all existing caps before setting them anew
         $u->remove_all_caps();
         foreach ($user['caps'] as $cap => $value) {
             $u->add_cap($cap, (bool) $value);
         }
         $this->add_import_message('users', '__notice__', sprintf(__('User "%s" successfully imported.', 'cf-deploy'), $user['data']['user_login']));
         $ret = true;
     }
     $item_change['users'][$user['data']['user_login']] = 'new';
     if (!empty($local_user)) {
         $log_users = array($local_user_object);
         array_walk_recursive($log_users, array($this, 'object_to_array'));
         $item_change['users'][$user['data']['user_login']] = current($log_users);
     }
     $this->log_item_change($item_change);
     return $ret;
 }
 /**
  * Monster validation routine prior to accepting any data
  *
  * @param array $args 
  * @return mixed
  */
 public function parse_request($params)
 {
     cfd_tmp_dbg('cf-data-received.txt', $params, 'print');
     list($blog_id, $username, $auth_key, $method, $args, $sekret, $val_hash) = $params;
     # sekret key validation
     if ($sekret != $this->sekret($this->options['auth_key'], $method, $args, $username)) {
         return new IXR_Error('401', __('Unauthorized: key match failure', 'cf-deploy'));
     }
     # key validation
     if (!method_exists($this, $method)) {
         return new IXR_Error('400', sprintf(__('Invalid Request: method `%s` does not exist', 'cf-deploy'), $method));
     } elseif (empty($this->options['auth_key'])) {
         return new IXR_Error(401, __('Unauthorized: auth key not configured', 'cf-deploy'));
     }
     # hash validation, cheap way to ensure that the data safely made it from there to here intact
     if (md5(serialize($args)) != $val_hash) {
         cfd_tmp_dbg('cf-data-received.txt', PHP_EOL . PHP_EOL . '---- calculated local hash: ' . md5(serialize($args)), '', true);
         return new IXR_Error('400', __('Validation hash mismatch', 'cf-deploy'));
     }
     # user validation
     if (!($user = get_user_by('login', $username))) {
         cfd_tmp_dbg('cf-data-received.txt', PHP_EOL . PHP_EOL . '---- local get_user_by(login): ' . PHP_EOL . PHP_EOL . print_r($user, true), '', true);
         return new IXR_Error(401, __('Invalid Username', 'cf-deploy'));
     }
     $user = new WP_User($user->ID);
     if (!$user->has_cap(apply_filters('cf-deploy-user-permissions', CF_DEPLOY_CAPABILITIES))) {
         cfd_tmp_dbg('/tmp/cf-data-received.txt', PHP_EOL . PHP_EOL . '---- local user object: ' . PHP_EOL . PHP_EOL . print_r($user, true), '', true);
         return new IXR_Error(401, __('Unauthorized: not allowed', 'cf-deploy'));
     }
     // user is ok, set as current user
     wp_set_current_user($user->ID, $user->user_login);
     return compact('args', 'method', 'blog_id');
 }