[buddypress-trac] [BuddyPress Trac] #5429: New component to manage BuddyPress "attachments"

buddypress-trac noreply at wordpress.org
Wed Mar 12 17:02:08 UTC 2014

#5429: New component to manage BuddyPress "attachments"
 Reporter:  imath           |       Owner:
     Type:  enhancement     |      Status:  new
 Priority:  normal          |   Milestone:  2.0
Component:  All Components  |     Version:
 Severity:  normal          |  Resolution:
 Keywords:  2nd-opinion     |

Comment (by imath):

 Two weeks have passed since the publication of this ticket. I thought it
 was important I make a first "report" of my developments progress for this
 We decided in a dev-chat that this component would be developed as a
 "feature as a plugin" component. This is, in my opinion, a very good
 approach because it will enable us to soon work more collaboratively on
 the subject without affecting the BuddyPress core.
 Before i publish a first version of the plugin on the BuddyPress github
 repository, which I hope will happen in the coming days, I really want it
 to be as clean as possible. So I realize it’s taking me more time than I
 thought, sorry.

 PS: primarly wrote this in french and translated it. If like me you're
 more comfortable with this language you can read my first version
 G1M6o9SQW22c/edit?usp=sharing here] ;)

 ===== New "feature as a plugin" component for BuddyPress =====
 Since it is possible that the component integrates BuddyPress core when it
 will be mature enough, I think the activation process must be the same
 than for the other components : by integrating the components list of the
 BuddyPress administration settings page ({{{/ wp-admin/options-
 general.php?page=bp-components}}}). I see two interests :
 1. only some portions of the code will need to be changed once integrated
 in core (such as the path to the include directory of the component files)
 2. it allows to apply specific settings in conjunction with the components
 from being activated and would be likely to use the "attachments"
 component. These settings will directly be handled from this
 administration page.
 In my local development environment, I created a specific "loader" that
 allows me to include it in components list. However, it will be necessary
 to make some adjustments to core to make this possible. In Attachments,
 you will find a patch (5429.diff) detailing those needs.
 === About the BuddyPress Attachment API ===
 The plugin is based on a post_type I named {{{bp_attachment}}}, it draws
 heavily on the WordPress post type {{{attachment}}} we could have used to
 save time. However, I think there are more advantages to separate things.
 1. using the attachment post type would have generated the display of
 items in the list of media in the administration and during the use of the
 media editor by the administrator. This might lead to confusion and would
 need to filter the different queries.
 2. Our custom post type can enjoy a custom taxonomy I called
 {{{bp_component}}} and allow us to categorize the attachments depending on
 the components they’re linked to.
 The {{{bp_attachment}}} post type will have a term attribute ( groups ,
 messages ... ) and it will be possible to enrich it with metas referencing
 the items of the other components it is attached to, eg group_id = 1. The
 plugin also provides the ability to attach multiple items to an
 attachment. Indeed, it seems important to be able to offer users to link a
 file to several groups for example. This is a request that I was often
 made to BuddyDrive. So for the BuddyPress attachments component it will
 happen :)
 Ideally, I think, the other components should indicate they wish to use
 the attachments, we will see that later. In the meantime, the plugin is
 handling it for a single component : 'groups'.
 I preferred to start humbly and see for the other components a bit later.
 The 'groups' component is interesting because it acts as a container for
 other features and its visibility attributes can be exploited later in
 conjonction with the status of the attachment which defaults to 'inherit'.
 === PHP part ===
 I preferred to cut different parts of the API in different classes in the
 first place. It is always possible to combine them into one at some point
 if needed.
 1. {{{BP_Attachments_Upload}}} is responsible for managing the uploads. It
 includes different filters and actions to enjoy the WordPress Attachments
 API to our advantage to create different metas and associations to the
 terms of our custom taxonomy .
 2. {{{BP_Attachments_Browser}}} sets up and launches the WordPress media
 editor to allow its use for our attachments component.
 3. {{{BP_Attachments}}} is the main CRUD class for attachments. So far I
 have completed the R and D, C is provided by {{{BP_Attachments_Upload}}}
 and U is one of the things I still have to work on in the coming days. The
 different templates and the WP_List_Table in administration screens will
 use it.
 4. I still have to create the class {{{BP_Attachments_Groups}}} to manage
 the integration of the component within groups.
 Each of these classes have "wrapper" functions.
 About front end screens: to maximize compatibility with themes, I took the
 advantage of using the "plugins" templates provided by BuddyPress:
 - {{{'members/single/plugins'}}} for profile pages
 - {{{'groups/single/plugins'}}} for groups pages
 H3 tag around the hook {{{do_action('bp_template_title')}}} is a bit
 annoying , but it's the only drawback I see to this method.
 In profile pages, I use $ _GET variables to start. This principle,
 however, remains interesting if we opt for the use of Ajax in this section
 to provide a fallback mechanism, in case javascript is disabled or broken.
 For templates, I use the same markup than other components loops,
 replacing the avatar by a thumbnail of the photo or an icon file provided
 by WordPress .
 Secondary navigation can provide tabs to view all attachments, those he
 shared in groups. Eventually we can imagine other tabs for "private"
 files, shared with friends, etc. In this part of the plugin, I have to
 build templates for groups and those to display the file or edit it. In
 the edit template file I plan to list the components linking the file to
 allow the user to eventually detach his file from some or attach it to
 others. Finally, the use of a custom post type raises two concerns:
 1. The post type is only available on the blog ( root_blog ) on which it
 is initialized. This means that the use from a child site is not intended
 or requires the use of the {{{switch_to_blog()}}} function.
 2. This is not necessarily linked, but that's what made me think of it. We
 must create a mechanism for users to verify capabilities. Like checking a
 user can upload attachments on their profile, to a group, can edit,
 delete, etc. I started to build a mapping of capabilities that will be
 important to check when the time comes. I think it will be a priority
 following the publication of the first version of the plugin.
 On this second point, I think we should change the
 {{{bp_current_user_can()}}} function to allow it to pass arguments in
 order to check a user can create an attachment for a group_id for
 instance. I created this adaptation on my local dev. It is integrated in
 the patch attached to the ticket (5429.diff).
 In the particular case of groups or users avatars, for now I only need a
 small change in core. In {{{bp_core_avatar_handle_crop()}}} if
 {{{bp_core_delete_existing_avatar()}}} could include the item_id argument,
 it would be nice. I’m still wondering about
 {{{bp_core_avatar_handle_upload()}}} as the one I use in the plugin is
 almost a copy of it. Difference is my use of {{{new WP_Error }}} instead
 of {{{bp_core_add_message()}}}.
 These attachments will be a little special because they will not create a
 {{{ bp_attachment}}} in the posts table or in component upload
 directories. They will use the current logic. My choice is guided by a
 simplification of the Media Editor for this type of attachment that
 incorporates two tabs: Upload and Crop. Which brings me to the most
 complex part to me!

 === JavaScript / Ajax / WP Media Editor ===
 Since we use a {{{post_type != 'attachment'}}} it forced me to completely
 overload the BackBone WordPress model to replace {{{Attachments}}},
 {{{Attachment}}} & {{{Query}}} by BuddyPress specific ones eg
 The main reason is that WordPress is blocking Ajax actions (get/save) by
 early bailing after a post_type check :
 if ( 'attachment' != $post['post_type'] )
 It was also necessary that I "copy and adapt" some functions like the one
 that prepares attachments for javascript and the one that builds the url
 to the uploaded file, for the same reasons .
 About {{{Query}}} I need to integrate arguments to filter attachments by
 user, component or item_id.
 These changes were quite disturbing for my views "extends". I am just
 starting to glimpse the tunnel! (French expression! not sure it’s great in
 English: "voir le bout du tunnel")

 Another point, version 3.9 of WordPress added, among others, image editing
 functions directly inside the Media Editor. For now I am not too focused
 on the potential of this new view, but I plan to explore it more deeply
 soon especially to avoid using jCrop as
 [http://odyniec.net/projects/imgareaselect/ ImgAreaSelect] is included in
 the editor.
 The introduction of this new feature has temporarily "broken", the
 mechanism I had developed and more globally using the "Add Media" button
 in the WP_Editor in front end. I proposed a patch on WordPress trac
 27372.diff]. I am confident about the resolution of the
 [https://core.trac.wordpress.org/ticket/21811#comment:66 21811] ticket by
 the release of 3.9.
 However, this side effect has prompted me to design a fallback mechanism
 to keep on being able to create attachments even if Javascript is
 unavailable or broken.

 === Privacy ===
 "And last but not least!" boonebgorges is right to focus on this point as
 we will be expected on the subject, that's for sure. Unfortunately, in
 this area, even though WordPress provides a "private" status for its
 media, it provides no mechanism to ensure that access to the files is
 actually private. We faced this problem for our respective plugins BP Docs
 and BuddyDrive. I’ve explored how Easy Digital Downloads or WooCommerce
 was dealing with it, it is very similar. It does not cover all situations,
 especially when the server software is not Apache.

 At the same time, it is likely that the majority of WordPress
 configurations use Apache. We can therefore use the .htaccess trick by
 default and pair it with a mechanism to check files are not directly
 reachable prior to the ability to activate the "private" status of
 attachments. I looked at the links you've added to your comment,
 boonebgorges, and I think you’re right, our only option is to help
 administrators to configure their server so that access to files can be

 For instance we could move an image file in a subdirectory of the main
 private directory. Then from the settings of the component, we could
 attempt to display the image which if actually loaded would indicate that
 the server configuration does not provide ability to share private
 attachments. A tutorial could then be published on the codex to list the
 available ways to make it happen.

 It seems to me that the best practice is to move the main private upload
 directory out of the web directory while giving proper permissions to the
 www user to write / edit and delete folders and files within that
 particular directory.

 Then there is the problem of displaying images or other media. Since in
 such a case, it is easy to force a download, the display is actually more
 problematic especially if we must check each thumbnail upon current logged
 in user.

 I think the easiest way is to use a general thumbnail to indicate a file
 is private. In a similar way WordPress does for files that are not images.
 Then we should be able to display the image in its preview or unique view
 to limit the impact of having to load WordPress to check file access.
 About images, I thought, for a very small time, about using the
 post_content field of our {{{bp_attachment}}} post type to fill it with
 the base64 encoded version of the image, but I think it may be too heavy
 in particular when generating these encoded images.
 About the plugin, I’ve included a specific directory for private
 attachments. The idea is to use it instead of the public one according to
 the status selected of the {{{bp_attachment}}} post_type. In the first
 version I will publish on github, I think I will leave this part as a
 "todo" to enjoy your inputs on the subject. This is priority number 2
 after capabilities management :)

 To end this "report": I think I've completed the first version of the
 plugin by 60%, and I hope to be able to create the github repository
 within the next ten days.

 5329.diff contains core adaptations I believe are interesting to be
 published into trunk before the 2.0 release. As explained above about
 avatars, I will eventually complete it with another patch soon.

Ticket URL: <https://buddypress.trac.wordpress.org/ticket/5429#comment:6>
BuddyPress Trac <http://buddypress.org/>
BuddyPress Trac

More information about the buddypress-trac mailing list