public static function from_attachment_id($attachment_id, $upload_dir)
 {
     $returnValue = new AttachmentData();
     $metadata = wp_get_attachment_metadata($attachment_id);
     $returnValue->filename_base(basename($metadata['file']));
     $returnValue->filename_path($upload_dir['basedir'] . '/' . $metadata['file']);
     $returnValue->file_metadata($metadata);
     // Copy all of the custom data for this post.
     $returnValue->post_custom = get_post_custom($attachment_id);
     return $returnValue;
 }
 public function save_post($post_id)
 {
     if (!$this->role_at_least($this->get_site_option('role_broadcast'))) {
         return;
     }
     $allowed_post_status = array('publish');
     if ($this->role_at_least($this->get_site_option('role_broadcast_as_draft'))) {
         $allowed_post_status[] = 'draft';
     }
     if ($this->role_at_least($this->get_site_option('role_broadcast_scheduled_posts'))) {
         $allowed_post_status[] = 'future';
     }
     $post = get_post($post_id, 'ARRAY_A');
     if (!in_array($post['post_status'], $allowed_post_status)) {
         return;
     }
     if (!isset($_POST['broadcast'])) {
         // Site admin is never forced to do anything.
         if (is_super_admin()) {
             return;
         }
         // Ignore this post. It's being force broadcast.
         if (isset($_POST['broadcast_force'])) {
             return;
         }
         if ($this->get_site_option('always_use_required_list') == true) {
             $_POST['broadcast_force'] = true;
         } else {
             return;
         }
     }
     $post_type = $_POST['post_type'];
     $post_type_object = get_post_type_object($post_type);
     $post_type_supports_thumbnails = post_type_supports($post_type, 'thumbnail');
     $post_type_supports_custom_fields = post_type_supports($post_type, 'custom-fields');
     $post_type_is_hierarchical = $post_type_object->hierarchical;
     // Create new post data from the original stuff.
     $newPost = $post;
     foreach (array('ID', 'guid', 'menu_order', 'comment_count', 'post_parent') as $key) {
         unset($newPost[$key]);
     }
     if (isset($_POST['broadcast']['groups']['666'])) {
         $blogs = array_keys($_POST['broadcast']['groups']['666']);
     } else {
         $blogs = array();
     }
     // Now to add and remove blogs.
     $blogs = array_flip($blogs);
     // Remove the blog we're currently working on. No point in broadcasting to ourselves.
     global $blog_id;
     unset($blogs[$blog_id]);
     $user_id = $this->user_id();
     // Convenience.
     // Remove blacklisted
     foreach ($blogs as $blogID => $ignore) {
         if (!$this->is_blog_user_writable($user_id, $blogID)) {
             unset($blogs[$blogID]);
         }
     }
     // Add required blogs.
     if ($this->get_site_option('always_use_required_list')) {
         $requiredBlogs = $this->get_required_blogs();
         foreach ($requiredBlogs as $requiredBlog => $ignore) {
             $blogs[$requiredBlog] = $requiredBlog;
         }
     }
     $blogs = array_keys($blogs);
     // Now to add and remove blogs: done
     // Do we actually need to to anything?
     if (count($blogs) < 1) {
         return;
     }
     $link = $this->role_at_least($this->get_site_option('role_link')) && isset($_POST['broadcast']['link']);
     if ($link) {
         // Prepare the broadcast data for linked children.
         $broadcast_data = $this->get_post_broadcast_data($blog_id, $post_id);
         // Does this post type have parent support, so that we can link to a parent?
         if ($post_type_is_hierarchical && $_POST['post_parent'] > 0) {
             $post_id_parent = $_POST['post_parent'];
             $parent_broadcast_data = $this->get_post_broadcast_data($blog_id, $post_id_parent);
         }
     }
     $taxonomies = $this->role_at_least($this->get_site_option('role_taxonomies')) && isset($_POST['broadcast']['taxonomies']);
     $taxonomies_create = $this->role_at_least($this->get_site_option('role_taxonomies_create')) && isset($_POST['broadcast']['taxonomies_create']);
     if ($taxonomies) {
         $source_blog_taxonomies = get_object_taxonomies(array('object_type' => $post_type), 'array');
         $source_post_taxonomies = array();
         foreach ($source_blog_taxonomies as $source_blog_taxonomy => $ignore) {
             $source_post_taxonomies[$source_blog_taxonomy] = get_the_terms($post_id, $source_blog_taxonomy);
             if ($source_post_taxonomies[$source_blog_taxonomy] === false) {
                 unset($source_post_taxonomies[$source_blog_taxonomy]);
             }
         }
     }
     require_once 'AttachmentData.php';
     $upload_dir = wp_upload_dir();
     // We need to find out where the files are on disk for this blog.
     $attachment_data = array();
     $attached_files =& get_children('post_parent=' . $post_id . '&post_type=attachment');
     $has_attached_files = count($attached_files) > 0;
     if ($has_attached_files) {
         foreach ($attached_files as $attached_file) {
             $attachment_data[$attached_file->ID] = AttachmentData::from_attachment_id($attached_file->ID, $upload_dir);
         }
     }
     $custom_fields = $this->role_at_least($this->get_site_option('role_custom_fields')) && isset($_POST['broadcast']['custom_fields']) && ($post_type_supports_custom_fields || $post_type_supports_thumbnails);
     if ($custom_fields) {
         $post_custom_fields = get_post_custom($post_id);
         $has_thumbnail = isset($post_custom_fields['_thumbnail_id']);
         if ($has_thumbnail) {
             $thumbnail_id = $post_custom_fields['_thumbnail_id'][0];
             unset($post_custom_fields['_thumbnail_id']);
             // There is a new thumbnail id for each blog.
             $attachment_data['thumbnail'] = AttachmentData::from_attachment_id($thumbnail_id, $upload_dir);
             // Now that we know what the attachment id the thumbnail has, we must remove it from the attached files to avoid duplicates.
             unset($attachment_data[$thumbnail_id]);
         }
         // Remove all the _internal custom fields.
         $post_custom_fields = $this->keep_valid_custom_fields($post_custom_fields);
     }
     // Sticky isn't a tag, cat or custom_field.
     $post_is_sticky = @($_POST['sticky'] == 'sticky');
     // And now save the user's last settings.
     $this->save_last_used_settings($user_id, $_POST['broadcast']);
     $this->broadcasting = $_POST['broadcast'];
     $to_broadcasted_blogs = array();
     // Array of blog names that we're broadcasting to.
     // To prevent recursion
     unset($_POST['broadcast']);
     $original_blog = $blog_id;
     foreach ($blogs as $blogID) {
         // Another safety check. Goes with the safety dance.
         if (!$this->is_blog_user_writable($user_id, $blogID)) {
             continue;
         }
         switch_to_blog($blogID);
         // Post parent
         if ($link && isset($parent_broadcast_data)) {
             if ($parent_broadcast_data->has_linked_child_on_this_blog()) {
                 $linked_parent = $parent_broadcast_data->get_linked_child_on_this_blog();
                 $newPost['post_parent'] = $linked_parent;
             }
         }
         // Insert new? Or update? Depends on whether the parent post was linked before or is newly linked?
         $need_to_insert_post = true;
         if ($link) {
             if ($broadcast_data->has_linked_child_on_this_blog()) {
                 $child_post_id = $broadcast_data->get_linked_child_on_this_blog();
                 // Does this child post still exist?
                 $child_post = get_post($child_post_id);
                 if ($child_post !== null) {
                     $temp_post_data = $newPost;
                     $temp_post_data['ID'] = $child_post_id;
                     $new_post_id = wp_update_post($temp_post_data);
                     $need_to_insert_post = false;
                 }
             }
         }
         if ($need_to_insert_post) {
             $new_post_id = wp_insert_post($newPost);
             if ($link) {
                 $broadcast_data->add_linked_child($blogID, $new_post_id);
             }
         }
         if ($taxonomies) {
             foreach ($source_post_taxonomies as $source_post_taxonomy => $source_post_terms) {
                 // If we're updating a linked post, remove all the taxonomies and start from the top.
                 if ($link) {
                     if ($broadcast_data->has_linked_child_on_this_blog()) {
                         wp_set_object_terms($new_post_id, array(), $source_post_taxonomy);
                     }
                 }
                 // Get a list of cats that the target blog has.
                 $target_blog_terms = $this->get_current_blog_taxonomy_terms($source_post_taxonomy);
                 // Go through the original post's terms and compare each slug with the slug of the target terms.
                 $taxonomies_to_add_to = array();
                 $have_created_taxonomies = false;
                 foreach ($source_post_terms as $source_post_term) {
                     $found = false;
                     $source_slug = $source_post_term->slug;
                     foreach ($target_blog_terms as $target_blog_term) {
                         if ($target_blog_term['slug'] == $source_slug) {
                             $found = true;
                             $taxonomies_to_add_to[$target_blog_term['term_id']] = intval($target_blog_term['term_id']);
                             break;
                         }
                     }
                     // Should we create the taxonomy if it doesn't exist?
                     if (!$found && $taxonomies_create) {
                         $new_taxonomy = wp_insert_term($source_post_term->name, $source_post_taxonomy, array('slug' => $source_post_term->slug, 'description' => $source_post_term->description));
                         $taxonomies_to_add_to[] = $source_post_term->slug;
                         $have_created_taxonomies = true;
                     }
                 }
                 if ($taxonomies_create) {
                     $this->sync_terms($source_post_taxonomy, $original_blog, $blogID);
                 }
                 if (count($taxonomies_to_add_to) > 0) {
                     wp_set_object_terms($new_post_id, $taxonomies_to_add_to, $source_post_taxonomy);
                 }
             }
         }
         /**
         	Remove the current attachments.
         */
         $attachments_to_remove =& get_children('post_parent=' . $new_post_id . '&post_type=attachment');
         foreach ($attachments_to_remove as $attachment_to_remove) {
             wp_delete_attachment($attachment_to_remove->ID);
         }
         foreach ($attachment_data as $key => $attached_file) {
             if ($key != 'thumbnail') {
                 $this->copy_attachment($attached_file, $new_post_id);
             }
         }
         if ($custom_fields) {
             // Remove all old custom fields.
             $old_custom_fields = get_post_custom($new_post_id);
             foreach ($old_custom_fields as $key => $value) {
                 // This post has a featured image! Remove it from disk!
                 if ($key == '_thumbnail_id') {
                     $thumbnail_post = $value[0];
                     wp_delete_post($thumbnail_post);
                 }
                 delete_post_meta($new_post_id, $key);
             }
             foreach ($post_custom_fields as $meta_key => $meta_value) {
                 if (is_array($meta_value)) {
                     foreach ($meta_value as $single_meta_value) {
                         $single_meta_value = maybe_unserialize($single_meta_value);
                         add_post_meta($new_post_id, $meta_key, $single_meta_value);
                     }
                 } else {
                     $meta_value = maybe_unserialize($meta_value);
                     add_post_meta($new_post_id, $meta_key, $meta_value);
                 }
             }
             // Attached files are custom fields... but special custom fields. Therefore they need special treatment. Like retards. Retarded files.
             if ($has_thumbnail) {
                 $new_attachment_id = $this->copy_attachment($attachment_data['thumbnail'], $new_post_id);
                 if ($new_attachment_id !== false) {
                     update_post_meta($new_post_id, '_thumbnail_id', $new_attachment_id);
                 }
             }
         }
         // Sticky behaviour
         $child_post_is_sticky = is_sticky($new_post_id);
         if ($post_is_sticky && !$child_post_is_sticky) {
             stick_post($new_post_id);
         }
         if (!$post_is_sticky && $child_post_is_sticky) {
             unstick_post($new_post_id);
         }
         if ($link) {
             $new_post_broadcast_data = $this->get_post_broadcast_data($blog_id, $new_post_id);
             $new_post_broadcast_data->set_linked_parent($original_blog, $post_id);
             $this->set_post_broadcast_data($blogID, $new_post_id, $new_post_broadcast_data);
         }
         $to_broadcasted_blogs[] = '<a href="' . get_permalink($new_post_id) . '">' . get_bloginfo('name') . '</a>';
         restore_current_blog();
     }
     // Finished broadcasting.
     $this->broadcasting = false;
     $post_url_and_name = '<a href="' . get_permalink($post_id) . '">' . $post['post_title'] . '</a>';
     do_action('threewp_activity_monitor_new_activity', array('activity_id' => '3broadcast_broadcasted', 'activity_strings' => array('' => '%user_display_name_with_link% has broadcasted ' . $post_url_and_name . ' to: ' . implode(', ', $to_broadcasted_blogs))));
     // Save the post broadcast data.
     if ($link) {
         $this->set_post_broadcast_data($blog_id, $post_id, $broadcast_data);
     }
 }